Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-03 23:53:08

0001 #include "L1Trigger/TrackerDTC/interface/Setup.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
0004 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0005 #include "DataFormats/L1TrackTrigger/interface/TTBV.h"
0006 
0007 #include <cmath>
0008 #include <algorithm>
0009 #include <vector>
0010 #include <set>
0011 #include <string>
0012 #include <sstream>
0013 
0014 using namespace std;
0015 using namespace edm;
0016 
0017 namespace trackerDTC {
0018 
0019   Setup::Setup(const ParameterSet& iConfig,
0020                const MagneticField& magneticField,
0021                const TrackerGeometry& trackerGeometry,
0022                const TrackerTopology& trackerTopology,
0023                const TrackerDetToDTCELinkCablingMap& cablingMap,
0024                const StubAlgorithmOfficial& stubAlgorithm,
0025                const ParameterSet& pSetStubAlgorithm,
0026                const ParameterSet& pSetGeometryConfiguration,
0027                const ParameterSetID& pSetIdTTStubAlgorithm,
0028                const ParameterSetID& pSetIdGeometryConfiguration)
0029       : magneticField_(&magneticField),
0030         trackerGeometry_(&trackerGeometry),
0031         trackerTopology_(&trackerTopology),
0032         cablingMap_(&cablingMap),
0033         stubAlgorithm_(&stubAlgorithm),
0034         pSetSA_(&pSetStubAlgorithm),
0035         pSetGC_(&pSetGeometryConfiguration),
0036         pSetIdTTStubAlgorithm_(pSetIdTTStubAlgorithm),
0037         pSetIdGeometryConfiguration_(pSetIdGeometryConfiguration),
0038         // DD4hep
0039         fromDD4hep_(iConfig.getParameter<bool>("fromDD4hep")),
0040         // Parameter to check if configured Tracker Geometry is supported
0041         pSetSG_(iConfig.getParameter<ParameterSet>("SupportedGeometry")),
0042         sgXMLLabel_(pSetSG_.getParameter<string>("XMLLabel")),
0043         sgXMLPath_(pSetSG_.getParameter<string>("XMLPath")),
0044         sgXMLFile_(pSetSG_.getParameter<string>("XMLFile")),
0045         sgXMLVersions_(pSetSG_.getParameter<vector<string>>("XMLVersions")),
0046         // Parameter to check if Process History is consistent with process configuration
0047         pSetPH_(iConfig.getParameter<ParameterSet>("ProcessHistory")),
0048         phGeometryConfiguration_(pSetPH_.getParameter<string>("GeometryConfiguration")),
0049         phTTStubAlgorithm_(pSetPH_.getParameter<string>("TTStubAlgorithm")),
0050         // Common track finding parameter
0051         pSetTF_(iConfig.getParameter<ParameterSet>("TrackFinding")),
0052         beamWindowZ_(pSetTF_.getParameter<double>("BeamWindowZ")),
0053         matchedLayers_(pSetTF_.getParameter<int>("MatchedLayers")),
0054         matchedLayersPS_(pSetTF_.getParameter<int>("MatchedLayersPS")),
0055         unMatchedStubs_(pSetTF_.getParameter<int>("UnMatchedStubs")),
0056         unMatchedStubsPS_(pSetTF_.getParameter<int>("UnMatchedStubsPS")),
0057         // TMTT specific parameter
0058         pSetTMTT_(iConfig.getParameter<ParameterSet>("TMTT")),
0059         minPt_(pSetTMTT_.getParameter<double>("MinPt")),
0060         maxEta_(pSetTMTT_.getParameter<double>("MaxEta")),
0061         chosenRofPhi_(pSetTMTT_.getParameter<double>("ChosenRofPhi")),
0062         numLayers_(pSetTMTT_.getParameter<int>("NumLayers")),
0063         widthR_(pSetTMTT_.getParameter<int>("WidthR")),
0064         widthPhi_(pSetTMTT_.getParameter<int>("WidthPhi")),
0065         widthZ_(pSetTMTT_.getParameter<int>("WidthZ")),
0066         // Hybrid specific parameter
0067         pSetHybrid_(iConfig.getParameter<ParameterSet>("Hybrid")),
0068         hybridMinPt_(pSetHybrid_.getParameter<double>("MinPt")),
0069         hybridMaxEta_(pSetHybrid_.getParameter<double>("MaxEta")),
0070         hybridChosenRofPhi_(pSetHybrid_.getParameter<double>("ChosenRofPhi")),
0071         hybridNumLayers_(pSetHybrid_.getParameter<int>("NumLayers")),
0072         hybridNumRingsPS_(pSetHybrid_.getParameter<vector<int>>("NumRingsPS")),
0073         hybridWidthsR_(pSetHybrid_.getParameter<vector<int>>("WidthsR")),
0074         hybridWidthsZ_(pSetHybrid_.getParameter<vector<int>>("WidthsZ")),
0075         hybridWidthsPhi_(pSetHybrid_.getParameter<vector<int>>("WidthsPhi")),
0076         hybridWidthsAlpha_(pSetHybrid_.getParameter<vector<int>>("WidthsAlpha")),
0077         hybridWidthsBend_(pSetHybrid_.getParameter<vector<int>>("WidthsBend")),
0078         hybridRangesR_(pSetHybrid_.getParameter<vector<double>>("RangesR")),
0079         hybridRangesZ_(pSetHybrid_.getParameter<vector<double>>("RangesZ")),
0080         hybridRangesAlpha_(pSetHybrid_.getParameter<vector<double>>("RangesAlpha")),
0081         hybridLayerRs_(pSetHybrid_.getParameter<vector<double>>("LayerRs")),
0082         hybridDiskZs_(pSetHybrid_.getParameter<vector<double>>("DiskZs")),
0083         hybridDisk2SRsSet_(pSetHybrid_.getParameter<vector<ParameterSet>>("Disk2SRsSet")),
0084         // Parameter specifying TrackingParticle used for Efficiency measurements
0085         pSetTP_(iConfig.getParameter<ParameterSet>("TrackingParticle")),
0086         tpMaxEta_(pSetTP_.getParameter<double>("MaxEta")),
0087         tpMaxVertR_(pSetTP_.getParameter<double>("MaxVertR")),
0088         tpMaxVertZ_(pSetTP_.getParameter<double>("MaxVertZ")),
0089         tpMaxD0_(pSetTP_.getParameter<double>("MaxD0")),
0090         tpMinLayers_(pSetTP_.getParameter<int>("MinLayers")),
0091         tpMinLayersPS_(pSetTP_.getParameter<int>("MinLayersPS")),
0092         // Fimrware specific Parameter
0093         pSetFW_(iConfig.getParameter<ParameterSet>("Firmware")),
0094         numFramesInfra_(pSetFW_.getParameter<int>("NumFramesInfra")),
0095         freqLHC_(pSetFW_.getParameter<double>("FreqLHC")),
0096         freqBE_(pSetFW_.getParameter<double>("FreqBE")),
0097         tmpFE_(pSetFW_.getParameter<int>("TMP_FE")),
0098         tmpTFP_(pSetFW_.getParameter<int>("TMP_TFP")),
0099         speedOfLight_(pSetFW_.getParameter<double>("SpeedOfLight")),
0100         bField_(pSetFW_.getParameter<double>("BField")),
0101         bFieldError_(pSetFW_.getParameter<double>("BFieldError")),
0102         outerRadius_(pSetFW_.getParameter<double>("OuterRadius")),
0103         innerRadius_(pSetFW_.getParameter<double>("InnerRadius")),
0104         halfLength_(pSetFW_.getParameter<double>("HalfLength")),
0105         maxPitch_(pSetFW_.getParameter<double>("MaxPitch")),
0106         // Parmeter specifying front-end
0107         pSetFE_(iConfig.getParameter<ParameterSet>("FrontEnd")),
0108         widthBend_(pSetFE_.getParameter<int>("WidthBend")),
0109         widthCol_(pSetFE_.getParameter<int>("WidthCol")),
0110         widthRow_(pSetFE_.getParameter<int>("WidthRow")),
0111         baseBend_(pSetFE_.getParameter<double>("BaseBend")),
0112         baseCol_(pSetFE_.getParameter<double>("BaseCol")),
0113         baseRow_(pSetFE_.getParameter<double>("BaseRow")),
0114         baseWindowSize_(pSetFE_.getParameter<double>("BaseWindowSize")),
0115         bendCut_(pSetFE_.getParameter<double>("BendCut")),
0116         // Parmeter specifying DTC
0117         pSetDTC_(iConfig.getParameter<ParameterSet>("DTC")),
0118         numRegions_(pSetDTC_.getParameter<int>("NumRegions")),
0119         numOverlappingRegions_(pSetDTC_.getParameter<int>("NumOverlappingRegions")),
0120         numATCASlots_(pSetDTC_.getParameter<int>("NumATCASlots")),
0121         numDTCsPerRegion_(pSetDTC_.getParameter<int>("NumDTCsPerRegion")),
0122         numModulesPerDTC_(pSetDTC_.getParameter<int>("NumModulesPerDTC")),
0123         dtcNumRoutingBlocks_(pSetDTC_.getParameter<int>("NumRoutingBlocks")),
0124         dtcDepthMemory_(pSetDTC_.getParameter<int>("DepthMemory")),
0125         dtcWidthRowLUT_(pSetDTC_.getParameter<int>("WidthRowLUT")),
0126         dtcWidthQoverPt_(pSetDTC_.getParameter<int>("WidthQoverPt")),
0127         offsetDetIdDSV_(pSetDTC_.getParameter<int>("OffsetDetIdDSV")),
0128         offsetDetIdTP_(pSetDTC_.getParameter<int>("OffsetDetIdTP")),
0129         offsetLayerDisks_(pSetDTC_.getParameter<int>("OffsetLayerDisks")),
0130         offsetLayerId_(pSetDTC_.getParameter<int>("OffsetLayerId")),
0131         // Parmeter specifying GeometricProcessor
0132         pSetGP_(iConfig.getParameter<ParameterSet>("GeometricProcessor")),
0133         numSectorsPhi_(pSetGP_.getParameter<int>("NumSectorsPhi")),
0134         chosenRofZ_(pSetGP_.getParameter<double>("ChosenRofZ")),
0135         neededRangeChiZ_(pSetGP_.getParameter<double>("RangeChiZ")),
0136         gpDepthMemory_(pSetGP_.getParameter<int>("DepthMemory")),
0137         boundariesEta_(pSetGP_.getParameter<vector<double>>("BoundariesEta")),
0138         // Parmeter specifying HoughTransform
0139         pSetHT_(iConfig.getParameter<ParameterSet>("HoughTransform")),
0140         htNumBinsQoverPt_(pSetHT_.getParameter<int>("NumBinsQoverPt")),
0141         htNumBinsPhiT_(pSetHT_.getParameter<int>("NumBinsPhiT")),
0142         htMinLayers_(pSetHT_.getParameter<int>("MinLayers")),
0143         htDepthMemory_(pSetHT_.getParameter<int>("DepthMemory")),
0144         // Parmeter specifying MiniHoughTransform
0145         pSetMHT_(iConfig.getParameter<ParameterSet>("MiniHoughTransform")),
0146         mhtNumBinsQoverPt_(pSetMHT_.getParameter<int>("NumBinsQoverPt")),
0147         mhtNumBinsPhiT_(pSetMHT_.getParameter<int>("NumBinsPhiT")),
0148         mhtNumDLB_(pSetMHT_.getParameter<int>("NumDLB")),
0149         mhtMinLayers_(pSetMHT_.getParameter<int>("MinLayers")),
0150         // Parmeter specifying SeedFilter
0151         pSetSF_(iConfig.getParameter<ParameterSet>("SeedFilter")),
0152         sfPowerBaseCot_(pSetSF_.getParameter<int>("PowerBaseCot")),
0153         sfBaseDiffZ_(pSetSF_.getParameter<int>("BaseDiffZ")),
0154         sfMinLayers_(pSetSF_.getParameter<int>("MinLayers")),
0155         // Parmeter specifying KalmanFilter
0156         pSetKF_(iConfig.getParameter<ParameterSet>("KalmanFilter")),
0157         kfWidthLutInvPhi_(pSetKF_.getParameter<int>("WidthLutInvPhi")),
0158         kfWidthLutInvZ_(pSetKF_.getParameter<int>("WidthLutInvZ")),
0159         kfNumTracks_(pSetKF_.getParameter<int>("NumTracks")),
0160         kfMinLayers_(pSetKF_.getParameter<int>("MinLayers")),
0161         kfMaxLayers_(pSetKF_.getParameter<int>("MaxLayers")),
0162         kfMaxStubsPerLayer_(pSetKF_.getParameter<int>("MaxStubsPerLayer")),
0163         kfMaxSkippedLayers_(pSetKF_.getParameter<int>("MaxSkippedLayers")),
0164         kfBaseShiftr0_(pSetKF_.getParameter<int>("BaseShiftr0")),
0165         kfBaseShiftr02_(pSetKF_.getParameter<int>("BaseShiftr02")),
0166         kfBaseShiftv0_(pSetKF_.getParameter<int>("BaseShiftv0")),
0167         kfBaseShiftS00_(pSetKF_.getParameter<int>("BaseShiftS00")),
0168         kfBaseShiftS01_(pSetKF_.getParameter<int>("BaseShiftS01")),
0169         kfBaseShiftK00_(pSetKF_.getParameter<int>("BaseShiftK00")),
0170         kfBaseShiftK10_(pSetKF_.getParameter<int>("BaseShiftK10")),
0171         kfBaseShiftR00_(pSetKF_.getParameter<int>("BaseShiftR00")),
0172         kfBaseShiftInvR00_(pSetKF_.getParameter<int>("BaseShiftInvR00")),
0173         kfBaseShiftChi20_(pSetKF_.getParameter<int>("BaseShiftChi20")),
0174         kfBaseShiftC00_(pSetKF_.getParameter<int>("BaseShiftC00")),
0175         kfBaseShiftC01_(pSetKF_.getParameter<int>("BaseShiftC01")),
0176         kfBaseShiftC11_(pSetKF_.getParameter<int>("BaseShiftC11")),
0177         kfBaseShiftr1_(pSetKF_.getParameter<int>("BaseShiftr1")),
0178         kfBaseShiftr12_(pSetKF_.getParameter<int>("BaseShiftr12")),
0179         kfBaseShiftv1_(pSetKF_.getParameter<int>("BaseShiftv1")),
0180         kfBaseShiftS12_(pSetKF_.getParameter<int>("BaseShiftS12")),
0181         kfBaseShiftS13_(pSetKF_.getParameter<int>("BaseShiftS13")),
0182         kfBaseShiftK21_(pSetKF_.getParameter<int>("BaseShiftK21")),
0183         kfBaseShiftK31_(pSetKF_.getParameter<int>("BaseShiftK31")),
0184         kfBaseShiftR11_(pSetKF_.getParameter<int>("BaseShiftR11")),
0185         kfBaseShiftInvR11_(pSetKF_.getParameter<int>("BaseShiftInvR11")),
0186         kfBaseShiftChi21_(pSetKF_.getParameter<int>("BaseShiftChi21")),
0187         kfBaseShiftC22_(pSetKF_.getParameter<int>("BaseShiftC22")),
0188         kfBaseShiftC23_(pSetKF_.getParameter<int>("BaseShiftC23")),
0189         kfBaseShiftC33_(pSetKF_.getParameter<int>("BaseShiftC33")),
0190         kfBaseShiftChi2_(pSetKF_.getParameter<int>("BaseShiftChi2")),
0191         // Parmeter specifying DuplicateRemoval
0192         pSetDR_(iConfig.getParameter<ParameterSet>("DuplicateRemoval")),
0193         drDepthMemory_(pSetDR_.getParameter<int>("DepthMemory")),
0194         drWidthPhi0_(pSetDR_.getParameter<int>("WidthPhi0")),
0195         drWidthQoverPt_(pSetDR_.getParameter<int>("WidthQoverPt")),
0196         drWidthCot_(pSetDR_.getParameter<int>("WidthCot")),
0197         drWidthZ0_(pSetDR_.getParameter<int>("WidthZ0")) {
0198     configurationSupported_ = true;
0199     // check if bField is supported
0200     checkMagneticField();
0201     // check if geometry is supported
0202     checkGeometry();
0203     if (!configurationSupported_)
0204       return;
0205     // derive constants
0206     calculateConstants();
0207     // convert configuration of TTStubAlgorithm
0208     consumeStubAlgorithm();
0209     // create all possible encodingsBend
0210     encodingsBendPS_.reserve(maxWindowSize_ + 1);
0211     encodingsBend2S_.reserve(maxWindowSize_ + 1);
0212     encodeBend(encodingsBendPS_, true);
0213     encodeBend(encodingsBend2S_, false);
0214     // create encodingsLayerId
0215     encodingsLayerId_.reserve(numDTCsPerRegion_);
0216     encodeLayerId();
0217     // create sensor modules
0218     produceSensorModules();
0219   }
0220 
0221   // checks current configuration vs input sample configuration
0222   void Setup::checkHistory(const ProcessHistory& processHistory) const {
0223     const pset::Registry* psetRegistry = pset::Registry::instance();
0224     // check used TTStubAlgorithm in input producer
0225     checkHistory(processHistory, psetRegistry, phTTStubAlgorithm_, pSetIdTTStubAlgorithm_);
0226     // check used GeometryConfiguration in input producer
0227     checkHistory(processHistory, psetRegistry, phGeometryConfiguration_, pSetIdGeometryConfiguration_);
0228   }
0229 
0230   // checks consitency between history and current configuration for a specific module
0231   void Setup::checkHistory(const ProcessHistory& ph,
0232                            const pset::Registry* pr,
0233                            const string& label,
0234                            const ParameterSetID& pSetId) const {
0235     vector<pair<string, ParameterSet>> pSets;
0236     pSets.reserve(ph.size());
0237     for (const ProcessConfiguration& pc : ph) {
0238       const ParameterSet* pSet = pr->getMapped(pc.parameterSetID());
0239       if (pSet && pSet->exists(label))
0240         pSets.emplace_back(pc.processName(), pSet->getParameterSet(label));
0241     }
0242     if (pSets.empty()) {
0243       cms::Exception exception("BadConfiguration");
0244       exception << label << " not found in process history.";
0245       exception.addContext("tt::Setup::checkHistory");
0246       throw exception;
0247     }
0248     auto consistent = [&pSetId](const pair<string, ParameterSet>& p) { return p.second.id() == pSetId; };
0249     if (!all_of(pSets.begin(), pSets.end(), consistent)) {
0250       const ParameterSet& pSetProcess = getParameterSet(pSetId);
0251       cms::Exception exception("BadConfiguration");
0252       exception.addContext("tt::Setup::checkHistory");
0253       exception << label << " inconsistent with History." << endl;
0254       exception << "Current Configuration:" << endl << pSetProcess.dump() << endl;
0255       for (const pair<string, ParameterSet>& p : pSets)
0256         if (!consistent(p))
0257           exception << "Process " << p.first << " Configuration:" << endl << dumpDiff(p.second, pSetProcess) << endl;
0258       throw exception;
0259     }
0260   }
0261 
0262   // dumps pSetHistory where incosistent lines with pSetProcess are highlighted
0263   string Setup::dumpDiff(const ParameterSet& pSetHistory, const ParameterSet& pSetProcess) const {
0264     stringstream ssHistory, ssProcess, ss;
0265     ssHistory << pSetHistory.dump();
0266     ssProcess << pSetProcess.dump();
0267     string lineHistory, lineProcess;
0268     for (; getline(ssHistory, lineHistory) && getline(ssProcess, lineProcess);)
0269       ss << (lineHistory != lineProcess ? "\033[1;31m" : "") << lineHistory << "\033[0m" << endl;
0270     return ss.str();
0271   }
0272 
0273   // converts tk layout id into dtc id
0274   int Setup::dtcId(int tkLayoutId) const {
0275     checkTKLayoutId(tkLayoutId);
0276     const int tkId = tkLayoutId - 1;
0277     const int side = tkId / (numRegions_ * numATCASlots_);
0278     const int region = (tkId % (numRegions_ * numATCASlots_)) / numATCASlots_;
0279     const int slot = tkId % numATCASlots_;
0280     return region * numDTCsPerRegion_ + side * numATCASlots_ + slot;
0281   }
0282 
0283   // converts dtc id into tk layout id
0284   int Setup::tkLayoutId(int dtcId) const {
0285     checkDTCId(dtcId);
0286     const int slot = dtcId % numATCASlots_;
0287     const int region = dtcId / numDTCsPerRegion_;
0288     const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_;
0289     return (side * numRegions_ + region) * numATCASlots_ + slot + 1;
0290   }
0291 
0292   // converts TFP identifier (region[0-8], channel[0-47]) into dtc id
0293   int Setup::dtcId(int tfpRegion, int tfpChannel) const {
0294     checkTFPIdentifier(tfpRegion, tfpChannel);
0295     const int dtcChannel = numOverlappingRegions_ - (tfpChannel / numDTCsPerRegion_) - 1;
0296     const int dtcBoard = tfpChannel % numDTCsPerRegion_;
0297     const int dtcRegion = tfpRegion - dtcChannel >= 0 ? tfpRegion - dtcChannel : tfpRegion - dtcChannel + numRegions_;
0298     return dtcRegion * numDTCsPerRegion_ + dtcBoard;
0299   }
0300 
0301   // checks if given DTC id is connected to PS or 2S sensormodules
0302   bool Setup::psModule(int dtcId) const {
0303     checkDTCId(dtcId);
0304     // from tklayout: first 3 are 10 gbps PS, next 3 are 5 gbps PS and residual 6 are 5 gbps 2S modules
0305     return slot(dtcId) < numATCASlots_ / 2;
0306   }
0307 
0308   // checks if given dtcId is connected to -z (false) or +z (true)
0309   bool Setup::side(int dtcId) const {
0310     checkDTCId(dtcId);
0311     const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_;
0312     // from tkLayout: first 12 +z, next 12 -z
0313     return side == 0;
0314   }
0315 
0316   // ATCA slot number [0-11] of given dtcId
0317   int Setup::slot(int dtcId) const {
0318     checkDTCId(dtcId);
0319     return dtcId % numATCASlots_;
0320   }
0321 
0322   // sensor module for det id
0323   SensorModule* Setup::sensorModule(const DetId& detId) const {
0324     const auto it = detIdToSensorModule_.find(detId);
0325     if (it == detIdToSensorModule_.end()) {
0326       cms::Exception exception("NullPtr");
0327       exception << "Unknown DetId used.";
0328       exception.addContext("tt::Setup::sensorModule");
0329       throw exception;
0330     }
0331     return it->second;
0332   }
0333 
0334   // index = encoded bend, value = decoded bend for given window size and module type
0335   const vector<double>& Setup::encodingBend(int windowSize, bool psModule) const {
0336     const vector<vector<double>>& encodingsBend = psModule ? encodingsBendPS_ : encodingsBend2S_;
0337     return encodingsBend.at(windowSize);
0338   }
0339 
0340   // index = encoded layerId, inner value = decoded layerId for given dtcId or tfp channel
0341   const vector<int>& Setup::encodingLayerId(int dtcId) const {
0342     const int index = dtcId % numDTCsPerRegion_;
0343     return encodingsLayerId_.at(index);
0344   }
0345 
0346   // check if bField is supported
0347   void Setup::checkMagneticField() {
0348     const double bFieldES = magneticField_->inTesla(GlobalPoint(0., 0., 0.)).z();
0349     if (abs(bField_ - bFieldES) > bFieldError_) {
0350       configurationSupported_ = false;
0351       LogWarning("ConfigurationNotSupported")
0352           << "Magnetic Field from EventSetup (" << bFieldES << ") differs more then " << bFieldError_
0353           << " from supported value (" << bField_ << "). ";
0354     }
0355   }
0356 
0357   // check if geometry is supported
0358   void Setup::checkGeometry() {
0359     //FIX ME: Can we assume that geometry used in dd4hep wf supports L1Track?
0360     if (!fromDD4hep_) {
0361       const vector<string>& geomXMLFiles = pSetGC_->getParameter<vector<string>>(sgXMLLabel_);
0362       string version;
0363       for (const string& geomXMLFile : geomXMLFiles) {
0364         const auto begin = geomXMLFile.find(sgXMLPath_) + sgXMLPath_.size();
0365         const auto end = geomXMLFile.find(sgXMLFile_);
0366         if (begin != string::npos && end != string::npos)
0367           version = geomXMLFile.substr(begin, end - begin - 1);
0368       }
0369       if (version.empty()) {
0370         cms::Exception exception("LogicError");
0371         exception << "No " << sgXMLPath_ << "*/" << sgXMLFile_ << " found in GeometryConfiguration";
0372         exception.addContext("tt::Setup::checkGeometry");
0373         throw exception;
0374       }
0375       if (find(sgXMLVersions_.begin(), sgXMLVersions_.end(), version) == sgXMLVersions_.end()) {
0376         configurationSupported_ = false;
0377         LogWarning("ConfigurationNotSupported")
0378             << "Geometry Configuration " << sgXMLPath_ << version << "/" << sgXMLFile_ << " is not supported. ";
0379       }
0380     }
0381   }
0382 
0383   // convert configuration of TTStubAlgorithm
0384   void Setup::consumeStubAlgorithm() {
0385     numTiltedLayerRings_ = pSetSA_->getParameter<vector<double>>("NTiltedRings");
0386     windowSizeBarrelLayers_ = pSetSA_->getParameter<vector<double>>("BarrelCut");
0387     const auto& pSetsTiltedLayer = pSetSA_->getParameter<vector<ParameterSet>>("TiltedBarrelCutSet");
0388     const auto& pSetsEncapDisks = pSetSA_->getParameter<vector<ParameterSet>>("EndcapCutSet");
0389     windowSizeTiltedLayerRings_.reserve(pSetsTiltedLayer.size());
0390     for (const auto& pSet : pSetsTiltedLayer)
0391       windowSizeTiltedLayerRings_.emplace_back(pSet.getParameter<vector<double>>("TiltedCut"));
0392     windowSizeEndcapDisksRings_.reserve(pSetsEncapDisks.size());
0393     for (const auto& pSet : pSetsEncapDisks)
0394       windowSizeEndcapDisksRings_.emplace_back(pSet.getParameter<vector<double>>("EndcapCut"));
0395     maxWindowSize_ = -1;
0396     for (const auto& windowss : {windowSizeTiltedLayerRings_, windowSizeEndcapDisksRings_, {windowSizeBarrelLayers_}})
0397       for (const auto& windows : windowss)
0398         for (const auto& window : windows)
0399           maxWindowSize_ = max(maxWindowSize_, (int)(window / baseWindowSize_));
0400   }
0401 
0402   // create bend encodings
0403   void Setup::encodeBend(vector<vector<double>>& encodings, bool ps) const {
0404     for (int window = 0; window < maxWindowSize_ + 1; window++) {
0405       set<double> encoding;
0406       for (int bend = 0; bend < window + 1; bend++)
0407         encoding.insert(stubAlgorithm_->degradeBend(ps, window, bend));
0408       encodings.emplace_back(encoding.begin(), encoding.end());
0409     }
0410   }
0411 
0412   // create encodingsLayerId
0413   void Setup::encodeLayerId() {
0414     vector<vector<DTCELinkId>> dtcELinkIds(numDTCs_);
0415     for (vector<DTCELinkId>& dtcELinkId : dtcELinkIds)
0416       dtcELinkId.reserve(numModulesPerDTC_);
0417     for (const DTCELinkId& dtcLinkId : cablingMap_->getKnownDTCELinkIds())
0418       dtcELinkIds[dtcId(dtcLinkId.dtc_id())].push_back(dtcLinkId);
0419     for (int dtcBoard = 0; dtcBoard < numDTCsPerRegion_; dtcBoard++) {
0420       set<int> encodingLayerId;
0421       for (int region = 0; region < numRegions_; region++) {
0422         const int dtcId = region * numDTCsPerRegion_ + dtcBoard;
0423         for (const DTCELinkId& dtcLinkId : dtcELinkIds[dtcId]) {
0424           const DetId& detId = cablingMap_->dtcELinkIdToDetId(dtcLinkId)->second;
0425           const bool barrel = detId.subdetId() == StripSubdetector::TOB;
0426           const int layerId =
0427               barrel ? trackerTopology_->layer(detId) : trackerTopology_->tidWheel(detId) + offsetLayerDisks_;
0428           encodingLayerId.insert(layerId);
0429         }
0430       }
0431       // check configuration
0432       if ((int)encodingLayerId.size() > hybridNumLayers_) {
0433         cms::Exception exception("overflow");
0434         exception << "Cabling map connects more than " << hybridNumLayers_ << " layers to a DTC.";
0435         exception.addContext("tt::Setup::Setup");
0436         throw exception;
0437       }
0438       encodingsLayerId_.emplace_back(encodingLayerId.begin(), encodingLayerId.end());
0439     }
0440   }
0441 
0442   // create sensor modules
0443   void Setup::produceSensorModules() {
0444     sensorModules_.reserve(numModules_);
0445     dtcModules_ = vector<vector<SensorModule*>>(numDTCs_);
0446     for (vector<SensorModule*>& dtcModules : dtcModules_)
0447       dtcModules.reserve(numModulesPerDTC_);
0448     // loop over all tracker modules
0449     for (const DetId& detId : trackerGeometry_->detIds()) {
0450       // skip pixel detector
0451       if (detId.subdetId() == PixelSubdetector::PixelBarrel || detId.subdetId() == PixelSubdetector::PixelEndcap)
0452         continue;
0453       // skip multiple detIds per module
0454       if (!trackerTopology_->isLower(detId))
0455         continue;
0456       // lowerDetId - 1 = tk layout det id
0457       const DetId detIdTkLayout = detId + offsetDetIdTP_;
0458       // tk layout dtc id, lowerDetId - 1 = tk lyout det id
0459       const int tklId = cablingMap_->detIdToDTCELinkId(detIdTkLayout).first->second.dtc_id();
0460       // track trigger dtc id [0-215]
0461       const int dtcId = Setup::dtcId(tklId);
0462       // collection of so far connected modules to this dtc
0463       vector<SensorModule*>& dtcModules = dtcModules_[dtcId];
0464       // construct sendor module
0465       sensorModules_.emplace_back(*this, detId, dtcId, dtcModules.size());
0466       SensorModule* sensorModule = &sensorModules_.back();
0467       // store connection between detId and sensor module
0468       detIdToSensorModule_.emplace(detId, sensorModule);
0469       // store connection between dtcId and sensor module
0470       dtcModules.push_back(sensorModule);
0471     }
0472     for (vector<SensorModule*>& dtcModules : dtcModules_) {
0473       dtcModules.shrink_to_fit();
0474       // check configuration
0475       if ((int)dtcModules.size() > numModulesPerDTC_) {
0476         cms::Exception exception("overflow");
0477         exception << "Cabling map connects more than " << numModulesPerDTC_ << " modules to a DTC.";
0478         exception.addContext("tt::Setup::Setup");
0479         throw exception;
0480       }
0481     }
0482   }
0483 
0484   // derive constants
0485   void Setup::calculateConstants() {
0486     // emp
0487     const int numFramesPerBX = freqBE_ / freqLHC_;
0488     numFrames_ = numFramesPerBX * tmpTFP_ - 1;
0489     numFramesIO_ = numFramesPerBX * tmpTFP_ - numFramesInfra_;
0490     numFramesFE_ = numFramesPerBX * tmpFE_ - numFramesInfra_;
0491     // common track finding
0492     invPtToDphi_ = speedOfLight_ * bField_ / 2000.;
0493     baseRegion_ = 2. * M_PI / numRegions_;
0494     // gp
0495     baseSector_ = baseRegion_ / numSectorsPhi_;
0496     maxCot_ = sinh(maxEta_);
0497     maxZT_ = maxCot_ * chosenRofZ_;
0498     numSectorsEta_ = boundariesEta_.size() - 1;
0499     widthSectorEta_ = ceil(log2(numSectorsEta_));
0500     widthChiZ_ = ceil(log2(neededRangeChiZ_ / baseZ_));
0501     // ht
0502     htWidthQoverPt_ = ceil(log2(htNumBinsQoverPt_));
0503     htWidthPhiT_ = ceil(log2(htNumBinsPhiT_));
0504     const double rangeQoverPt = 2. * invPtToDphi_ / minPt_;
0505     htBaseQoverPt_ = rangeQoverPt / htNumBinsQoverPt_;
0506     htBasePhiT_ = baseSector_ / htNumBinsPhiT_;
0507     // tmtt
0508     widthLayer_ = ceil(log2(numLayers_));
0509     const double baseRgen = htBasePhiT_ / htBaseQoverPt_;
0510     const double rangeR = 2. * max(abs(outerRadius_ - chosenRofPhi_), abs(innerRadius_ - chosenRofPhi_));
0511     const int baseShiftR = ceil(log2(rangeR / baseRgen / pow(2., widthR_)));
0512     baseR_ = baseRgen * pow(2., baseShiftR);
0513     const double rangeZ = 2. * halfLength_;
0514     const int baseShiftZ = ceil(log2(rangeZ / baseR_ / pow(2., widthZ_)));
0515     baseZ_ = baseR_ * pow(2., baseShiftZ);
0516     const double rangePhiDTC = baseRegion_ + rangeQoverPt * baseR_ * pow(2., widthR_) / 4.;
0517     widthPhiDTC_ = widthPhi_ + ceil(log2(rangePhiDTC / baseRegion_));
0518     const int baseShiftPhi = ceil(log2(rangePhiDTC / htBasePhiT_ / pow(2., widthPhiDTC_)));
0519     basePhi_ = htBasePhiT_ * pow(2., baseShiftPhi);
0520     const double neededRangeChiPhi = 2. * htBasePhiT_;
0521     widthChiPhi_ = ceil(log2(neededRangeChiPhi / basePhi_));
0522     // hybrid
0523     const double hybridRangeQoverPt = 2. * invPtToDphi_ / hybridMinPt_;
0524     const double hybridRangeR =
0525         2. * max(abs(outerRadius_ - hybridChosenRofPhi_), abs(innerRadius_ - hybridChosenRofPhi_));
0526     const double hybridRangePhi = baseRegion_ + hybridRangeR * hybridRangeQoverPt / 2.;
0527     hybridWidthLayer_ = ceil(log2(hybridNumLayers_));
0528     hybridBasesZ_.reserve(SensorModule::NumTypes);
0529     for (int type = 0; type < SensorModule::NumTypes; type++)
0530       hybridBasesZ_.emplace_back(hybridRangesZ_.at(type) / pow(2., hybridWidthsZ_.at(type)));
0531     hybridBasesR_.reserve(SensorModule::NumTypes);
0532     for (int type = 0; type < SensorModule::NumTypes; type++)
0533       hybridBasesR_.emplace_back(hybridRangesR_.at(type) / pow(2., hybridWidthsR_.at(type)));
0534     hybridBasesR_[SensorModule::Disk2S] = 1.;
0535     hybridBasesPhi_.reserve(SensorModule::NumTypes);
0536     for (int type = 0; type < SensorModule::NumTypes; type++)
0537       hybridBasesPhi_.emplace_back(hybridRangePhi / pow(2., hybridWidthsPhi_.at(type)));
0538     hybridBasesAlpha_.reserve(SensorModule::NumTypes);
0539     for (int type = 0; type < SensorModule::NumTypes; type++)
0540       hybridBasesAlpha_.emplace_back(hybridRangesAlpha_.at(type) / pow(2., hybridWidthsAlpha_.at(type)));
0541     hybridNumsUnusedBits_.reserve(SensorModule::NumTypes);
0542     for (int type = 0; type < SensorModule::NumTypes; type++)
0543       hybridNumsUnusedBits_.emplace_back(TTBV::S - hybridWidthsR_.at(type) - hybridWidthsZ_.at(type) -
0544                                          hybridWidthsPhi_.at(type) - hybridWidthsAlpha_.at(type) -
0545                                          hybridWidthsBend_.at(type) - hybridWidthLayer_ - 1);
0546     hybridMaxCot_ = sinh(hybridMaxEta_);
0547     disk2SRs_.reserve(hybridDisk2SRsSet_.size());
0548     for (const auto& pSet : hybridDisk2SRsSet_)
0549       disk2SRs_.emplace_back(pSet.getParameter<vector<double>>("Disk2SRs"));
0550     // dtc
0551     numDTCs_ = numRegions_ * numDTCsPerRegion_;
0552     numDTCsPerTFP_ = numDTCsPerRegion_ * numOverlappingRegions_;
0553     numModules_ = numDTCs_ * numModulesPerDTC_;
0554     dtcNumModulesPerRoutingBlock_ = numModulesPerDTC_ / dtcNumRoutingBlocks_;
0555     dtcNumMergedRows_ = pow(2, widthRow_ - dtcWidthRowLUT_);
0556     const double maxRangeQoverPt = max(rangeQoverPt, hybridRangeQoverPt);
0557     const int baseShiftQoverPt = htWidthQoverPt_ - dtcWidthQoverPt_ + ceil(log2(maxRangeQoverPt / rangeQoverPt));
0558     dtcBaseQoverPt_ = htBaseQoverPt_ * pow(2., baseShiftQoverPt);
0559     const int baseDiffM = dtcWidthRowLUT_ - widthRow_;
0560     dtcBaseM_ = basePhi_ * pow(2., baseDiffM);
0561     const double x1 = pow(2, widthRow_) * baseRow_ * maxPitch_ / 2.;
0562     const double x0 = x1 - pow(2, dtcWidthRowLUT_) * baseRow_ * maxPitch_;
0563     const double maxM = atan2(x1, innerRadius_) - atan2(x0, innerRadius_);
0564     dtcWidthM_ = ceil(log2(maxM / dtcBaseM_));
0565     dtcNumUnusedBits_ = TTBV::S - 1 - widthR_ - widthPhiDTC_ - widthZ_ - 2 * htWidthQoverPt_ - 2 * widthSectorEta_ -
0566                         numSectorsPhi_ - widthLayer_;
0567     // mht
0568     mhtNumCells_ = mhtNumBinsQoverPt_ * mhtNumBinsPhiT_;
0569     mhtWidthQoverPt_ = ceil(log2(htNumBinsQoverPt_ * mhtNumBinsQoverPt_));
0570     mhtWidthPhiT_ = ceil(log2(htNumBinsPhiT_ * mhtNumBinsPhiT_));
0571     mhtBaseQoverPt_ = htBaseQoverPt_ / mhtNumBinsQoverPt_;
0572     mhtBasePhiT_ = htBasePhiT_ / mhtNumBinsPhiT_;
0573     // SF
0574     sfBaseCot_ = pow(2, sfPowerBaseCot_);
0575     sfBaseZT_ = baseZ_ * pow(2, sfBaseDiffZ_);
0576     // DR
0577     drBaseQoverPt_ = htBaseQoverPt_ * pow(2, htWidthQoverPt_ - drWidthQoverPt_);
0578     drBasePhi0_ = basePhi_ * pow(2, widthPhiDTC_ - drWidthPhi0_);
0579     drBaseCot_ = floor(log2(2. * maxCot_ * pow(2, -drWidthCot_)));
0580     drBaseZ0_ = baseZ_ * pow(2, ceil(log2(2. * beamWindowZ_ / baseZ_)) - drWidthZ0_);
0581     // KF
0582     kfBasex0_ = drBaseQoverPt_;
0583     kfBasex1_ = drBasePhi0_;
0584     kfBasex2_ = drBaseCot_;
0585     kfBasex3_ = drBaseZ0_;
0586     kfBasem0_ = basePhi_;
0587     kfBasem1_ = baseZ_;
0588     kfBaseH00_ = baseR_;
0589     kfBaseH12_ = baseR_;
0590     kfBaseChi2_ = pow(2, kfBaseShiftChi2_);
0591     kfBaser0_ = pow(2, kfBaseShiftr0_) * kfBasex1_;
0592     kfBaser02_ = pow(2, kfBaseShiftr02_) * kfBasex1_ * kfBasex1_;
0593     kfBasev0_ = pow(2, kfBaseShiftv0_) * kfBasex1_ * kfBasex1_;
0594     kfBaseS00_ = pow(2, kfBaseShiftS00_) * kfBasex0_ * kfBasex1_;
0595     kfBaseS01_ = pow(2, kfBaseShiftS01_) * kfBasex1_ * kfBasex1_;
0596     kfBaseK00_ = pow(2, kfBaseShiftK00_) * kfBasex0_ / kfBasex1_;
0597     kfBaseK10_ = pow(2, kfBaseShiftK10_);
0598     kfBaseR00_ = pow(2, kfBaseShiftR00_) * kfBasex1_ * kfBasex1_;
0599     kfBaseInvR00_ = pow(2, kfBaseShiftInvR00_) / kfBasex1_ / kfBasex1_;
0600     kfBaseChi20_ = pow(2, kfBaseShiftChi20_);
0601     kfBaseC00_ = pow(2, kfBaseShiftC00_) * kfBasex0_ * kfBasex0_;
0602     kfBaseC01_ = pow(2, kfBaseShiftC01_) * kfBasex0_ * kfBasex1_;
0603     kfBaseC11_ = pow(2, kfBaseShiftC11_) * kfBasex1_ * kfBasex1_;
0604     kfBaser1_ = pow(2, kfBaseShiftr1_) * kfBasex3_;
0605     kfBaser12_ = pow(2, kfBaseShiftr12_) * kfBasex3_ * kfBasex3_;
0606     kfBasev1_ = pow(2, kfBaseShiftv1_) * kfBasex3_ * kfBasex3_;
0607     kfBaseS12_ = pow(2, kfBaseShiftS12_) * kfBasex2_ * kfBasex3_;
0608     kfBaseS13_ = pow(2, kfBaseShiftS13_) * kfBasex3_ * kfBasex3_;
0609     kfBaseK21_ = pow(2, kfBaseShiftK21_) * kfBasex2_ / kfBasex3_;
0610     kfBaseK31_ = pow(2, kfBaseShiftK31_);
0611     kfBaseR11_ = pow(2, kfBaseShiftR11_) * kfBasex3_ * kfBasex3_;
0612     kfBaseInvR11_ = pow(2, kfBaseShiftInvR11_) / kfBasex3_ / kfBasex3_;
0613     kfBaseChi21_ = pow(2, kfBaseShiftChi21_);
0614     kfBaseC22_ = pow(2, kfBaseShiftC22_) * kfBasex2_ * kfBasex2_;
0615     kfBaseC23_ = pow(2, kfBaseShiftC23_) * kfBasex2_ * kfBasex3_;
0616     kfBaseC33_ = pow(2, kfBaseShiftC33_) * kfBasex3_ * kfBasex3_;
0617   }
0618 
0619   // returns bit accurate position of a stub from a given tfp identifier region [0-8] channel [0-47]
0620   GlobalPoint Setup::stubPos(bool hybrid, const TTDTC::Frame& frame, int tfpRegion, int tfpChannel) const {
0621     GlobalPoint p;
0622     if (frame.first.isNull())
0623       return p;
0624     TTBV bv(frame.second);
0625     if (hybrid) {
0626       const DetId& detId = frame.first->getDetId();
0627       const int dtcId = Setup::dtcId(tfpRegion, tfpChannel);
0628       const bool barrel = detId.subdetId() == StripSubdetector::TOB;
0629       const bool psModule = Setup::psModule(dtcId);
0630       const int layerId =
0631           (barrel ? trackerTopology_->layer(detId) : trackerTopology_->tidWheel(detId)) - offsetLayerId_;
0632       const bool side = Setup::side(dtcId);
0633       SensorModule::Type type;
0634       if (barrel && psModule)
0635         type = SensorModule::BarrelPS;
0636       if (barrel && !psModule)
0637         type = SensorModule::Barrel2S;
0638       if (!barrel && psModule)
0639         type = SensorModule::DiskPS;
0640       if (!barrel && !psModule)
0641         type = SensorModule::Disk2S;
0642       const int widthBend = hybridWidthsBend_.at(type);
0643       const int widthAlpha = hybridWidthsAlpha_.at(type);
0644       const int widthPhi = hybridWidthsPhi_.at(type);
0645       const int widthZ = hybridWidthsZ_.at(type);
0646       const int widthR = hybridWidthsR_.at(type);
0647       const double basePhi = hybridBasesPhi_.at(type);
0648       const double baseZ = hybridBasesZ_.at(type);
0649       const double baseR = hybridBasesR_.at(type);
0650       // parse bit vector
0651       bv >>= 1 + hybridWidthLayer_ + widthBend + widthAlpha;
0652       double phi = (bv.val(widthPhi, 0, true) + .5) * basePhi;
0653       bv >>= widthPhi;
0654       double z = (bv.val(widthZ, 0, true) + .5) * baseZ;
0655       bv >>= widthZ;
0656       double r = (bv.val(widthR, 0, barrel) + .5) * baseR;
0657       if (barrel) {
0658         r += hybridLayerRs_.at(layerId);
0659       } else {
0660         z += hybridDiskZs_.at(layerId) * (side ? 1. : -1.);
0661       }
0662       phi = deltaPhi(phi + tfpRegion * baseRegion_);
0663       if (type == SensorModule::Disk2S) {
0664         r = bv.val(widthR);
0665         r = disk2SRs_.at(layerId).at((int)r);
0666       }
0667       p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z));
0668     } else {
0669       bv >>= 2 * htWidthQoverPt_ + 2 * widthSectorEta_ + numSectorsPhi_ + widthLayer_;
0670       double z = (bv.val(widthZ_, 0, true) + .5) * baseZ_;
0671       bv >>= widthZ_;
0672       double phi = (bv.val(widthPhiDTC_, 0, true) + .5) * basePhi_;
0673       bv >>= widthPhiDTC_;
0674       double r = (bv.val(widthR_, 0, true) + .5) * baseR_;
0675       bv >>= widthR_;
0676       r = r + chosenRofPhi_;
0677       phi = deltaPhi(phi + tfpRegion * baseRegion_);
0678       p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z));
0679     }
0680     return p;
0681   }
0682 
0683   // returns global TTStub position
0684   GlobalPoint Setup::stubPos(const TTStubRef& ttStubRef) const {
0685     const DetId detId = ttStubRef->getDetId() + offsetDetIdDSV_;
0686     const GeomDetUnit* det = trackerGeometry_->idToDetUnit(detId);
0687     const PixelTopology* topol =
0688         dynamic_cast<const PixelTopology*>(&(dynamic_cast<const PixelGeomDetUnit*>(det)->specificTopology()));
0689     const Plane& plane = dynamic_cast<const PixelGeomDetUnit*>(det)->surface();
0690     const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered();
0691     return plane.toGlobal(topol->localPosition(mp));
0692   }
0693 
0694   // range check of dtc id
0695   void Setup::checkDTCId(int dtcId) const {
0696     if (dtcId < 0 || dtcId >= numDTCsPerRegion_ * numRegions_) {
0697       cms::Exception exception("out_of_range");
0698       exception.addContext("trackerDTC::Setup::checkDTCId");
0699       exception << "Used DTC Id (" << dtcId << ") "
0700                 << "is out of range 0 to " << numDTCsPerRegion_ * numRegions_ - 1 << ".";
0701       throw exception;
0702     }
0703   }
0704 
0705   // range check of tklayout id
0706   void Setup::checkTKLayoutId(int tkLayoutId) const {
0707     if (tkLayoutId <= 0 || tkLayoutId > numDTCsPerRegion_ * numRegions_) {
0708       cms::Exception exception("out_of_range");
0709       exception.addContext("trackerDTC::Setup::checkTKLayoutId");
0710       exception << "Used TKLayout Id (" << tkLayoutId << ") "
0711                 << "is out of range 1 to " << numDTCsPerRegion_ * numRegions_ << ".";
0712       throw exception;
0713     }
0714   }
0715 
0716   // range check of tfp identifier
0717   void Setup::checkTFPIdentifier(int tfpRegion, int tfpChannel) const {
0718     const bool oorRegion = tfpRegion >= numRegions_ || tfpRegion < 0;
0719     const bool oorChannel = tfpChannel >= numDTCsPerTFP_ || tfpChannel < 0;
0720     if (oorRegion || oorChannel) {
0721       cms::Exception exception("out_of_range");
0722       exception.addContext("trackerDTC::Setup::checkTFPIdentifier");
0723       if (oorRegion)
0724         exception << "Requested Processing Region "
0725                   << "(" << tfpRegion << ") "
0726                   << "is out of range 0 to " << numRegions_ - 1 << ".";
0727       if (oorChannel)
0728         exception << "Requested TFP Channel "
0729                   << "(" << tfpChannel << ") "
0730                   << "is out of range 0 to " << numDTCsPerTFP_ - 1 << ".";
0731       throw exception;
0732     }
0733   }
0734 
0735 }  // namespace trackerDTC