CMS 3D CMS Logo

PixelCPEGenericForBricked.cc
Go to the documentation of this file.
2 
6 
7 // Pixel templates contain the rec hit error parameterizaiton
9 
10 // The generic formula
12 
13 // Services
16 
17 #include "boost/multi_array.hpp"
18 
19 #include <iostream>
20 using namespace std;
21 
22 namespace {
23  constexpr float micronsToCm = 1.0e-4;
24 } // namespace
25 
26 //-----------------------------------------------------------------------------
28 //-----------------------------------------------------------------------------
30  const MagneticField* mag,
31  const TrackerGeometry& geom,
32  const TrackerTopology& ttopo,
33  const SiPixelLorentzAngle* lorentzAngle,
34  const SiPixelGenErrorDBObject* genErrorDBObject,
35  const SiPixelLorentzAngle* lorentzAngleWidth = nullptr)
36  : PixelCPEGeneric(conf, mag, geom, ttopo, lorentzAngle, genErrorDBObject, lorentzAngleWidth) {
37  if (theVerboseLevel > 0)
38  LogDebug("PixelCPEGenericBricked") << "constructing a generic algorithm for ideal pixel detector.\n"
39  << "CPEGenericForBricked::VerboseLevel =" << theVerboseLevel;
40 #ifdef EDM_ML_DEBUG
41  cout << "From PixelCPEGenericForBricked::PixelCPEGenericForBricked(...)" << endl;
42  cout << "(int)useErrorsFromTemplates_ = " << (int)useErrorsFromTemplates_ << endl;
43  cout << "truncatePixelCharge_ = " << (int)truncatePixelCharge_ << endl;
44  cout << "IrradiationBiasCorrection_ = " << (int)IrradiationBiasCorrection_ << endl;
45  cout << "(int)DoCosmics_ = " << (int)DoCosmics_ << endl;
46  cout << "(int)LoadTemplatesFromDB_ = " << (int)LoadTemplatesFromDB_ << endl;
47 #endif
48 }
49 
50 //-----------------------------------------------------------------------------
54 //-----------------------------------------------------------------------------
56  ClusterParam& theClusterParamBase) const {
57  ClusterParamGeneric& theClusterParam = static_cast<ClusterParamGeneric&>(theClusterParamBase);
58 
59  float chargeWidthX = (theDetParam.lorentzShiftInCmX * theDetParam.widthLAFractionX);
60  float chargeWidthY = (theDetParam.lorentzShiftInCmY * theDetParam.widthLAFractionY);
61  float shiftX = 0.5f * theDetParam.lorentzShiftInCmX;
62  float shiftY = 0.5f * theDetParam.lorentzShiftInCmY;
63 
64  //cout<<" main la width "<<chargeWidthX<<" "<<chargeWidthY<<endl;
65 
67  float qclus = theClusterParam.theCluster->charge();
68  float locBz = theDetParam.bz;
69  float locBx = theDetParam.bx;
70  //cout << "PixelCPEGenericForBricked::localPosition(...) : locBz = " << locBz << endl;
71 
72  theClusterParam.pixmx = -999; // max pixel charge for truncation of 2-D cluster
73  theClusterParam.sigmay = -999.9; // CPE Generic y-error for multi-pixel cluster
74  theClusterParam.deltay = -999.9; // CPE Generic y-bias for multi-pixel cluster
75  theClusterParam.sigmax = -999.9; // CPE Generic x-error for multi-pixel cluster
76  theClusterParam.deltax = -999.9; // CPE Generic x-bias for multi-pixel cluster
77  theClusterParam.sy1 = -999.9; // CPE Generic y-error for single single-pixel
78  theClusterParam.dy1 = -999.9; // CPE Generic y-bias for single single-pixel cluster
79  theClusterParam.sy2 = -999.9; // CPE Generic y-error for single double-pixel cluster
80  theClusterParam.dy2 = -999.9; // CPE Generic y-bias for single double-pixel cluster
81  theClusterParam.sx1 = -999.9; // CPE Generic x-error for single single-pixel cluster
82  theClusterParam.dx1 = -999.9; // CPE Generic x-bias for single single-pixel cluster
83  theClusterParam.sx2 = -999.9; // CPE Generic x-error for single double-pixel cluster
84  theClusterParam.dx2 = -999.9; // CPE Generic x-bias for single double-pixel cluster
85 
87  int gtemplID_ = theDetParam.detTemplateId;
88 
89  //int gtemplID0 = genErrorDBObject_->getGenErrorID(theDetParam.theDet->geographicalId().rawId());
90  //if(gtemplID0!=gtemplID_) cout<<" different id "<< gtemplID_<<" "<<gtemplID0<<endl;
91 
92  theClusterParam.qBin_ = gtempl.qbin(gtemplID_,
93  theClusterParam.cotalpha,
94  theClusterParam.cotbeta,
95  locBz,
96  locBx,
97  qclus,
99  theClusterParam.pixmx,
100  theClusterParam.sigmay,
101  theClusterParam.deltay,
102  theClusterParam.sigmax,
103  theClusterParam.deltax,
104  theClusterParam.sy1,
105  theClusterParam.dy1,
106  theClusterParam.sy2,
107  theClusterParam.dy2,
108  theClusterParam.sx1,
109  theClusterParam.dx1,
110  theClusterParam.sx2,
111  theClusterParam.dx2);
112 
113  // now use the charge widths stored in the new generic template headers (change to the
114  // incorrect sign convention of the base class)
115  bool useLAWidthFromGenError = false;
116  if (useLAWidthFromGenError) {
117  chargeWidthX = (-micronsToCm * gtempl.lorxwidth());
118  chargeWidthY = (-micronsToCm * gtempl.lorywidth());
119  edm::LogInfo("PixelCPE bricked localPosition():")
120  << "redefine la width (gen-error)" << chargeWidthX << " " << chargeWidthY;
121  }
122  edm::LogInfo("PixelCPEGeneric bricked localPosition():") << "GenError:" << gtemplID_;
123 
124  // These numbers come in microns from the qbin(...) call. Transform them to cm.
125  theClusterParam.deltax = theClusterParam.deltax * micronsToCm;
126  theClusterParam.dx1 = theClusterParam.dx1 * micronsToCm;
127  theClusterParam.dx2 = theClusterParam.dx2 * micronsToCm;
128 
129  theClusterParam.deltay = theClusterParam.deltay * micronsToCm;
130  theClusterParam.dy1 = theClusterParam.dy1 * micronsToCm;
131  theClusterParam.dy2 = theClusterParam.dy2 * micronsToCm;
132 
133  theClusterParam.sigmax = theClusterParam.sigmax * micronsToCm;
134  theClusterParam.sx1 = theClusterParam.sx1 * micronsToCm;
135  theClusterParam.sx2 = theClusterParam.sx2 * micronsToCm;
136 
137  theClusterParam.sigmay = theClusterParam.sigmay * micronsToCm;
138  theClusterParam.sy1 = theClusterParam.sy1 * micronsToCm;
139  theClusterParam.sy2 = theClusterParam.sy2 * micronsToCm;
140 
141  } // if ( useErrorsFromTemplates_ )
142  else {
143  theClusterParam.qBin_ = 0;
144  }
145 
146  int q_f_X;
147  int q_l_X;
148  int q_f_Y;
149  int q_l_Y;
150  int q_f_b; // Q first bricked: charge of the dented row at the bootom of a cluster
151  int q_l_b; // Same but at the top of the cluster
152  int lowest_is_bricked = 1;
153  int highest_is_bricked = 0;
154 
155  if (theDetParam.theTopol->isBricked()) {
156  collect_edge_charges_bricked(theClusterParam,
157  q_f_X,
158  q_l_X,
159  q_f_Y,
160  q_l_Y,
161  q_f_b,
162  q_l_b,
163  lowest_is_bricked,
164  highest_is_bricked,
166  } else {
167  collect_edge_charges(theClusterParam, q_f_X, q_l_X, q_f_Y, q_l_Y, useErrorsFromTemplates_ && truncatePixelCharge_);
168  }
169 
170  //--- Find the inner widths along X and Y in one shot. We
171  //--- compute the upper right corner of the inner pixels
172  //--- (== lower left corner of upper right pixel) and
173  //--- the lower left corner of the inner pixels
174  //--- (== upper right corner of lower left pixel), and then
175  //--- subtract these two points in the formula.
176 
177  //--- Upper Right corner of Lower Left pixel -- in measurement frame
178  MeasurementPoint meas_URcorn_LLpix(theClusterParam.theCluster->minPixelRow() + 1.0,
179  theClusterParam.theCluster->minPixelCol() + 1.0);
180  //--- Lower Left corner of Upper Right pixel -- in measurement frame
181  MeasurementPoint meas_LLcorn_URpix(theClusterParam.theCluster->maxPixelRow(),
182  theClusterParam.theCluster->maxPixelCol());
183 
184  if (theDetParam.theTopol->isBricked()) {
185  if (lowest_is_bricked)
186  meas_URcorn_LLpix = MeasurementPoint(theClusterParam.theCluster->minPixelRow() + 1.0,
187  theClusterParam.theCluster->minPixelCol() + 1.5);
188  if (highest_is_bricked)
189  meas_LLcorn_URpix =
190  MeasurementPoint(theClusterParam.theCluster->maxPixelRow(), theClusterParam.theCluster->maxPixelCol() + 0.5);
191  }
192 
193  //--- These two now converted into the local
194  LocalPoint local_URcorn_LLpix;
195  LocalPoint local_LLcorn_URpix;
196 
197  // PixelCPEGenericForBricked can be used with or without track angles
198  // If PixelCPEGenericForBricked is called with track angles, use them to correct for bows/kinks:
199  if (theClusterParam.with_track_angle) {
200  local_URcorn_LLpix = theDetParam.theTopol->localPosition(meas_URcorn_LLpix, theClusterParam.loc_trk_pred);
201  local_LLcorn_URpix = theDetParam.theTopol->localPosition(meas_LLcorn_URpix, theClusterParam.loc_trk_pred);
202  } else {
203  local_URcorn_LLpix = theDetParam.theTopol->localPosition(meas_URcorn_LLpix);
204  local_LLcorn_URpix = theDetParam.theTopol->localPosition(meas_LLcorn_URpix);
205  }
206 
207 #ifdef EDM_ML_DEBUG
208  if (theVerboseLevel > 0) {
209  cout << "\n\t >>> theClusterParam.theCluster->x = " << theClusterParam.theCluster->x()
210  << "\n\t >>> theClusterParam.theCluster->y = " << theClusterParam.theCluster->y()
211  << "\n\t >>> cluster: minRow = " << theClusterParam.theCluster->minPixelRow()
212  << " minCol = " << theClusterParam.theCluster->minPixelCol()
213  << "\n\t >>> cluster: maxRow = " << theClusterParam.theCluster->maxPixelRow()
214  << " maxCol = " << theClusterParam.theCluster->maxPixelCol()
215  << "\n\t >>> meas: inner lower left = " << meas_URcorn_LLpix.x() << "," << meas_URcorn_LLpix.y()
216  << "\n\t >>> meas: inner upper right = " << meas_LLcorn_URpix.x() << "," << meas_LLcorn_URpix.y() << endl;
217  }
218 #endif
219 
220  //--- &&& Note that the cuts below should not be hardcoded (like in Orca and
221  //--- &&& CPEFromDetPosition/PixelCPEInitial), but rather be
222  //--- &&& externally settable (but tracked) parameters.
223 
224  //--- Position, including the half lorentz shift
225 
226 #ifdef EDM_ML_DEBUG
227  if (theVerboseLevel > 0)
228  cout << "\t >>> Generic:: processing X" << endl;
229 #endif
230 
232  theClusterParam.theCluster->sizeX(),
233  q_f_X,
234  q_l_X,
235  local_URcorn_LLpix.x(),
236  local_LLcorn_URpix.x(),
237  chargeWidthX, // lorentz shift in cm
238  theDetParam.theThickness,
239  theClusterParam.cotalpha,
240  theDetParam.thePitchX,
241  theDetParam.theRecTopol->isItBigPixelInX(theClusterParam.theCluster->minPixelRow()),
242  theDetParam.theRecTopol->isItBigPixelInX(theClusterParam.theCluster->maxPixelRow()),
245  the_size_cutX); // cut for eff charge width &&&
246 
247  // apply the lorentz offset correction
248  xPos = xPos + shiftX;
249 
250 #ifdef EDM_ML_DEBUG
251  if (theVerboseLevel > 0)
252  cout << "\t >>> Generic:: processing Y" << endl;
253 #endif
254 
255  // staggering pf the pixel cells allowed along local-Y direction only
256  float yPos;
257  if (theDetParam.theTopol->isBricked()) {
259  theClusterParam.theCluster->sizeY(),
260  q_f_Y,
261  q_l_Y,
262  q_f_b,
263  q_l_b,
264  local_URcorn_LLpix.y(),
265  local_LLcorn_URpix.y(),
266  chargeWidthY, // lorentz shift in cm
267  theDetParam.theThickness,
268  theClusterParam.cotbeta,
269  theDetParam.thePitchY,
270  theDetParam.theRecTopol->isItBigPixelInY(theClusterParam.theCluster->minPixelCol()),
271  theDetParam.theRecTopol->isItBigPixelInY(theClusterParam.theCluster->maxPixelCol()),
274  the_size_cutY); // cut for eff charge width &&&
275  } else {
277  theClusterParam.theCluster->sizeY(),
278  q_f_Y,
279  q_l_Y,
280  local_URcorn_LLpix.y(),
281  local_LLcorn_URpix.y(),
282  chargeWidthY, // lorentz shift in cm
283  theDetParam.theThickness,
284  theClusterParam.cotbeta,
285  theDetParam.thePitchY,
286  theDetParam.theRecTopol->isItBigPixelInY(theClusterParam.theCluster->minPixelCol()),
287  theDetParam.theRecTopol->isItBigPixelInY(theClusterParam.theCluster->maxPixelCol()),
290  the_size_cutY); // cut for eff charge width &&&
291  }
292 
293  // apply the lorentz offset correction
294  yPos = yPos + shiftY;
295 
296  // Apply irradiation corrections
298  if (theClusterParam.theCluster->sizeX() == 1) { // size=1
299  // ggiurgiu@jhu.edu, 02/03/09 : for size = 1, the Lorentz shift is already accounted by the irradiation correction
300  //float tmp1 = (0.5 * theDetParam.lorentzShiftInCmX);
301  //cout << "Apply correction correction_dx1 = " << theClusterParam.dx1 << " to xPos = " << xPos;
302  xPos = xPos - (0.5f * theDetParam.lorentzShiftInCmX);
303  // Find if pixel is double (big).
304  bool bigInX = theDetParam.theRecTopol->isItBigPixelInX(theClusterParam.theCluster->maxPixelRow());
305  if (!bigInX)
306  xPos -= theClusterParam.dx1;
307  else
308  xPos -= theClusterParam.dx2;
309  //cout<<" to "<<xPos<<" "<<(tmp1+theClusterParam.dx1)<<endl;
310  } else { // size>1
311  //cout << "Apply correction correction_deltax = " << theClusterParam.deltax << " to xPos = " << xPos;
312  xPos -= theClusterParam.deltax;
313  //cout<<" to "<<xPos<<endl;
314  }
315 
316  if (theClusterParam.theCluster->sizeY() == 1) {
317  // ggiurgiu@jhu.edu, 02/03/09 : for size = 1, the Lorentz shift is already accounted by the irradiation correction
318  yPos = yPos - (0.5f * theDetParam.lorentzShiftInCmY);
319 
320  // Find if pixel is double (big).
321  bool bigInY = theDetParam.theRecTopol->isItBigPixelInY(theClusterParam.theCluster->maxPixelCol());
322  if (!bigInY)
323  yPos -= theClusterParam.dy1;
324  else
325  yPos -= theClusterParam.dy2;
326 
327  } else {
328  //cout << "Apply correction correction_deltay = " << theClusterParam.deltay << " to yPos = " << yPos << endl;
329  yPos -= theClusterParam.deltay;
330  }
331 
332  } // if ( IrradiationBiasCorrection_ )
333 
334  //cout<<" in PixelCPEGenericForBricked:localPosition - pos = "<<xPos<<" "<<yPos<<endl; //dk
335 
336  //--- Now put the two together
337  LocalPoint pos_in_local(xPos, yPos);
338  return pos_in_local;
339 }
340 
342  int& q_f_X,
343  int& q_l_X,
344  int& q_f_Y,
345  int& q_l_Y,
346  int& q_f_b,
347  int& q_l_b, //Bricked correction
348  int& lowest_is_bricked, //Bricked correction
349  int& highest_is_bricked, //Bricked correction
350  bool truncate) {
351  ClusterParamGeneric& theClusterParam = static_cast<ClusterParamGeneric&>(theClusterParamBase);
352 
353  // Initialize return variables.
354  q_f_X = q_l_X = 0.0;
355  q_f_Y = q_l_Y = 0.0;
356  q_f_b = q_l_b = 0.0;
357 
358  // Obtain boundaries in index units
359  int xmin = theClusterParam.theCluster->minPixelRow();
360  int xmax = theClusterParam.theCluster->maxPixelRow();
361  int ymin = theClusterParam.theCluster->minPixelCol();
362  int ymax = theClusterParam.theCluster->maxPixelCol();
363 
364  //bool lowest_is_bricked = 1; //Tells you if the lowest pixel of the cluster is on a bricked row or not.
365  //bool highest_is_bricked = 0;
366 
367  //Sums up the charge of the non-bricked pixels at the top of the clusters in the event that the highest pixel of the cluster is on a bricked row.
368  int q_t_b = 0;
369  int q_t_nb = 0;
370  int q_b_b = 0;
371  int q_b_nb = 0;
372 
373  //This is included in the main loop.
374  // Iterate over the pixels to find out if a bricked row is lowest/highest.
375  /* int isize = theClusterParam.theCluster->size();
376  for (int i = 0; i != isize; ++i) {
377  auto const& pixel = theClusterParam.theCluster->pixel(i);
378 
379  // Y projection
380  if (pixel.y == ymin && !(pixel.x%2) ) lowest_is_bricked = 0;
381  if (pixel.y == ymax && (pixel.x%2) ) highest_is_bricked = 1;
382  } */
383 
384  // Iterate over the pixels.
385  int isize = theClusterParam.theCluster->size();
386  for (int i = 0; i != isize; ++i) {
387  auto const& pixel = theClusterParam.theCluster->pixel(i);
388  // ggiurgiu@fnal.gov: add pixel charge truncation
389  int pix_adc = pixel.adc;
390  if (truncate)
391  pix_adc = std::min(pix_adc, theClusterParam.pixmx);
392  //
393  // X projection
394  if (pixel.x == xmin)
395  q_f_X += pix_adc;
396  if (pixel.x == xmax)
397  q_l_X += pix_adc;
398  //
399  // Y projection
400  if (pixel.y == ymin) {
401  q_f_Y += pix_adc;
402  if (pixel.x % 2)
403  q_b_nb += pix_adc;
404  else
405  lowest_is_bricked = 0;
406  }
407  if (pixel.y == ymin + 1 && !(pixel.x % 2))
408  q_b_b += pix_adc;
409  if (pixel.y == ymax) {
410  q_l_Y += pix_adc;
411  if (!(pixel.x % 2))
412  q_t_b += pix_adc;
413  else
414  highest_is_bricked = 1;
415  }
416  if (pixel.y == ymax - 1 && (pixel.x % 2))
417  q_t_nb += pix_adc;
418  }
419 
420  edm::LogInfo("PixelCPE: collect_edge_charges_bricked: l/h") << lowest_is_bricked << "it" << highest_is_bricked;
421 
422  if (lowest_is_bricked)
423  q_f_b = q_b_b;
424  else
425  q_f_b = q_b_nb;
426 
427  if (highest_is_bricked)
428  q_l_b = -q_t_b;
429  else
430  q_l_b = -q_t_nb;
431 
432  //Need to add the edge pixels that were missed:
433  for (int i = 0; i != isize; ++i) {
434  auto const& pixel = theClusterParam.theCluster->pixel(i);
435  int pix_adc = pixel.adc;
436  if (truncate)
437  pix_adc = std::min(pix_adc, theClusterParam.pixmx);
438 
439  if (lowest_is_bricked && pixel.y == ymin + 1 && !(pixel.x % 2))
440  q_f_Y += pix_adc;
441 
442  if (!highest_is_bricked && pixel.y == ymax - 1 && (pixel.x % 2))
443  q_l_Y += pix_adc;
444 
445  edm::LogInfo("PixelCPE: collect_edge_charges_bricked: Q") << q_l_b << q_f_b << q_f_X << q_l_X << q_f_Y << q_l_Y;
446 
447  return;
448  }
449 }
Pixel pixel(int i) const
static void collect_edge_charges_bricked(ClusterParam &theClusterParam, int &q_f_X, int &q_l_X, int &q_f_Y, int &q_l_Y, int &Q_f_b, int &Q_l_b, int &lowest_is_bricked, int &highest_is_bricked, bool truncate)
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
float the_eff_charge_cut_highY
const SiPixelCluster * theCluster
Definition: PixelCPEBase.h:75
int maxPixelRow() const
int sizeY() const
static void collect_edge_charges(ClusterParam &theClusterParam, int &q_f_X, int &q_l_X, int &q_f_Y, int &q_l_Y, bool truncate)
std::vector< SiPixelGenErrorStore > thePixelGenError_
PixelCPEGenericForBricked(edm::ParameterSet const &conf, const MagneticField *, const TrackerGeometry &, const TrackerTopology &, const SiPixelLorentzAngle *, const SiPixelGenErrorDBObject *, const SiPixelLorentzAngle *)
The constructor.
T x() const
Definition: PV2DBase.h:43
bool IrradiationBiasCorrection_
const RectangularPixelTopology * theRecTopol
Definition: PixelCPEBase.h:50
int minPixelRow() const
float generic_position_formula_y_bricked(int size, int q_f, int q_l, int q_f_b, int q_l_b, float upper_edge_first_pix, float lower_edge_last_pix, float lorentz_shift, float theThickness, float cot_angle, float pitch, bool first_is_big, bool last_is_big, float eff_charge_cut_low, float eff_charge_cut_high, float size_cut)
Definition: SiPixelUtils.cc:82
T y() const
Definition: PV2DBase.h:44
int charge() const
int qbin(int id, float cotalpha, float cotbeta, float locBz, float locBx, float qclus, bool irradiationCorrections, int &pixmx, float &sigmay, float &deltay, float &sigmax, float &deltax, float &sy1, float &dy1, float &sy2, float &dy2, float &sx1, float &dx1, float &sx2, float &dx2)
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
const PixelTopology * theTopol
Definition: PixelCPEBase.h:49
bool LoadTemplatesFromDB_
Definition: PixelCPEBase.h:242
int minPixelCol() const
bool isItBigPixelInX(const int ixbin) const override
virtual bool isBricked() const =0
float the_eff_charge_cut_lowX
int maxPixelCol() const
int sizeX() const
float lorxwidth()
signed lorentz x-width (microns)
Log< level::Info, false > LogInfo
Topology::LocalTrackPred loc_trk_pred
Definition: PixelCPEBase.h:89
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
LocalPoint localPosition(DetParam const &theDetParam, ClusterParam &theClusterParam) const override
int size() const
float the_eff_charge_cut_lowY
float y() const
float lorywidth()
signed lorentz y-width (microns)
float x() const
bool isItBigPixelInY(const int iybin) const override
float generic_position_formula(int size, int q_f, int q_l, float upper_edge_first_pix, float lower_edge_last_pix, float lorentz_shift, float theThickness, float cot_angle, float pitch, bool first_is_big, bool last_is_big, float eff_charge_cut_low, float eff_charge_cut_high, float size_cut)
Definition: SiPixelUtils.cc:16
#define LogDebug(id)
float the_eff_charge_cut_highX