CMS 3D CMS Logo

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