CMS 3D CMS Logo

pixelCPEforGPU.h
Go to the documentation of this file.
1 #ifndef RecoLocalTracker_SiPixelRecHits_pixelCPEforGPU_h
2 #define RecoLocalTracker_SiPixelRecHits_pixelCPEforGPU_h
3 
4 #include <cassert>
5 #include <cmath>
6 #include <cstdint>
7 #include <iterator>
8 
14 
16  // From https://cmssdt.cern.ch/dxr/CMSSW/source/CondFormats/SiPixelTransient/src/SiPixelGenError.cc#485-486
17  // qbin: int (0-4) describing the charge of the cluster
18  // [0: 1.5<Q/Qavg, 1: 1<Q/Qavg<1.5, 2: 0.85<Q/Qavg<1, 3: 0.95Qmin<Q<0.85Qavg, 4: Q<0.95Qmin]
20  // arbitrary number of bins for sampling errors
22 } // namespace CPEFastParametrisation
23 
24 namespace pixelCPEforGPU {
25 
29 
30  // all modules are identical!
31  struct CommonParams {
34  float thePitchX;
35  float thePitchY;
36 
37  uint16_t maxModuleStride;
39  };
40 
41  struct DetParams {
42  bool isBarrel;
43  bool isPosZ;
44  uint16_t layer;
45  uint16_t index;
46  uint32_t rawId;
47 
48  float shiftX;
49  float shiftY;
50  float chargeWidthX;
51  float chargeWidthY;
52  uint16_t pixmx; // max pix charge
53 
54  uint16_t nRowsRoc; //we don't need 2^16 columns, is worth to use 15 + 1 for sign
55  uint16_t nColsRoc;
56  uint16_t nRows;
57  uint16_t nCols;
58 
59  uint32_t numPixsInModule;
60 
61  float x0, y0, z0; // the vertex in the local coord of the detector
62 
63  float apeXX, apeYY; // ape^2
64  uint8_t sx2, sy1, sy2;
69 
71  };
72 
73  template <typename TrackerTopology>
74  struct LayerGeometryT {
76  uint8_t layer[pixelTopology::layerIndexSize<TrackerTopology>];
77  uint16_t maxModuleStride;
78  };
79 
80  // using LayerGeometry = LayerGeometryT<pixelTopology::Phase1>;
81  // using LayerGeometryPhase2 = LayerGeometryT<pixelTopology::Phase2>;
82 
83  template <typename TrackerTopology>
84  struct ParamsOnGPUT {
87 
92 
93  constexpr CommonParams const& __restrict__ commonParams() const {
94  CommonParams const* __restrict__ l = m_commonParams;
95  return *l;
96  }
97  constexpr DetParams const& __restrict__ detParams(int i) const {
98  DetParams const* __restrict__ l = m_detParams;
99  return l[i];
100  }
101  constexpr LayerGeometry const& __restrict__ layerGeometry() const { return *m_layerGeometry; }
102  constexpr AverageGeometry const& __restrict__ averageGeometry() const { return *m_averageGeometry; }
103 
104  __device__ uint8_t layer(uint16_t id) const {
106  };
107  };
108 
109  // SOA (on device)
110  template <uint32_t N>
111  struct ClusParamsT {
112  uint32_t minRow[N];
113  uint32_t maxRow[N];
114  uint32_t minCol[N];
115  uint32_t maxCol[N];
116 
117  int32_t q_f_X[N];
118  int32_t q_l_X[N];
119  int32_t q_f_Y[N];
120  int32_t q_l_Y[N];
121 
122  int32_t charge[N];
123 
124  float xpos[N];
125  float ypos[N];
126 
127  float xerr[N];
128  float yerr[N];
129 
130  int16_t xsize[N]; // (*8) clipped at 127 if negative is edge....
131  int16_t ysize[N];
132 
134  };
135 
138 
140  DetParams const& __restrict__ detParams, float const x, float const y, float& cotalpha, float& cotbeta) {
141  // x,y local position on det
142  auto gvx = x - detParams.x0;
143  auto gvy = y - detParams.y0;
144  auto gvz = -1.f / detParams.z0;
145  // normalization not required as only ratio used...
146  // calculate angles
147  cotalpha = gvx * gvz;
148  cotbeta = gvy * gvz;
149  }
150 
151  constexpr inline float correction(int sizeM1,
152  int q_f,
153  int q_l,
154  uint16_t upper_edge_first_pix,
155  uint16_t lower_edge_last_pix,
156  float lorentz_shift,
157  float theThickness, //detector thickness
158  float cot_angle,
159  float pitch,
160  bool first_is_big,
161  bool last_is_big)
162  {
163  if (0 == sizeM1) // size 1
164  return 0;
165 
166  float w_eff = 0;
167  bool simple = true;
168  if (1 == sizeM1) { // size 2
169  //--- Width of the clusters minus the edge (first and last) pixels.
170  //--- In the note, they are denoted x_F and x_L (and y_F and y_L)
171  // assert(lower_edge_last_pix >= upper_edge_first_pix);
172  auto w_inner = pitch * float(lower_edge_last_pix - upper_edge_first_pix); // in cm
173 
174  //--- Predicted charge width from geometry
175  auto w_pred = theThickness * cot_angle // geometric correction (in cm)
176  - lorentz_shift; // (in cm) &&& check fpix!
177 
178  w_eff = std::abs(w_pred) - w_inner;
179 
180  //--- If the observed charge width is inconsistent with the expectations
181  //--- based on the track, do *not* use w_pred-w_inner. Instead, replace
182  //--- it with an *average* effective charge width, which is the average
183  //--- length of the edge pixels.
184 
185  // this can produce "large" regressions for very small numeric differences
186  simple = (w_eff < 0.0f) | (w_eff > pitch);
187  }
188 
189  if (simple) {
190  //--- Total length of the two edge pixels (first+last)
191  float sum_of_edge = 2.0f;
192  if (first_is_big)
193  sum_of_edge += 1.0f;
194  if (last_is_big)
195  sum_of_edge += 1.0f;
196  w_eff = pitch * 0.5f * sum_of_edge; // ave. length of edge pixels (first+last) (cm)
197  }
198 
199  //--- Finally, compute the position in this projection
200  float qdiff = q_l - q_f;
201  float qsum = q_l + q_f;
202 
203  //--- Temporary fix for clusters with both first and last pixel with charge = 0
204  if (qsum == 0)
205  qsum = 1.0f;
206 
207  return 0.5f * (qdiff / qsum) * w_eff;
208  }
209 
210  template <typename TrackerTraits>
211  constexpr inline void position(CommonParams const& __restrict__ comParams,
212  DetParams const& __restrict__ detParams,
213  ClusParams& cp,
214  uint32_t ic) {
215  constexpr int maxSize = TrackerTraits::maxSizeCluster;
216  //--- Upper Right corner of Lower Left pixel -- in measurement frame
217  uint16_t llx = cp.minRow[ic] + 1;
218  uint16_t lly = cp.minCol[ic] + 1;
219 
220  //--- Lower Left corner of Upper Right pixel -- in measurement frame
221  uint16_t urx = cp.maxRow[ic];
222  uint16_t ury = cp.maxCol[ic];
223 
224  uint16_t llxl = llx, llyl = lly, urxl = urx, uryl = ury;
225 
226  llxl = TrackerTraits::localX(llx);
227  llyl = TrackerTraits::localY(lly);
228  urxl = TrackerTraits::localX(urx);
229  uryl = TrackerTraits::localY(ury);
230 
231  auto mx = llxl + urxl;
232  auto my = llyl + uryl;
233 
234  int xsize = int(urxl) + 2 - int(llxl);
235  int ysize = int(uryl) + 2 - int(llyl);
236  assert(xsize >= 0); // 0 if bixpix...
237  assert(ysize >= 0);
238 
239  if (TrackerTraits::isBigPixX(cp.minRow[ic]))
240  ++xsize;
241  if (TrackerTraits::isBigPixX(cp.maxRow[ic]))
242  ++xsize;
243  if (TrackerTraits::isBigPixY(cp.minCol[ic]))
244  ++ysize;
245  if (TrackerTraits::isBigPixY(cp.maxCol[ic]))
246  ++ysize;
247 
248  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]);
249  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]);
250 
251  xsize = 8 * xsize - unbalanceX;
252  ysize = 8 * ysize - unbalanceY;
253 
254  cp.xsize[ic] = std::min(xsize, maxSize);
255  cp.ysize[ic] = std::min(ysize, maxSize);
256 
257  if (cp.minRow[ic] == 0 || cp.maxRow[ic] == uint32_t(detParams.nRows - 1))
258  cp.xsize[ic] = -cp.xsize[ic];
259 
260  if (cp.minCol[ic] == 0 || cp.maxCol[ic] == uint32_t(detParams.nCols - 1))
261  cp.ysize[ic] = -cp.ysize[ic];
262 
263  // apply the lorentz offset correction
264  float xoff = 0.5f * float(detParams.nRows) * comParams.thePitchX;
265  float yoff = 0.5f * float(detParams.nCols) * comParams.thePitchY;
266 
267  //correction for bigpixels for phase1
268  xoff = xoff + TrackerTraits::bigPixXCorrection * comParams.thePitchX;
269  yoff = yoff + TrackerTraits::bigPixYCorrection * comParams.thePitchY;
270 
271  // apply the lorentz offset correction
272  auto xPos = detParams.shiftX + (comParams.thePitchX * 0.5f * float(mx)) - xoff;
273  auto yPos = detParams.shiftY + (comParams.thePitchY * 0.5f * float(my)) - yoff;
274 
275  float cotalpha = 0, cotbeta = 0;
276 
277  computeAnglesFromDet(detParams, xPos, yPos, cotalpha, cotbeta);
278 
279  auto thickness = detParams.isBarrel ? comParams.theThicknessB : comParams.theThicknessE;
280 
281  auto xcorr = correction(cp.maxRow[ic] - cp.minRow[ic],
282  cp.q_f_X[ic],
283  cp.q_l_X[ic],
284  llxl,
285  urxl,
286  detParams.chargeWidthX, // lorentz shift in cm
287  thickness,
288  cotalpha,
289  comParams.thePitchX,
290  TrackerTraits::isBigPixX(cp.minRow[ic]),
291  TrackerTraits::isBigPixX(cp.maxRow[ic]));
292 
293  auto ycorr = correction(cp.maxCol[ic] - cp.minCol[ic],
294  cp.q_f_Y[ic],
295  cp.q_l_Y[ic],
296  llyl,
297  uryl,
298  detParams.chargeWidthY, // lorentz shift in cm
299  thickness,
300  cotbeta,
301  comParams.thePitchY,
302  TrackerTraits::isBigPixY(cp.minCol[ic]),
303  TrackerTraits::isBigPixY(cp.maxCol[ic]));
304 
305  cp.xpos[ic] = xPos + xcorr;
306  cp.ypos[ic] = yPos + ycorr;
307  }
308 
309  template <typename TrackerTraits>
310  constexpr inline void errorFromSize(CommonParams const& __restrict__ comParams,
311  DetParams const& __restrict__ detParams,
312  ClusParams& cp,
313  uint32_t ic) {
314  // Edge cluster errors
315  cp.xerr[ic] = 0.0050;
316  cp.yerr[ic] = 0.0085;
317 
318  // FIXME these are errors form Run1
325 
326  constexpr float xerr_barrel_l1[] = {0.00115, 0.00120, 0.00088}; //TODO MOVE THESE SOMEWHERE ELSE
327  constexpr float yerr_barrel_l1[] = {
328  0.00375, 0.00230, 0.00250, 0.00250, 0.00230, 0.00230, 0.00210, 0.00210, 0.00240};
329  constexpr float xerr_barrel_ln[] = {0.00115, 0.00120, 0.00088};
330  constexpr float yerr_barrel_ln[] = {
331  0.00375, 0.00230, 0.00250, 0.00250, 0.00230, 0.00230, 0.00210, 0.00210, 0.00240};
332  constexpr float xerr_endcap[] = {0.0020, 0.0020};
333  constexpr float yerr_endcap[] = {0.00210};
334 
335  auto sx = cp.maxRow[ic] - cp.minRow[ic];
336  auto sy = cp.maxCol[ic] - cp.minCol[ic];
337 
338  // is edgy ?
339  bool isEdgeX = cp.xsize[ic] < 1;
340  bool isEdgeY = cp.ysize[ic] < 1;
341 
342  // is one and big?
343  bool isBig1X = ((0 == sx) && TrackerTraits::isBigPixX(cp.minRow[ic]));
344  bool isBig1Y = ((0 == sy) && TrackerTraits::isBigPixY(cp.minCol[ic]));
345 
346  if (!isEdgeX && !isBig1X) {
347  if (not detParams.isBarrel) {
348  cp.xerr[ic] = sx < std::size(xerr_endcap) ? xerr_endcap[sx] : xerr_endcap_def;
349  } else if (detParams.layer == 1) {
350  cp.xerr[ic] = sx < std::size(xerr_barrel_l1) ? xerr_barrel_l1[sx] : xerr_barrel_l1_def;
351  } else {
352  cp.xerr[ic] = sx < std::size(xerr_barrel_ln) ? xerr_barrel_ln[sx] : xerr_barrel_ln_def;
353  }
354  }
355 
356  if (!isEdgeY && !isBig1Y) {
357  if (not detParams.isBarrel) {
358  cp.yerr[ic] = sy < std::size(yerr_endcap) ? yerr_endcap[sy] : yerr_endcap_def;
359  } else if (detParams.layer == 1) {
360  cp.yerr[ic] = sy < std::size(yerr_barrel_l1) ? yerr_barrel_l1[sy] : yerr_barrel_l1_def;
361  } else {
362  cp.yerr[ic] = sy < std::size(yerr_barrel_ln) ? yerr_barrel_ln[sy] : yerr_barrel_ln_def;
363  }
364  }
365  }
366 
367  template <typename TrackerTraits>
368  constexpr inline void errorFromDB(CommonParams const& __restrict__ comParams,
369  DetParams const& __restrict__ detParams,
370  ClusParams& cp,
371  uint32_t ic) {
372  // Edge cluster errors
373  cp.xerr[ic] = 0.0050f;
374  cp.yerr[ic] = 0.0085f;
375 
376  auto sx = cp.maxRow[ic] - cp.minRow[ic];
377  auto sy = cp.maxCol[ic] - cp.minCol[ic];
378 
379  // is edgy ? (size is set negative: see above)
380  bool isEdgeX = cp.xsize[ic] < 1;
381  bool isEdgeY = cp.ysize[ic] < 1;
382  // is one and big?
383  bool isOneX = (0 == sx);
384  bool isOneY = (0 == sy);
385  bool isBigX = TrackerTraits::isBigPixX(cp.minRow[ic]);
386  bool isBigY = TrackerTraits::isBigPixY(cp.minCol[ic]);
387 
388  auto ch = cp.charge[ic];
389  auto bin = 0;
391  // find first bin which minimum charge exceeds cluster charge
392  if (ch < detParams.minCh[bin + 1])
393  break;
394 
395  // in detParams qBins are reversed bin0 -> smallest charge, bin4-> largest charge
396  // whereas in CondFormats/SiPixelTransient/src/SiPixelGenError.cc it is the opposite
397  // so we reverse the bin here -> kGenErrorQBins - 1 - bin
398  cp.status[ic].qBin = CPEFastParametrisation::kGenErrorQBins - 1 - bin;
399  cp.status[ic].isOneX = isOneX;
400  cp.status[ic].isBigX = (isOneX & isBigX) | isEdgeX;
401  cp.status[ic].isOneY = isOneY;
402  cp.status[ic].isBigY = (isOneY & isBigY) | isEdgeY;
403 
404  auto xoff = -float(TrackerTraits::xOffset) * comParams.thePitchX;
405  int low_value = 0;
406  int high_value = CPEFastParametrisation::kNumErrorBins - 1;
407  int bin_value = float(CPEFastParametrisation::kNumErrorBins) * (cp.xpos[ic] + xoff) / (2 * xoff);
408  // return estimated bin value truncated to [0, 15]
409  int jx = std::clamp(bin_value, low_value, high_value);
410 
411  auto toCM = [](uint8_t x) { return float(x) * 1.e-4f; };
412 
413  if (not isEdgeX) {
414  cp.xerr[ic] = isOneX ? toCM(isBigX ? detParams.sx2 : detParams.sigmax1[jx])
415  : detParams.xfact[bin] * toCM(detParams.sigmax[jx]);
416  }
417 
418  auto ey = cp.ysize[ic] > 8 ? detParams.sigmay[std::min(cp.ysize[ic] - 9, 15)] : detParams.sy1;
419  if (not isEdgeY) {
420  cp.yerr[ic] = isOneY ? toCM(isBigY ? detParams.sy2 : detParams.sy1) : detParams.yfact[bin] * toCM(ey);
421  }
422  }
423 
424  //for Phase2 -> fallback to error from size
425  template <>
426  constexpr inline void errorFromDB<pixelTopology::Phase2>(CommonParams const& __restrict__ comParams,
427  DetParams const& __restrict__ detParams,
428  ClusParams& cp,
429  uint32_t ic) {
430  errorFromSize<pixelTopology::Phase2>(comParams, detParams, cp, ic);
431  }
432 
433 } // namespace pixelCPEforGPU
434 
435 #endif // RecoLocalTracker_SiPixelRecHits_pixelCPEforGPU_h
uint8_t sigmax[CPEFastParametrisation::kNumErrorBins]
float xfact[CPEFastParametrisation::kGenErrorQBins]
uint8_t sigmax1[CPEFastParametrisation::kNumErrorBins]
constexpr uint32_t numberOfLayers
AverageGeometry const * m_averageGeometry
constexpr AverageGeometry const &__restrict__ averageGeometry() const
constexpr LayerGeometry const &__restrict__ layerGeometry() const
DetParams const * m_detParams
constexpr int kGenErrorQBins
const Int_t ysize
assert(be >=bs)
constexpr DetParams const &__restrict__ detParams(int i) const
constexpr void errorFromSize(CommonParams const &__restrict__ comParams, DetParams const &__restrict__ detParams, ClusParams &cp, uint32_t ic)
CommonParams const * m_commonParams
LayerGeometry const * m_layerGeometry
int minCh[CPEFastParametrisation::kGenErrorQBins]
constexpr uint32_t maxHitsInIter()
__device__ uint8_t layer(uint16_t id) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
constexpr void position(CommonParams const &__restrict__ comParams, DetParams const &__restrict__ detParams, ClusParams &cp, uint32_t ic)
constexpr void computeAnglesFromDet(DetParams const &__restrict__ detParams, float const x, float const y, float &cotalpha, float &cotbeta)
constexpr CommonParams const &__restrict__ commonParams() const
#define N
Definition: blowfish.cc:9
T __ldg(T const *x)
Definition: cudaCompat.h:137
constexpr void errorFromDB(CommonParams const &__restrict__ comParams, DetParams const &__restrict__ detParams, ClusParams &cp, uint32_t ic)
constexpr float correction(int sizeM1, int q_f, int q_l, uint16_t upper_edge_first_pix, uint16_t lower_edge_last_pix, float lorentz_shift, float theThickness, float cot_angle, float pitch, bool first_is_big, bool last_is_big)
float yfact[CPEFastParametrisation::kGenErrorQBins]
float x
uint8_t layer[pixelTopology::layerIndexSize< TrackerTopology >]
uint8_t sigmay[CPEFastParametrisation::kNumErrorBins]
const Int_t xsize
#define __device__
constexpr int kNumErrorBins
constexpr int32_t MaxHitsInIter
uint32_t layerStart[TrackerTopology::numberOfLayers+1]
def cp(fromDir, toDir, listOfFiles, overwrite=False, smallList=False)