File indexing completed on 2025-07-03 00:42:36
0001 #ifndef RecoLocalTracker_SiPixelRecHits_interface_pixelCPEforDevice_h
0002 #define RecoLocalTracker_SiPixelRecHits_interface_pixelCPEforDevice_h
0003
0004 #include <algorithm>
0005 #include <cassert>
0006 #include <cmath>
0007 #include <cstdint>
0008 #include <iterator>
0009
0010 #include "DataFormats/SiPixelClusterSoA/interface/ClusteringConstants.h"
0011 #include "Geometry/CommonTopologies/interface/SimplePixelTopology.h"
0012 #include "DataFormats/TrackingRecHitSoA/interface/SiPixelHitStatus.h"
0013 #include "DataFormats/SiPixelClusterSoA/interface/ClusteringConstants.h"
0014 #include "DataFormats/GeometrySurface/interface/SOARotation.h"
0015 #include "Geometry/CommonTopologies/interface/SimplePixelTopology.h"
0016
0017
0018
0019 namespace pixelCPEforDevice {
0020
0021
0022
0023
0024 constexpr int kGenErrorQBins = 5;
0025
0026 constexpr int kNumErrorBins = 16;
0027
0028 constexpr float micronsToCm = 1.0e-4f;
0029
0030 using Status = SiPixelHitStatus;
0031 using Frame = SOAFrame<float>;
0032 using Rotation = SOARotation<float>;
0033
0034
0035
0036 template <uint32_t N>
0037 struct ClusParamsT {
0038 uint32_t minRow[N];
0039 uint32_t maxRow[N];
0040 uint32_t minCol[N];
0041 uint32_t maxCol[N];
0042
0043 int32_t q_f_X[N];
0044 int32_t q_l_X[N];
0045 int32_t q_f_Y[N];
0046 int32_t q_l_Y[N];
0047
0048 int32_t charge[N];
0049
0050 float xpos[N];
0051 float ypos[N];
0052
0053 float xerr[N];
0054 float yerr[N];
0055
0056 int16_t xsize[N];
0057 int16_t ysize[N];
0058
0059 Status status[N];
0060 };
0061
0062
0063 struct CommonParams {
0064 float theThicknessB;
0065 float theThicknessE;
0066 };
0067
0068 struct DetParams {
0069 bool isBarrel;
0070 bool isPosZ;
0071 uint16_t layer;
0072 uint16_t index;
0073 uint32_t rawId;
0074
0075 float shiftX;
0076 float shiftY;
0077 float thePitchX;
0078 float thePitchY;
0079 float chargeWidthX;
0080 float chargeWidthY;
0081 uint16_t pixmx;
0082
0083 uint16_t nRowsRoc;
0084 uint16_t nColsRoc;
0085 uint16_t nRows;
0086 uint16_t nCols;
0087
0088 uint32_t numPixsInModule;
0089
0090 float x0, y0, z0;
0091
0092 float apeXX, apeYY;
0093 uint8_t sx2, sy1, sy2;
0094 uint8_t sigmax[kNumErrorBins], sigmax1[kNumErrorBins],
0095 sigmay[kNumErrorBins];
0096 float xfact[kGenErrorQBins], yfact[kGenErrorQBins];
0097 int minCh[kGenErrorQBins];
0098
0099 Frame frame;
0100 };
0101
0102 constexpr int32_t MaxHitsInIter = pixelClustering::maxHitsInIter();
0103 using ClusParams = ClusParamsT<MaxHitsInIter>;
0104
0105 constexpr inline void computeAnglesFromDet(
0106 DetParams const& __restrict__ detParams, float const x, float const y, float& cotalpha, float& cotbeta) {
0107
0108 auto gvx = x - detParams.x0;
0109 auto gvy = y - detParams.y0;
0110 auto gvz = -1.f / detParams.z0;
0111
0112
0113 cotalpha = gvx * gvz;
0114 cotbeta = gvy * gvz;
0115 }
0116
0117 constexpr inline float correction(int sizeM1,
0118 int q_f,
0119 int q_l,
0120 uint16_t upper_edge_first_pix,
0121 uint16_t lower_edge_last_pix,
0122 float lorentz_shift,
0123 float theThickness,
0124 float cot_angle,
0125 float pitch,
0126 bool first_is_big,
0127 bool last_is_big)
0128 {
0129 if (0 == sizeM1)
0130 return 0;
0131
0132 float w_eff = 0;
0133 bool simple = true;
0134 if (1 == sizeM1) {
0135
0136
0137
0138 auto w_inner = pitch * float(lower_edge_last_pix - upper_edge_first_pix);
0139
0140
0141 auto w_pred = theThickness * cot_angle
0142 - lorentz_shift;
0143
0144 w_eff = std::abs(w_pred) - w_inner;
0145
0146
0147
0148
0149
0150
0151
0152 simple = (w_eff < 0.0f) | (w_eff > pitch);
0153 }
0154
0155 if (simple) {
0156
0157 float sum_of_edge = 2.0f;
0158 if (first_is_big)
0159 sum_of_edge += 1.0f;
0160 if (last_is_big)
0161 sum_of_edge += 1.0f;
0162 w_eff = pitch * 0.5f * sum_of_edge;
0163 }
0164
0165
0166 float qdiff = q_l - q_f;
0167 float qsum = q_l + q_f;
0168
0169
0170 if (qsum == 0)
0171 qsum = 1.0f;
0172
0173 return 0.5f * (qdiff / qsum) * w_eff;
0174 }
0175
0176 template <typename TrackerTraits>
0177 constexpr inline void position(CommonParams const& __restrict__ comParams,
0178 DetParams const& __restrict__ detParams,
0179 ClusParams& cp,
0180 uint32_t ic) {
0181 constexpr int maxSize = TrackerTraits::maxSizeCluster;
0182
0183 uint16_t llx = cp.minRow[ic] + 1;
0184 uint16_t lly = cp.minCol[ic] + 1;
0185
0186
0187 uint16_t urx = cp.maxRow[ic];
0188 uint16_t ury = cp.maxCol[ic];
0189
0190 uint16_t llxl = llx, llyl = lly, urxl = urx, uryl = ury;
0191
0192 llxl = TrackerTraits::localX(llx);
0193 llyl = TrackerTraits::localY(lly);
0194 urxl = TrackerTraits::localX(urx);
0195 uryl = TrackerTraits::localY(ury);
0196
0197 auto mx = llxl + urxl;
0198 auto my = llyl + uryl;
0199
0200 int xsize = int(urxl) + 2 - int(llxl);
0201 int ysize = int(uryl) + 2 - int(llyl);
0202 assert(xsize >= 0);
0203 assert(ysize >= 0);
0204
0205 if (TrackerTraits::isBigPixX(cp.minRow[ic]))
0206 ++xsize;
0207 if (TrackerTraits::isBigPixX(cp.maxRow[ic]))
0208 ++xsize;
0209 if (TrackerTraits::isBigPixY(cp.minCol[ic]))
0210 ++ysize;
0211 if (TrackerTraits::isBigPixY(cp.maxCol[ic]))
0212 ++ysize;
0213
0214 int unbalanceX = 8.f * std::abs(float(cp.q_f_X[ic] - cp.q_l_X[ic])) / float(cp.q_f_X[ic] + cp.q_l_X[ic]);
0215 int unbalanceY = 8.f * std::abs(float(cp.q_f_Y[ic] - cp.q_l_Y[ic])) / float(cp.q_f_Y[ic] + cp.q_l_Y[ic]);
0216
0217 xsize = 8 * xsize - unbalanceX;
0218 ysize = 8 * ysize - unbalanceY;
0219
0220 cp.xsize[ic] = std::min(xsize, maxSize);
0221 cp.ysize[ic] = std::min(ysize, maxSize);
0222
0223 if (cp.minRow[ic] == 0 || cp.maxRow[ic] == uint32_t(detParams.nRows - 1))
0224 cp.xsize[ic] = -cp.xsize[ic];
0225
0226 if (cp.minCol[ic] == 0 || cp.maxCol[ic] == uint32_t(detParams.nCols - 1))
0227 cp.ysize[ic] = -cp.ysize[ic];
0228
0229
0230
0231
0232
0233 float xPos = std::fmaf(0.5f * ((float)mx - (float)detParams.nRows) - TrackerTraits::bigPixXCorrection,
0234 detParams.thePitchX,
0235 detParams.shiftX);
0236 float yPos = std::fmaf(0.5f * ((float)my - (float)detParams.nCols) - TrackerTraits::bigPixYCorrection,
0237 detParams.thePitchY,
0238 detParams.shiftY);
0239
0240 float cotalpha = 0, cotbeta = 0;
0241
0242 computeAnglesFromDet(detParams, xPos, yPos, cotalpha, cotbeta);
0243
0244 auto thickness = detParams.isBarrel ? comParams.theThicknessB : comParams.theThicknessE;
0245
0246 auto xCorr = correction(cp.maxRow[ic] - cp.minRow[ic],
0247 cp.q_f_X[ic],
0248 cp.q_l_X[ic],
0249 llxl,
0250 urxl,
0251 detParams.chargeWidthX,
0252 thickness,
0253 cotalpha,
0254 detParams.thePitchX,
0255 TrackerTraits::isBigPixX(cp.minRow[ic]),
0256 TrackerTraits::isBigPixX(cp.maxRow[ic]));
0257
0258 auto yCorr = correction(cp.maxCol[ic] - cp.minCol[ic],
0259 cp.q_f_Y[ic],
0260 cp.q_l_Y[ic],
0261 llyl,
0262 uryl,
0263 detParams.chargeWidthY,
0264 thickness,
0265 cotbeta,
0266 detParams.thePitchY,
0267 TrackerTraits::isBigPixY(cp.minCol[ic]),
0268 TrackerTraits::isBigPixY(cp.maxCol[ic]));
0269
0270 cp.xpos[ic] = xPos + xCorr;
0271 cp.ypos[ic] = yPos + yCorr;
0272 }
0273
0274 template <typename TrackerTraits>
0275 constexpr inline void errorFromSize(CommonParams const& __restrict__ comParams,
0276 DetParams const& __restrict__ detParams,
0277 ClusParams& cp,
0278 uint32_t ic) {
0279
0280 cp.xerr[ic] = 0.0050;
0281 cp.yerr[ic] = 0.0085;
0282
0283
0284 float xerr_barrel_l1_def = TrackerTraits::xerr_barrel_l1_def;
0285 float yerr_barrel_l1_def = TrackerTraits::yerr_barrel_l1_def;
0286 float xerr_barrel_ln_def = TrackerTraits::xerr_barrel_ln_def;
0287 float yerr_barrel_ln_def = TrackerTraits::yerr_barrel_ln_def;
0288 float xerr_endcap_def = TrackerTraits::xerr_endcap_def;
0289 float yerr_endcap_def = TrackerTraits::yerr_endcap_def;
0290
0291 constexpr float xerr_barrel_l1[] = {0.00115, 0.00120, 0.00088};
0292 constexpr float yerr_barrel_l1[] = {
0293 0.00375, 0.00230, 0.00250, 0.00250, 0.00230, 0.00230, 0.00210, 0.00210, 0.00240};
0294 constexpr float xerr_barrel_ln[] = {0.00115, 0.00120, 0.00088};
0295 constexpr float yerr_barrel_ln[] = {
0296 0.00375, 0.00230, 0.00250, 0.00250, 0.00230, 0.00230, 0.00210, 0.00210, 0.00240};
0297 constexpr float xerr_endcap[] = {0.0020, 0.0020};
0298 constexpr float yerr_endcap[] = {0.00210};
0299
0300 auto sx = cp.maxRow[ic] - cp.minRow[ic];
0301 auto sy = cp.maxCol[ic] - cp.minCol[ic];
0302
0303
0304 bool isEdgeX = cp.xsize[ic] < 1;
0305 bool isEdgeY = cp.ysize[ic] < 1;
0306
0307
0308 bool isBig1X = ((0 == sx) && TrackerTraits::isBigPixX(cp.minRow[ic]));
0309 bool isBig1Y = ((0 == sy) && TrackerTraits::isBigPixY(cp.minCol[ic]));
0310
0311 if (!isEdgeX && !isBig1X) {
0312 if (not detParams.isBarrel) {
0313 cp.xerr[ic] = sx < std::size(xerr_endcap) ? xerr_endcap[sx] : xerr_endcap_def;
0314 } else if (detParams.layer == 1) {
0315 cp.xerr[ic] = sx < std::size(xerr_barrel_l1) ? xerr_barrel_l1[sx] : xerr_barrel_l1_def;
0316 } else {
0317 cp.xerr[ic] = sx < std::size(xerr_barrel_ln) ? xerr_barrel_ln[sx] : xerr_barrel_ln_def;
0318 }
0319 }
0320
0321 if (!isEdgeY && !isBig1Y) {
0322 if (not detParams.isBarrel) {
0323 cp.yerr[ic] = sy < std::size(yerr_endcap) ? yerr_endcap[sy] : yerr_endcap_def;
0324 } else if (detParams.layer == 1) {
0325 cp.yerr[ic] = sy < std::size(yerr_barrel_l1) ? yerr_barrel_l1[sy] : yerr_barrel_l1_def;
0326 } else {
0327 cp.yerr[ic] = sy < std::size(yerr_barrel_ln) ? yerr_barrel_ln[sy] : yerr_barrel_ln_def;
0328 }
0329 }
0330 }
0331
0332 template <typename TrackerTraits>
0333 constexpr inline void errorFromDB(CommonParams const& __restrict__ comParams,
0334 DetParams const& __restrict__ detParams,
0335 ClusParams& cp,
0336 uint32_t ic) {
0337
0338 cp.xerr[ic] = 0.0050f;
0339 cp.yerr[ic] = 0.0085f;
0340
0341 auto sx = cp.maxRow[ic] - cp.minRow[ic];
0342 auto sy = cp.maxCol[ic] - cp.minCol[ic];
0343
0344
0345 bool isEdgeX = cp.xsize[ic] < 1;
0346 bool isEdgeY = cp.ysize[ic] < 1;
0347
0348 bool isOneX = (0 == sx);
0349 bool isOneY = (0 == sy);
0350 bool isBigX = TrackerTraits::isBigPixX(cp.minRow[ic]);
0351 bool isBigY = TrackerTraits::isBigPixY(cp.minCol[ic]);
0352
0353 auto ch = cp.charge[ic];
0354 auto bin = 0;
0355 for (; bin < kGenErrorQBins - 1; ++bin)
0356
0357 if (ch < detParams.minCh[bin + 1])
0358 break;
0359
0360
0361
0362
0363 cp.status[ic].qBin = kGenErrorQBins - 1 - bin;
0364 cp.status[ic].isOneX = isOneX;
0365 cp.status[ic].isBigX = (isOneX & isBigX) | isEdgeX;
0366 cp.status[ic].isOneY = isOneY;
0367 cp.status[ic].isBigY = (isOneY & isBigY) | isEdgeY;
0368
0369 auto xoff = -float(TrackerTraits::xOffset) * detParams.thePitchX;
0370 int low_value = 0;
0371 int high_value = kNumErrorBins - 1;
0372 int bin_value = float(kNumErrorBins) * (cp.xpos[ic] + xoff) / (2 * xoff);
0373
0374
0375
0376
0377 int tmp_max = std::max<int>(bin_value, low_value);
0378 int jx = std::min<int>(tmp_max, high_value);
0379
0380 auto toCM = [](uint8_t x) { return float(x) * 1.e-4f; };
0381
0382 if (not isEdgeX) {
0383 cp.xerr[ic] = isOneX ? toCM(isBigX ? detParams.sx2 : detParams.sigmax1[jx])
0384 : detParams.xfact[bin] * toCM(detParams.sigmax[jx]);
0385 }
0386
0387 auto ey = cp.ysize[ic] > 8 ? detParams.sigmay[std::min(cp.ysize[ic] - 9, 15)] : detParams.sy1;
0388 if (not isEdgeY) {
0389 cp.yerr[ic] = isOneY ? toCM(isBigY ? detParams.sy2 : detParams.sy1) : detParams.yfact[bin] * toCM(ey);
0390 }
0391 }
0392
0393
0394 template <>
0395 constexpr inline void errorFromDB<pixelTopology::Phase2>(CommonParams const& __restrict__ comParams,
0396 DetParams const& __restrict__ detParams,
0397 ClusParams& cp,
0398 uint32_t ic) {
0399 errorFromSize<pixelTopology::Phase2>(comParams, detParams, cp, ic);
0400 }
0401
0402 template <typename TrackerTopology>
0403 struct ParamsOnDeviceT {
0404 CommonParams m_commonParams;
0405
0406 DetParams m_detParams[TrackerTopology::numberOfModules];
0407
0408 constexpr CommonParams const& __restrict__ commonParams() const { return m_commonParams; }
0409 constexpr DetParams const& __restrict__ detParams(int i) const { return m_detParams[i]; }
0410
0411 CommonParams& commonParams() { return m_commonParams; }
0412 DetParams& detParams(int i) { return m_detParams[i]; }
0413
0414 #ifdef ONLY_TRIPLETS_IN_HOLE
0415 using AverageGeometry = pixelTopology::AverageGeometryT<TrackerTopology>;
0416
0417 AverageGeometry m_averageGeometry;
0418 constexpr AverageGeometry const& __restrict__ averageGeometry() const { return m_averageGeometry; }
0419 AverageGeometry& averageGeometry() { return m_averageGeometry; }
0420 #endif
0421 };
0422
0423 }
0424
0425 #endif