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
0040 fromDD4hep_(iConfig.getParameter<bool>("fromDD4hep")),
0041
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
0048 pSetPH_(iConfig.getParameter<ParameterSet>("ProcessHistory")),
0049 phGeometryConfiguration_(pSetPH_.getParameter<string>("GeometryConfiguration")),
0050 phTTStubAlgorithm_(pSetPH_.getParameter<string>("TTStubAlgorithm")),
0051
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
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
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
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
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
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
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
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
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
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
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
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
0195 pSetKFin_(iConfig.getParameter<ParameterSet>("KalmanFilterIn")),
0196 kfinShiftRangePhi_(pSetKFin_.getParameter<int>("ShiftRangePhi")),
0197 kfinShiftRangeZ_(pSetKFin_.getParameter<int>("ShiftRangeZ")),
0198
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
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
0213 pSetDR_(iConfig.getParameter<ParameterSet>("DuplicateRemoval")),
0214 drDepthMemory_(pSetDR_.getParameter<int>("DepthMemory")) {
0215 configurationSupported_ = true;
0216
0217 checkMagneticField();
0218
0219 checkGeometry();
0220 if (!configurationSupported_)
0221 return;
0222
0223 calculateConstants();
0224
0225 consumeStubAlgorithm();
0226
0227 encodingsBendPS_.reserve(maxWindowSize_ + 1);
0228 encodingsBend2S_.reserve(maxWindowSize_ + 1);
0229 encodeBend(encodingsBendPS_, true);
0230 encodeBend(encodingsBend2S_, false);
0231
0232 produceSensorModules();
0233
0234 configureTPSelector();
0235 }
0236
0237
0238 void Setup::checkHistory(const ProcessHistory& processHistory) const {
0239 const pset::Registry* psetRegistry = pset::Registry::instance();
0240
0241 checkHistory(processHistory, psetRegistry, phTTStubAlgorithm_, pSetIdTTStubAlgorithm_);
0242
0243 checkHistory(processHistory, psetRegistry, phGeometryConfiguration_, pSetIdGeometryConfiguration_);
0244 }
0245
0246
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
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
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
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
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
0318 bool Setup::psModule(int dtcId) const {
0319 checkDTCId(dtcId);
0320
0321 return slot(dtcId) < slotLimitPS_;
0322 }
0323
0324
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
0341 bool Setup::gbps10(int dtcId) const {
0342 checkDTCId(dtcId);
0343 return slot(dtcId) < slotLimit10gbps_;
0344 }
0345
0346
0347 bool Setup::side(int dtcId) const {
0348 checkDTCId(dtcId);
0349 const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_;
0350
0351 return side == 0;
0352 }
0353
0354
0355 int Setup::slot(int dtcId) const {
0356 checkDTCId(dtcId);
0357 return dtcId % numATCASlots_;
0358 }
0359
0360
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
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
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
0390 void Setup::checkGeometry() {
0391
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
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
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
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
0452 for (const DetId& detId : trackerGeometry_->detIds()) {
0453
0454 if (detId.subdetId() == pixelBarrel || detId.subdetId() == pixelDisks)
0455 continue;
0456
0457 if (!trackerTopology_->isLower(detId))
0458 continue;
0459
0460 const DetId detIdTkLayout = detId + offsetDetIdTP_;
0461
0462 const int tklId = cablingMap_->detIdToDTCELinkId(detIdTkLayout).first->second.dtc_id();
0463
0464 const int dtcId = Setup::dtcId(tklId);
0465
0466 vector<SensorModule*>& dtcModules = dtcModules_[dtcId];
0467
0468 sensorModules_.emplace_back(this, detId, dtcId, dtcModules.size());
0469 SensorModule* sensorModule = &sensorModules_.back();
0470
0471 detIdToSensorModule_.emplace(detId, sensorModule);
0472
0473 dtcModules.push_back(sensorModule);
0474 }
0475 for (vector<SensorModule*>& dtcModules : dtcModules_) {
0476 dtcModules.shrink_to_fit();
0477
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
0488 void Setup::configureTPSelector() {
0489
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
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
0514 int Setup::trackletLayerId(const TTStubRef& ttStubRef) const {
0515 return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetLayerId_ : numBarrelLayer_ - offsetLayerId_);
0516 }
0517
0518
0519 int Setup::indexLayerId(const TTStubRef& ttStubRef) const {
0520 return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetLayerId_ : offsetLayerId_ + offsetLayerDisks_);
0521 }
0522
0523
0524 bool Setup::barrel(const TTStubRef& ttStubRef) const {
0525 const DetId& detId = ttStubRef->getDetId();
0526 return detId.subdetId() == StripSubdetector::TOB;
0527 }
0528
0529
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
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
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
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
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
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
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
0654 void Setup::calculateConstants() {
0655
0656 const int numFramesPerBX = freqBE_ / freqLHC_;
0657 numFrames_ = numFramesPerBX * tmpTFP_ - 1;
0658 numFramesIO_ = numFramesPerBX * tmpTFP_ - numFramesInfra_;
0659 numFramesFE_ = numFramesPerBX * tmpFE_ - numFramesInfra_;
0660
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
0668 maxPitch_ = max(pitchPS_, pitch2S_);
0669 maxLength_ = max(lengthPS_, length2S_);
0670
0671 invPtToDphi_ = speedOfLight_ * bField_ / 2000.;
0672 baseRegion_ = 2. * M_PI / numRegions_;
0673
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
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
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
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
0746 mhtNumCells_ = mhtNumBinsInv2R_ * mhtNumBinsPhiT_;
0747
0748 zhtNumCells_ = zhtNumBinsCot_ * zhtNumBinsZT_;
0749
0750 kfWidthLayerCount_ = ceil(log2(zhtMaxStubsPerLayer_));
0751 }
0752
0753
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
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
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
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
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
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
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 }