File indexing completed on 2025-06-11 03:00:12
0001 #include "L1Trigger/TrackerDTC/interface/Stub.h"
0002
0003 #include <cmath>
0004 #include <iterator>
0005 #include <algorithm>
0006 #include <utility>
0007
0008 namespace trackerDTC {
0009
0010 Stub::Stub(const trackerTFP::DataFormats* dataFormats, const tt::SensorModule* sm, const TTStubRef& ttStubRef)
0011 : setup_(dataFormats->setup()),
0012 dataFormats_(dataFormats),
0013 layerEncoding_(nullptr),
0014 sm_(sm),
0015 ttStubRef_(ttStubRef),
0016 valid_(true),
0017 regions_(0, setup_->numOverlappingRegions()) {
0018 const trackerTFP::DataFormat& dfR = dataFormats_->format(trackerTFP::Variable::r, trackerTFP::Process::dtc);
0019 const trackerTFP::DataFormat& dfPhi = dataFormats_->format(trackerTFP::Variable::phi, trackerTFP::Process::dtc);
0020 const trackerTFP::DataFormat& dfZ = dataFormats_->format(trackerTFP::Variable::z, trackerTFP::Process::dtc);
0021 const trackerTFP::DataFormat& dfInv2R = dataFormats_->format(trackerTFP::Variable::inv2R, trackerTFP::Process::ht);
0022
0023 const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered();
0024
0025
0026 col_ = std::floor(std::pow(-1, sm_->signCol()) * (mp.y() - sm_->numColumns() / 2) / setup_->baseCol());
0027
0028 row_ = std::floor(std::pow(-1, sm_->signRow()) * (mp.x() - sm_->numRows() / 2) / setup_->baseRow());
0029
0030 bend_ = std::floor(std::pow(-1, sm_->signBend()) * (ttStubRef->bendBE()) / setup_->baseBend());
0031
0032 rowLUT_ = std::floor(static_cast<double>(row_) / std::pow(2., setup_->widthRow() - setup_->dtcWidthRowLUT()));
0033
0034 rowSub_ = row_ - (rowLUT_ + .5) * std::pow(2, setup_->widthRow() - setup_->dtcWidthRowLUT());
0035
0036 const double y = (col_ + .5) * setup_->baseCol() * sm_->pitchCol();
0037
0038 d_ = sm_->r() + y * sm_->sinTilt();
0039
0040 z_ = dfZ.digi(sm_->z() + y * sm_->cosTilt());
0041 const double x = (rowLUT_ + .5) * setup_->baseRow() * setup_->dtcNumMergedRows() * sm_->pitchRow();
0042
0043 r_ = dfR.digi(std::sqrt(d_ * d_ + x * x) - setup_->chosenRofPhi());
0044 const double x0 = rowLUT_ * setup_->baseRow() * setup_->dtcNumMergedRows() * sm_->pitchRow();
0045 const double x1 = (rowLUT_ + 1) * setup_->baseRow() * setup_->dtcNumMergedRows() * sm_->pitchRow();
0046 const double phi0 = sm_->phi() + std::atan2(x0, d_);
0047 const double phi1 = sm_->phi() + std::atan2(x1, d_);
0048 const double c = (phi0 + phi1) / 2.;
0049 const double m = (phi1 - phi0) / setup_->dtcNumMergedRows();
0050
0051 c_ = digi(c, dfPhi.base() / 2.);
0052
0053 m_ = digi(m, setup_->dtcBaseM());
0054
0055 phi_ = dfPhi.digi(c_ + rowSub_ * m_);
0056
0057
0058 const double dr = sm_->sep() / (sm_->cosTilt() - sm_->sinTilt() * z_ / d_);
0059
0060 const double inv2ROverBend = sm_->pitchRow() / dr / d_;
0061
0062 const double inv2R = -bend_ * setup_->baseBend() * inv2ROverBend;
0063
0064 const double dInv2R = setup_->bendCut() * inv2ROverBend;
0065 inv2R_.first = dfInv2R.digi(inv2R - dInv2R);
0066 inv2R_.second = dfInv2R.digi(inv2R + dInv2R);
0067 const double maxInv2R = dfInv2R.range() / 2.;
0068
0069 if (inv2R_.first > maxInv2R || inv2R_.second < -maxInv2R)
0070 valid_ = false;
0071 else {
0072 inv2R_.first = std::max(inv2R_.first, -maxInv2R);
0073 inv2R_.second = std::min(inv2R_.second, maxInv2R);
0074 }
0075
0076 phiT_.first = phi_ - r_ * inv2R_.first;
0077 phiT_.second = phi_ - r_ * inv2R_.second;
0078 if (phiT_.first > phiT_.second)
0079 std::swap(phiT_.first, phiT_.second);
0080 if (phiT_.first < 0.)
0081 regions_.set(0);
0082 if (phiT_.second >= 0.)
0083 regions_.set(1);
0084 }
0085
0086 Stub::Stub(const tt::Setup* setup,
0087 const trackerTFP::DataFormats* dataFormats,
0088 const LayerEncoding* layerEncoding,
0089 const tt::SensorModule* sm,
0090 const TTStubRef& ttStubRef)
0091 : setup_(setup), dataFormats_(dataFormats), layerEncoding_(layerEncoding), sm_(sm), ttStubRef_(ttStubRef) {
0092 const Stub stub(dataFormats, sm, ttStubRef);
0093 bend_ = stub.bend_;
0094 valid_ = stub.valid_;
0095 row_ = stub.row_;
0096 col_ = stub.col_;
0097 r_ = stub.r_;
0098 phi_ = stub.phi_;
0099 z_ = stub.z_;
0100 phiT_ = stub.phiT_;
0101 inv2R_ = stub.inv2R_;
0102 regions_ = stub.regions_;
0103
0104 const trackerTFP::DataFormat& dfZT = dataFormats->format(trackerTFP::Variable::zT, trackerTFP::Process::gp);
0105 const double r = r_ + setup->chosenRofPhi();
0106 const double ratioRZ = setup->chosenRofZ() / r;
0107
0108 const double zT = z_ * ratioRZ;
0109
0110 const double dZT = setup->beamWindowZ() * std::abs(1. - ratioRZ);
0111 zT_ = {zT - dZT, zT + dZT};
0112 if (std::abs(zT) > dfZT.range() / 2. + dZT)
0113 valid_ = false;
0114
0115 if (!setup_->useHybrid())
0116 return;
0117
0118 r_ -= sm->offsetR() - setup->chosenRofPhi();
0119
0120 z_ -= sm->offsetZ();
0121 if (sm->type() == tt::SensorModule::Disk2S) {
0122
0123 r_ = sm->encodedR() + (sm->side() ? -col_ : (col_ + sm->numColumns() / 2));
0124 r_ = (r_ + 0.5) * setup->hybridBaseR(sm->type());
0125 }
0126
0127 const std::vector<double>& encodingBend = setup->encodingBend(sm->windowSize(), sm->psModule());
0128 const auto pos = std::find(encodingBend.begin(), encodingBend.end(), std::abs(ttStubRef->bendBE()));
0129 const int uBend = std::distance(encodingBend.begin(), pos);
0130 bend_ = std::pow(-1, std::signbit(bend_)) * uBend;
0131 }
0132
0133
0134 tt::FrameStub Stub::frame(int region) const {
0135 return make_pair(ttStubRef_, setup_->useHybrid() ? formatHybrid(region) : formatTMTT(region));
0136 }
0137
0138
0139 double Stub::digi(double value, double precision) const {
0140 return (std::floor(value / precision + 1.e-12) + .5) * precision;
0141 }
0142
0143
0144 tt::Frame Stub::formatHybrid(int region) const {
0145 const tt::SensorModule::Type type = sm_->type();
0146
0147 const int decodedLayerId = layerEncoding_->decode(sm_);
0148
0149 double phi = phi_ - (region - .5) * setup_->baseRegion() + setup_->hybridRangePhi() / 2.;
0150
0151 const bool twosR = type == tt::SensorModule::BarrelPS || type == tt::SensorModule::Barrel2S;
0152 const bool noAlpha = type != tt::SensorModule::Disk2S;
0153 const std::string hwR = TTBV(r_, setup_->hybridBaseR(type), setup_->hybridWidthR(type), twosR).str();
0154 const std::string hwPhi = TTBV(phi, setup_->hybridBasePhi(type), setup_->hybridWidthPhi(type)).str();
0155 const std::string hwZ = TTBV(z_, setup_->hybridBaseZ(type), setup_->hybridWidthZ(type), true).str();
0156 const std::string hwAlpha =
0157 noAlpha ? "" : TTBV(row_, setup_->hybridBaseAlpha(type), setup_->hybridWidthAlpha(type), true).str();
0158 const std::string hwBend = TTBV(bend_, setup_->hybridWidthBend(type), true).str();
0159 const std::string hwLayer = TTBV(decodedLayerId, setup_->hybridWidthLayerId()).str();
0160 const std::string hwGap = TTBV(0, setup_->hybridNumUnusedBits(type)).str();
0161 const std::string hwValid = TTBV(1, 1).str();
0162
0163 return tt::Frame(hwGap + hwR + hwZ + hwPhi + hwAlpha + hwBend + hwLayer + hwValid);
0164 }
0165
0166 tt::Frame Stub::formatTMTT(int region) const {
0167 const trackerTFP::DataFormat& dfInv2R = dataFormats_->format(trackerTFP::Variable::inv2R, trackerTFP::Process::ht);
0168 const trackerTFP::DataFormat& dfPhiT = dataFormats_->format(trackerTFP::Variable::phiT, trackerTFP::Process::gp);
0169 const trackerTFP::DataFormat& dfZT = dataFormats_->format(trackerTFP::Variable::zT, trackerTFP::Process::gp);
0170 const double offset = (region - .5) * dfPhiT.range();
0171 const double r = r_;
0172 const double phi = phi_ - offset;
0173 const double z = z_;
0174 const int indexLayerId = setup_->indexLayerId(ttStubRef_);
0175 TTBV layer(indexLayerId, dataFormats_->width(trackerTFP::Variable::layer, trackerTFP::Process::dtc));
0176 if (sm_->barrel()) {
0177 layer.set(4);
0178 if (sm_->tilted())
0179 layer.set(3);
0180 } else if (sm_->psModule())
0181 layer.set(3);
0182 int phiTMin = std::max(dfPhiT.integer(phiT_.first - offset), -setup_->gpNumBinsPhiT() / 2);
0183 int phiTMax = std::min(dfPhiT.integer(phiT_.second - offset), setup_->gpNumBinsPhiT() / 2 - 1);
0184 if (phiTMin > setup_->gpNumBinsPhiT() / 2 - 1)
0185 phiTMin = setup_->gpNumBinsPhiT() / 2 - 1;
0186 if (phiTMax < -setup_->gpNumBinsPhiT() / 2)
0187 phiTMax = -setup_->gpNumBinsPhiT() / 2;
0188 const int zTMin = std::max(dfZT.integer(zT_.first), -setup_->gpNumBinsZT() / 2);
0189 const int zTMax = std::min(dfZT.integer(zT_.second), setup_->gpNumBinsZT() / 2 - 1);
0190 const int inv2RMin = std::max(dfInv2R.integer(inv2R_.first), -setup_->htNumBinsInv2R() / 2);
0191 const int inv2RMax = std::min(dfInv2R.integer(inv2R_.second), setup_->htNumBinsInv2R() / 2 - 1);
0192 const trackerTFP::StubDTC stub(
0193 ttStubRef_, dataFormats_, r, phi, z, layer, phiTMin, phiTMax, zTMin, zTMax, inv2RMin, inv2RMax);
0194 return stub.frame().second;
0195 }
0196
0197 }