Back to home page

Project CMSSW displayed by LXR

 
 

    


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     // get stub local coordinates
0023     const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered();
0024     // convert to uniformed local coordinates
0025     // column number in pitch units
0026     col_ = std::floor(std::pow(-1, sm_->signCol()) * (mp.y() - sm_->numColumns() / 2) / setup_->baseCol());
0027     // row number in half pitch units
0028     row_ = std::floor(std::pow(-1, sm_->signRow()) * (mp.x() - sm_->numRows() / 2) / setup_->baseRow());
0029     // bend number in quarter pitch units
0030     bend_ = std::floor(std::pow(-1, sm_->signBend()) * (ttStubRef->bendBE()) / setup_->baseBend());
0031     // reduced row number for look up
0032     rowLUT_ = std::floor(static_cast<double>(row_) / std::pow(2., setup_->widthRow() - setup_->dtcWidthRowLUT()));
0033     // sub row number inside reduced row number
0034     rowSub_ = row_ - (rowLUT_ + .5) * std::pow(2, setup_->widthRow() - setup_->dtcWidthRowLUT());
0035     // convert local to global coordinates
0036     const double y = (col_ + .5) * setup_->baseCol() * sm_->pitchCol();
0037     // radius of a column of strips/pixel in cm
0038     d_ = sm_->r() + y * sm_->sinTilt();
0039     // stub z in cm
0040     z_ = dfZ.digi(sm_->z() + y * sm_->cosTilt());
0041     const double x = (rowLUT_ + .5) * setup_->baseRow() * setup_->dtcNumMergedRows() * sm_->pitchRow();
0042     // stub r wrt chosen RofPhi in cm
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     // intercept of linearized stub phi in rad
0051     c_ = digi(c, dfPhi.base() / 2.);
0052     // slope of linearized stub phi in rad / strip
0053     m_ = digi(m, setup_->dtcBaseM());
0054     // stub phi w.r.t. detector region centre in rad
0055     phi_ = dfPhi.digi(c_ + rowSub_ * m_);
0056     // assaign stub to processing regions
0057     // radial (cylindrical) component of sensor separation
0058     const double dr = sm_->sep() / (sm_->cosTilt() - sm_->sinTilt() * z_ / d_);
0059     // converts bend into inv2R in 1/cm
0060     const double inv2ROverBend = sm_->pitchRow() / dr / d_;
0061     // inv2R in 1/cm
0062     const double inv2R = -bend_ * setup_->baseBend() * inv2ROverBend;
0063     // inv2R uncertainty in 1/cm
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     // cut on pt
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     // range of stub extrapolated phi to radius chosenRofPhi in rad
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     // apply "eta" cut
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     // extrapolated z at radius T assuming z0=0
0108     const double zT = z_ * ratioRZ;
0109     // extrapolated z0 window at radius T
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     // apply data format specific manipulations
0115     if (!setup_->useHybrid())
0116       return;
0117     // stub r w.r.t. an offset in cm
0118     r_ -= sm->offsetR() - setup->chosenRofPhi();
0119     // stub z w.r.t. an offset in cm
0120     z_ -= sm->offsetZ();
0121     if (sm->type() == tt::SensorModule::Disk2S) {
0122       // encoded r
0123       r_ = sm->encodedR() + (sm->side() ? -col_ : (col_ + sm->numColumns() / 2));
0124       r_ = (r_ + 0.5) * setup->hybridBaseR(sm->type());
0125     }
0126     // encode bend
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   // returns bit accurate representation of Stub
0134   tt::FrameStub Stub::frame(int region) const {
0135     return make_pair(ttStubRef_, setup_->useHybrid() ? formatHybrid(region) : formatTMTT(region));
0136   }
0137 
0138   // truncates double precision to f/w integer equivalent
0139   double Stub::digi(double value, double precision) const {
0140     return (std::floor(value / precision + 1.e-12) + .5) * precision;
0141   }
0142 
0143   // returns 64 bit stub in hybrid data format
0144   tt::Frame Stub::formatHybrid(int region) const {
0145     const tt::SensorModule::Type type = sm_->type();
0146     // layer encoding
0147     const int decodedLayerId = layerEncoding_->decode(sm_);
0148     // stub phi w.r.t. processing region border in rad
0149     double phi = phi_ - (region - .5) * setup_->baseRegion() + setup_->hybridRangePhi() / 2.;
0150     // convert stub variables into bit vectors
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     // assemble final bitset
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 }  // namespace trackerDTC