CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PixelCPEGeneric.cc
Go to the documentation of this file.
2 
5 
6 // this is needed to get errors from templates
10 
11 
12 // Services
15 
16 #include "boost/multi_array.hpp"
17 
18 #include <iostream>
19 using namespace std;
20 
21 namespace {
22  constexpr float HALF_PI = 1.57079632679489656;
23  constexpr float PI = 2*HALF_PI;
24 
25 }
26 
27 
28 //-----------------------------------------------------------------------------
30 //-----------------------------------------------------------------------------
32  const MagneticField * mag, const SiPixelLorentzAngle * lorentzAngle, const SiPixelCPEGenericErrorParm * genErrorParm, const SiPixelTemplateDBObject * templateDBobject)
33  : PixelCPEBase(conf, mag, lorentzAngle, genErrorParm, templateDBobject)
34 {
35 
36  if (theVerboseLevel > 0)
37  LogDebug("PixelCPEGeneric")
38  << " constructing a generic algorithm for ideal pixel detector.\n"
39  << " CPEGeneric:: VerboseLevel = " << theVerboseLevel;
40 
41  // Externally settable cuts
42  the_eff_charge_cut_lowX = conf.getParameter<double>("eff_charge_cut_lowX");
43  the_eff_charge_cut_lowY = conf.getParameter<double>("eff_charge_cut_lowY");
44  the_eff_charge_cut_highX = conf.getParameter<double>("eff_charge_cut_highX");
45  the_eff_charge_cut_highY = conf.getParameter<double>("eff_charge_cut_highY");
46  the_size_cutX = conf.getParameter<double>("size_cutX");
47  the_size_cutY = conf.getParameter<double>("size_cutY");
48 
49  EdgeClusterErrorX_ = conf.getParameter<double>("EdgeClusterErrorX");
50  EdgeClusterErrorY_ = conf.getParameter<double>("EdgeClusterErrorY");
51 
52  // Externally settable flags to inflate errors
53  inflate_errors = conf.getParameter<bool>("inflate_errors");
54  inflate_all_errors_no_trk_angle = conf.getParameter<bool>("inflate_all_errors_no_trk_angle");
55 
56  UseErrorsFromTemplates_ = conf.getParameter<bool>("UseErrorsFromTemplates");
57  TruncatePixelCharge_ = conf.getParameter<bool>("TruncatePixelCharge");
58  IrradiationBiasCorrection_ = conf.getParameter<bool>("IrradiationBiasCorrection");
59  DoCosmics_ = conf.getParameter<bool>("DoCosmics");
60  LoadTemplatesFromDB_ = conf.getParameter<bool>("LoadTemplatesFromDB");
61 
62  if ( !UseErrorsFromTemplates_ && ( TruncatePixelCharge_ ||
63  IrradiationBiasCorrection_ ||
64  DoCosmics_ ||
65  LoadTemplatesFromDB_ ) )
66  {
67  throw cms::Exception("PixelCPEGeneric::PixelCPEGeneric: ")
68  << "\nERROR: UseErrorsFromTemplates_ is set to False in PixelCPEGeneric_cfi.py. "
69  << " In this case it does not make sense to set any of the following to True: "
70  << " TruncatePixelCharge_, IrradiationBiasCorrection_, DoCosmics_, LoadTemplatesFromDB_ !!!"
71  << "\n\n";
72  }
73 
74  if ( UseErrorsFromTemplates_ )
75  {
76  templID_ = -999;
77  if ( LoadTemplatesFromDB_ )
78  {
79  // Initialize template store to the selected ID [Morris, 6/25/08]
81  throw cms::Exception("InvalidCalibrationLoaded")
82  << "ERROR: Templates not filled correctly. Check the sqlite file. Using SiPixelTemplateDBObject version "
83  << ( *templateDBobject_ ).version() << ". Template ID is " << templID_;
84  }
85  else
86  {
87  if ( !templ_.pushfile( templID_ ) )
88  throw cms::Exception("InvalidCalibrationLoaded")
89  << "ERROR: Templates not loaded correctly from text file. Reconstruction will fail." << " Template ID is " << templID_;
90  }
91 
92  } // if ( UseErrorsFromTemplates_ )
93 
94  //cout << endl;
95  //cout << "From PixelCPEGeneric::PixelCPEGeneric(...)" << endl;
96  //cout << "(int)UseErrorsFromTemplates_ = " << (int)UseErrorsFromTemplates_ << endl;
97  //cout << "TruncatePixelCharge_ = " << (int)TruncatePixelCharge_ << endl;
98  //cout << "IrradiationBiasCorrection_ = " << (int)IrradiationBiasCorrection_ << endl;
99  //cout << "(int)DoCosmics_ = " << (int)DoCosmics_ << endl;
100  //cout << "(int)LoadTemplatesFromDB_ = " << (int)LoadTemplatesFromDB_ << endl;
101  //cout << endl;
102 
103  //yes, these should be config parameters!
104  //default case...
105  xerr_barrel_l1_= {0.00115, 0.00120, 0.00088};
106  xerr_barrel_l1_def_=0.01030;
107  yerr_barrel_l1_= {0.00375,0.00230,0.00250,0.00250,0.00230,0.00230,0.00210,0.00210,0.00240};
108  yerr_barrel_l1_def_=0.00210;
109  xerr_barrel_ln_= {0.00115, 0.00120, 0.00088};
110  xerr_barrel_ln_def_=0.01030;
111  yerr_barrel_ln_= {0.00375,0.00230,0.00250,0.00250,0.00230,0.00230,0.00210,0.00210,0.00240};
112  yerr_barrel_ln_def_=0.00210;
113  xerr_endcap_= {0.0020, 0.0020};
114  xerr_endcap_def_=0.0020;
115  yerr_endcap_= {0.00210};
116  yerr_endcap_def_=0.00075;
117 
118  bool isUpgrade=false;
119  if ( conf.exists("Upgrade") && conf.getParameter<bool>("Upgrade")) {
120  isUpgrade=true;
121  xerr_barrel_ln_= {0.00114,0.00104,0.00214};
122  xerr_barrel_ln_def_=0.00425;
123  yerr_barrel_ln_= {0.00299,0.00203,0.0023,0.00237,0.00233,0.00243,0.00232,0.00259,0.00176};
124  yerr_barrel_ln_def_=0.00245;
125  xerr_endcap_= {0.00151,0.000813,0.00221};
126  xerr_endcap_def_=0.00218;
127  yerr_endcap_= {0.00261,0.00107,0.00264};
128  yerr_endcap_def_=0.00357;
129 
130  if ( conf.exists("SmallPitch") && conf.getParameter<bool>("SmallPitch")) {
131  xerr_barrel_l1_= {0.00104, 0.000691, 0.00122};
132  xerr_barrel_l1_def_=0.00321;
133  yerr_barrel_l1_= {0.00199,0.00136,0.0015,0.00153,0.00152,0.00171,0.00154,0.00157,0.00154};
134  yerr_barrel_l1_def_=0.00164;
135  }
136  else{
137  xerr_barrel_l1_= {0.00114,0.00104,0.00214};
138  xerr_barrel_l1_def_=0.00425;
139  yerr_barrel_l1_= {0.00299,0.00203,0.0023,0.00237,0.00233,0.00243,0.00232,0.00259,0.00176};
140  yerr_barrel_l1_def_=0.00245;
141  }
142  }
143 
144  isUpgrade_=isUpgrade;
145 
146 }
147 
148 
149 
150 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
157 {
160  {
162  /*bool fpix; //!< barrel(false) or forward(true)
163  if ( thePart == GeomDetEnumerators::PixelBarrel )
164  fpix = false; // no, it's not forward -- it's barrel
165  else
166  fpix = true; // yes, it's forward
167  */
168  float qclus = cluster.charge();
169 
170 
171  float locBz = (*theParam).bz;
172  //cout << "PixelCPEGeneric::localPosition(...) : locBz = " << locBz << endl;
173 
174  pixmx = -999.9; // max pixel charge for truncation of 2-D cluster
175  sigmay = -999.9; // CPE Generic y-error for multi-pixel cluster
176  deltay = -999.9; // CPE Generic y-bias for multi-pixel cluster
177  sigmax = -999.9; // CPE Generic x-error for multi-pixel cluster
178  deltax = -999.9; // CPE Generic x-bias for multi-pixel cluster
179  sy1 = -999.9; // CPE Generic y-error for single single-pixel
180  dy1 = -999.9; // CPE Generic y-bias for single single-pixel cluster
181  sy2 = -999.9; // CPE Generic y-error for single double-pixel cluster
182  dy2 = -999.9; // CPE Generic y-bias for single double-pixel cluster
183  sx1 = -999.9; // CPE Generic x-error for single single-pixel cluster
184  dx1 = -999.9; // CPE Generic x-bias for single single-pixel cluster
185  sx2 = -999.9; // CPE Generic x-error for single double-pixel cluster
186  dx2 = -999.9; // CPE Generic x-bias for single double-pixel cluster
187 
188  qBin_ = templ_.qbin( templID_, cotalpha_, cotbeta_, locBz, qclus, // inputs
189  pixmx, // returned by reference
190  sigmay, deltay, sigmax, deltax, // returned by reference
191  sy1, dy1, sy2, dy2, sx1, dx1, sx2, dx2 ); // returned by reference
192 
193  // These numbers come in microns from the qbin(...) call. Transform them to cm.
194  const float micronsToCm = 1.0e-4;
195 
197  dx1 = dx1 * micronsToCm;
198  dx2 = dx2 * micronsToCm;
199 
201  dy1 = dy1 * micronsToCm;
202  dy2 = dy2 * micronsToCm;
203 
205  sx1 = sx1 * micronsToCm;
206  sx2 = sx2 * micronsToCm;
207 
209  sy1 = sy1 * micronsToCm;
210  sy2 = sy2 * micronsToCm;
211 
212  } // if ( UseErrorsFromTemplates_ )
213 
214 
215  float Q_f_X = 0.0;
216  float Q_l_X = 0.0;
217  float Q_f_Y = 0.0;
218  float Q_l_Y = 0.0;
219  collect_edge_charges( cluster,
220  Q_f_X, Q_l_X,
221  Q_f_Y, Q_l_Y );
222 
223  //--- Find the inner widths along X and Y in one shot. We
224  //--- compute the upper right corner of the inner pixels
225  //--- (== lower left corner of upper right pixel) and
226  //--- the lower left corner of the inner pixels
227  //--- (== upper right corner of lower left pixel), and then
228  //--- subtract these two points in the formula.
229 
230  //--- Upper Right corner of Lower Left pixel -- in measurement frame
231  MeasurementPoint meas_URcorn_LLpix( cluster.minPixelRow()+1.0,
232  cluster.minPixelCol()+1.0 );
233 
234  //--- Lower Left corner of Upper Right pixel -- in measurement frame
235  MeasurementPoint meas_LLcorn_URpix( cluster.maxPixelRow(),
236  cluster.maxPixelCol() );
237 
238  //--- These two now converted into the local
239 
240  LocalPoint local_URcorn_LLpix;
241  LocalPoint local_LLcorn_URpix;
242 
243 
244  // PixelCPEGeneric can be used with or without track angles
245  // If PixelCPEGeneric is called with track angles, use them to correct for bows/kinks:
246  if ( with_track_angle )
247  {
248  local_URcorn_LLpix = theTopol->localPosition(meas_URcorn_LLpix, loc_trk_pred_);
249  local_LLcorn_URpix = theTopol->localPosition(meas_LLcorn_URpix, loc_trk_pred_);
250  }
251  else
252  {
253  local_URcorn_LLpix = theTopol->localPosition(meas_URcorn_LLpix);
254  local_LLcorn_URpix = theTopol->localPosition(meas_LLcorn_URpix);
255  }
256 
257  #ifdef EDM_ML_DEBUG
258  if (theVerboseLevel > 20) {
259  cout
260  << "\n\t >>> cluster.x = " << cluster.x()
261  << "\n\t >>> cluster.y = " << cluster.y()
262  << "\n\t >>> cluster: minRow = " << cluster.minPixelRow()
263  << " minCol = " << cluster.minPixelCol()
264  << "\n\t >>> cluster: maxRow = " << cluster.maxPixelRow()
265  << " maxCol = " << cluster.maxPixelCol()
266  << "\n\t >>> meas: inner lower left = " << meas_URcorn_LLpix.x()
267  << "," << meas_URcorn_LLpix.y()
268  << "\n\t >>> meas: inner upper right = " << meas_LLcorn_URpix.x()
269  << "," << meas_LLcorn_URpix.y()
270  << endl;
271  }
272 #endif
273 
274  //--- &&& Note that the cuts below should not be hardcoded (like in Orca and
275  //--- &&& CPEFromDetPosition/PixelCPEInitial), but rather be
276  //--- &&& externally settable (but tracked) parameters.
277 
278 
279  //--- Position, including the half lorentz shift
280 
281  #ifdef EDM_ML_DEBUG
282  if (theVerboseLevel > 20)
283  cout << "\t >>> Generic:: processing X" << endl;
284 #endif
285 
286  float xPos =
287  generic_position_formula( cluster.sizeX(),
288  Q_f_X, Q_l_X,
289  local_URcorn_LLpix.x(), local_LLcorn_URpix.x(),
290  0.5*lorentzShiftInCmX_, // 0.5 * lorentz shift in
291  cotalpha_,
292  thePitchX,
293  theRecTopol->isItBigPixelInX( cluster.minPixelRow() ),
294  theRecTopol->isItBigPixelInX( cluster.maxPixelRow() ),
297  the_size_cutX); // cut for eff charge width &&&
298 
299 
300  #ifdef EDM_ML_DEBUG
301  if (theVerboseLevel > 20)
302  cout << "\t >>> Generic:: processing Y" << endl;
303 #endif
304 
305  float yPos =
306  generic_position_formula( cluster.sizeY(),
307  Q_f_Y, Q_l_Y,
308  local_URcorn_LLpix.y(), local_LLcorn_URpix.y(),
309  0.5*lorentzShiftInCmY_, // 0.5 * lorentz shift in cm
310  cotbeta_,
311  thePitchY, // 0.5 * lorentz shift (may be 0)
312  theRecTopol->isItBigPixelInY( cluster.minPixelCol() ),
313  theRecTopol->isItBigPixelInY( cluster.maxPixelCol() ),
316  the_size_cutY); // cut for eff charge width &&&
317 
318  // Apply irradiation corrections.
320  {
321  if ( cluster.sizeX() == 1 )
322  {
323 
324  // Find if pixel is double (big).
325  bool bigInX = theRecTopol->isItBigPixelInX( cluster.maxPixelRow() );
326 
327  if ( !bigInX )
328  {
329  //cout << "Apply correction dx1 = " << dx1 << " to xPos = " << xPos << endl;
330  xPos -= dx1;
331  }
332  else
333  {
334  //cout << "Apply correction dx2 = " << dx2 << " to xPos = " << xPos << endl;
335  xPos -= dx2;
336  }
337  }
338  else
339  {
340  //cout << "Apply correction correction_deltax = " << deltax << " to xPos = " << xPos << endl;
341  xPos -= deltax;
342  }
343 
344  if ( cluster.sizeY() == 1 )
345  {
346 
347  // Find if pixel is double (big).
348  bool bigInY = theRecTopol->isItBigPixelInY( cluster.maxPixelCol() );
349 
350  if ( !bigInY )
351  {
352  //cout << "Apply correction dy1 = " << dy1 << " to yPos = " << yPos << endl;
353  yPos -= dy1;
354  }
355  else
356  {
357  //cout << "Apply correction dy2 = " << dy2 << " to yPos = " << yPos << endl;
358  yPos -= dy2;
359  }
360  }
361  else
362  {
363  //cout << "Apply correction deltay = " << deltay << " to yPos = " << yPos << endl;
364  yPos -= deltay;
365  }
366 
367  } // if ( IrradiationBiasCorrection_ )
368 
369  //--- Now put the two together
370  LocalPoint pos_in_local( xPos, yPos );
371  return pos_in_local;
372 }
373 
374 
375 
376 //-----------------------------------------------------------------------------
381 //-----------------------------------------------------------------------------
382 float
385  float Q_f,
386  float Q_l,
387  float upper_edge_first_pix,
388  float lower_edge_last_pix,
389  float half_lorentz_shift,
390  float cot_angle,
391  float pitch,
392  bool first_is_big,
393  bool last_is_big,
394  float eff_charge_cut_low,
395  float eff_charge_cut_high,
396  float size_cut
397  ) const
398 {
399  float geom_center = 0.5f * ( upper_edge_first_pix + lower_edge_last_pix );
400 
401  //--- The case of only one pixel in this projection is separate. Note that
402  //--- here first_pix == last_pix, so the average of the two is still the
403  //--- center of the pixel.
404  if ( size == 1 )
405  {
406  // ggiurgiu@jhu.edu, 02/03/09 : for size = 1, the Lorentz shift is already accounted by the irradiation correction
408  return geom_center;
409  else
410  return geom_center + half_lorentz_shift;
411  }
412 
413 
414  //--- Width of the clusters minus the edge (first and last) pixels.
415  //--- In the note, they are denoted x_F and x_L (and y_F and y_L)
416  float W_inner = lower_edge_last_pix - upper_edge_first_pix; // in cm
417 
418 
419  //--- Predicted charge width from geometry
420  float W_pred =
421  theThickness * cot_angle // geometric correction (in cm)
422  - 2.f * half_lorentz_shift; // (in cm) &&& check fpix!
423 
424 
425  //--- Total length of the two edge pixels (first+last)
426  float sum_of_edge = 2.0f;
427  if (first_is_big) sum_of_edge += 1.0f;
428  if (last_is_big) sum_of_edge += 1.0f;
429 
430 
431  //--- The `effective' charge width -- particle's path in first and last pixels only
432  float W_eff = std::abs( W_pred ) - W_inner;
433 
434 
435  //--- If the observed charge width is inconsistent with the expectations
436  //--- based on the track, do *not* use W_pred-W_innner. Instead, replace
437  //--- it with an *average* effective charge width, which is the average
438  //--- length of the edge pixels.
439  //
440  // bool usedEdgeAlgo = false;
441  if ( (size >= size_cut) || (
442  ( W_eff/pitch < eff_charge_cut_low ) |
443  ( W_eff/pitch > eff_charge_cut_high ) ) )
444  {
445  W_eff = pitch * 0.5f * sum_of_edge; // ave. length of edge pixels (first+last) (cm)
446  // usedEdgeAlgo = true;
448  }
449 
450 
451  //--- Finally, compute the position in this projection
452  float Qdiff = Q_l - Q_f;
453  float Qsum = Q_l + Q_f;
454 
455  //--- Temporary fix for clusters with both first and last pixel with charge = 0
456  if(Qsum==0) Qsum=1.0f;
457  float hit_pos = geom_center + 0.5f*(Qdiff/Qsum) * W_eff + half_lorentz_shift;
458 
459  #ifdef EDM_ML_DEBUG
460  //--- Debugging output
461  if (theVerboseLevel > 20) {
463  cout << "\t >>> We are in the Barrel." ;
464  } else {
465  cout << "\t >>> We are in the Forward." ;
466  }
467  cout
468  << "\n\t >>> cot(angle) = " << cot_angle << " pitch = " << pitch << " size = " << size
469  << "\n\t >>> upper_edge_first_pix = " << upper_edge_first_pix
470  << "\n\t >>> lower_edge_last_pix = " << lower_edge_last_pix
471  << "\n\t >>> geom_center = " << geom_center
472  << "\n\t >>> half_lorentz_shift = " << half_lorentz_shift
473  << "\n\t >>> W_inner = " << W_inner
474  << "\n\t >>> W_pred = " << W_pred
475  << "\n\t >>> W_eff(orig) = " << fabs( W_pred ) - W_inner
476  << "\n\t >>> W_eff(used) = " << W_eff
477  << "\n\t >>> sum_of_edge = " << sum_of_edge
478  << "\n\t >>> Qdiff = " << Qdiff << " Qsum = " << Qsum
479  << "\n\t >>> hit_pos = " << hit_pos
480  << "\n\t >>> RecHits: total = " << nRecHitsTotal_
481  << " used edge = " << nRecHitsUsedEdge_
482  << endl;
483  if (usedEdgeAlgo)
484  cout << "\n\t >>> Used Edge algorithm." ;
485  else
486  cout << "\n\t >>> Used angle information." ;
487  cout << endl;
488  }
489 #endif
490 
491  return hit_pos;
492 }
493 
494 
495 
496 
497 
498 //-----------------------------------------------------------------------------
502 //-----------------------------------------------------------------------------
503 void
506  float & Q_f_X,
507  float & Q_l_X,
508  float & Q_f_Y,
509  float & Q_l_Y
510  ) const
511 {
512  // Initialize return variables.
513  Q_f_X = Q_l_X = 0.0;
514  Q_f_Y = Q_l_Y = 0.0;
515 
516 
517  // Obtain boundaries in index units
518  int xmin = cluster.minPixelRow();
519  int xmax = cluster.maxPixelRow();
520  int ymin = cluster.minPixelCol();
521  int ymax = cluster.maxPixelCol();
522 
523 
524 
525  // Iterate over the pixels.
526  int isize = cluster.size();
527 
528  for (int i = 0; i != isize; ++i)
529  {
530  auto const & pixel = cluster.pixel(i);
531  // ggiurgiu@fnal.gov: add pixel charge truncation
532  float pix_adc = pixel.adc;
534  pix_adc = std::min(pix_adc, pixmx );
535 
536  //
537  // X projection
538  if ( pixel.x == xmin ) Q_f_X += pix_adc;
539  if ( pixel.x == xmax ) Q_l_X += pix_adc;
540  //
541  // Y projection
542  if ( pixel.y == ymin ) Q_f_Y += pix_adc;
543  if ( pixel.y == ymax ) Q_l_Y += pix_adc;
544  }
545 
546  return;
547 }
548 
549 
550 //============== INFLATED ERROR AND ERRORS FROM DB BELOW ================
551 
552 //-------------------------------------------------------------------------
553 // Hit error in the local frame
554 //-------------------------------------------------------------------------
555 LocalError
557 {
558 
559  // Default errors are the maximum error used for edge clusters.
560  /*
561  int row_offset = cluster.minPixelRow();
562  int col_offset = cluster.minPixelCol();
563  int n_bigInX = 0;
564  for (int irow = 0; irow < sizex; ++irow)
565  if ( theTopol->isItBigPixelInX( irow+row_offset ) )
566  ++n_bigInX;
567  int n_bigInY = 0;
568  for (int icol = 0; icol < sizey; ++icol)
569  if ( theTopol->isItBigPixelInY( icol+col_offset ) )
570  ++n_bigInX;
571  float xerr = (float)(sizex + n_bigInX) * thePitchX / sqrt(12.0);
572  float yerr = (float)(sizey + n_bigInY) * thePitchY / sqrt(12.0);
573  */
574 
575  // These are determined by looking at residuals for edge clusters
576  const float micronsToCm = 1.0e-4f;
577  float xerr = EdgeClusterErrorX_ * micronsToCm;
578  float yerr = EdgeClusterErrorY_ * micronsToCm;
579 
580  // Find if cluster is at the module edge.
581  int maxPixelCol = cluster.maxPixelCol();
582  int maxPixelRow = cluster.maxPixelRow();
583  int minPixelCol = cluster.minPixelCol();
584  int minPixelRow = cluster.minPixelRow();
585  unsigned int sizex = maxPixelRow - minPixelRow+1;
586  unsigned int sizey = maxPixelCol - minPixelCol+1;
587 
588  bool edgex = ( theRecTopol->isItEdgePixelInX( minPixelRow ) ) || ( theRecTopol->isItEdgePixelInX( maxPixelRow ) );
589  bool edgey = ( theRecTopol->isItEdgePixelInY( minPixelCol ) ) || ( theRecTopol->isItEdgePixelInY( maxPixelCol ) );
590 
591  // Find if cluster contains double (big) pixels.
592  bool bigInX = theRecTopol->containsBigPixelInX( minPixelRow, maxPixelRow );
593  bool bigInY = theRecTopol->containsBigPixelInY( minPixelCol, maxPixelCol );
595  {
596  //cout << "Track angles are not known and we are processing cosmics." << endl;
597  //cout << "Default angle estimation which assumes track from PV (0,0,0) does not work." << endl;
598  //cout << "Use an error parameterization which only depends on cluster size (by Vincenzo Chiochia)." << endl;
599 
601  {
602  DetId id = (theDet->geographicalId());
603  int layer=PXBDetId(id).layer();
604  if ( layer==1 ) {
605  if ( !edgex )
606  {
607  if ( sizex<=xerr_barrel_l1_.size() ) xerr=xerr_barrel_l1_[sizex-1];
608  else xerr=xerr_barrel_l1_def_;
609  }
610 
611  if ( !edgey )
612  {
613  if ( sizey<=yerr_barrel_l1_.size() ) yerr=yerr_barrel_l1_[sizey-1];
614  else yerr=yerr_barrel_l1_def_;
615  }
616  }
617  else{
618  if ( !edgex )
619  {
620  if ( sizex<=xerr_barrel_ln_.size() ) xerr=xerr_barrel_ln_[sizex-1];
621  else xerr=xerr_barrel_ln_def_;
622  }
623 
624  if ( !edgey )
625  {
626  if ( sizey<=yerr_barrel_ln_.size() ) yerr=yerr_barrel_ln_[sizey-1];
627  else yerr=yerr_barrel_ln_def_;
628  }
629  }
630  }
631  else // EndCap
632  {
633  if ( !edgex )
634  {
635  if ( sizex<=xerr_endcap_.size() ) xerr=xerr_endcap_[sizex-1];
636  else xerr=xerr_endcap_def_;
637  }
638 
639  if ( !edgey )
640  {
641  if ( sizey<=yerr_endcap_.size() ) yerr=yerr_endcap_[sizey-1];
642  else yerr=yerr_endcap_def_;
643  }
644  }
645 
646  } // if ( !with_track_angle )
647  else
648  {
649  //cout << "Track angles are known. We can use either errors from templates or the error parameterization from DB." << endl;
650 
652  {
653  if (qBin_ == 0 && inflate_errors )
654  {
655  int n_bigx = 0;
656  int n_bigy = 0;
657 
658  int row_offset = minPixelRow;
659  int col_offset = minPixelCol;
660 
661  for (int irow = 0; irow < 7; ++irow)
662  {
663  if ( theRecTopol->isItBigPixelInX( irow+row_offset ) )
664  ++n_bigx;
665  }
666 
667  for (int icol = 0; icol < 21; ++icol)
668  {
669  if ( theRecTopol->isItBigPixelInY( icol+col_offset ) )
670  ++n_bigy;
671  }
672 
673  xerr = (float)(sizex + n_bigx) * thePitchX / std::sqrt( 12.0f );
674  yerr = (float)(sizey + n_bigy) * thePitchY / std::sqrt( 12.0f );
675 
676  } // if ( qbin == 0 && inflate_errors )
677  else
678  {
679  // Default errors
680 
681  if ( !edgex )
682  {
683  if ( sizex == 1 )
684  {
685  if ( !bigInX )
686  xerr = sx1;
687  else
688  xerr = sx2;
689  }
690  else
691  xerr = sigmax;
692 
693  }
694 
695  if ( !edgey )
696  {
697  if ( sizey == 1 )
698  {
699  if ( !bigInY )
700  yerr = sy1;
701  else
702  yerr = sy2;
703  }
704  else
705  yerr = sigmay;
706 
707  }
708  } // if ( qbin == 0 && inflate_errors ) else
709 
710  } //if ( UseErrorsFromTemplates_ )
711  else
712  {
713  //cout << endl << "Use errors from DB:" << endl;
714 
715  if ( edgex && edgey )
716  {
717  //--- Both axes on the edge, no point in calling PixelErrorParameterization,
718  //--- just return the max errors on both.
719  }
720  else
721  {
722 
723  auto alpha = HALF_PI - std::atan(cotalpha_);
724  auto beta = HALF_PI - std::atan(cotbeta_);
725  if (zneg) { beta -=PI; alpha -=PI;}
726 
727  pair<float,float> errPair =
729  alpha, beta, bigInX, bigInY );
730  if ( !edgex )
731  xerr = errPair.first;
732  if ( !edgey )
733  yerr = errPair.second;
734  }
735 
736  LogDebug("PixelCPEGeneric") <<
737  " Sizex = " << cluster.sizeX() << " Sizey = " << cluster.sizeY() <<
738  " Edgex = " << edgex << " Edgey = " << edgey <<
739  " ErrX = " << xerr << " ErrY = " << yerr;
740 
741 
742  } //if ( UseErrorsFromTemplates_ ) else
743 
744  } // if ( !with_track_angle ) else
745 
746 #ifdef EDM_ML_DEBUG
747  if ( !(xerr > 0.0) )
748  throw cms::Exception("PixelCPEGeneric::localError")
749  << "\nERROR: Negative pixel error xerr = " << xerr << "\n\n";
750 
751  if ( !(yerr > 0.0) )
752  throw cms::Exception("PixelCPEGeneric::localError")
753  << "\nERROR: Negative pixel error yerr = " << yerr << "\n\n";
754 #endif
755 
756  auto xerr_sq = xerr*xerr;
757  auto yerr_sq = yerr*yerr;
758 
759  return LocalError( xerr_sq, 0, yerr_sq );
760 
761 }
762 
763 
764 
765 
766 
767 
#define LogDebug(id)
const double beta
T getParameter(std::string const &) const
std::vector< float > xerr_barrel_l1_
int i
Definition: DBlmapReader.cc:9
Topology::LocalTrackPred loc_trk_pred_
Definition: PixelCPEBase.h:253
float charge() const
float alpha
Definition: AMPTWrapper.h:95
int minPixelCol() const
bool with_track_angle
Definition: PixelCPEBase.h:203
const float micronsToCm
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
float the_eff_charge_cut_highY
#define PI
SiPixelCPEGenericDBErrorParametrization * genErrorsFromDB_
int qbin(int id, float cotalpha, float cotbeta, float locBz, float qclus, float &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)
std::vector< float > xerr_barrel_ln_
short getTemplateID(const uint32_t &detid) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
float theThickness
Definition: PixelCPEBase.h:176
T y() const
Definition: PV3DBase.h:63
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::pair< float, float > getError(const SiPixelCPEGenericErrorParm *parmErrors, GeomDetType::SubDetector pixelPart, int sizex, int sizey, float alpha, float beta, bool bigInX=false, bool bigInY=false)
GeomDetType::SubDetector thePart
Definition: PixelCPEBase.h:173
bool IrradiationBiasCorrection_
unsigned int layer() const
layer id
Definition: PXBDetId.h:35
std::vector< float > yerr_endcap_
void collect_edge_charges(const SiPixelCluster &cluster, float &Q_f_X, float &Q_l_X, float &Q_f_Y, float &Q_l_Y) const
int maxPixelRow() const
LocalPoint localPosition(const SiPixelCluster &cluster) const
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
#define unlikely(x)
Definition: Likely.h:21
double xPos
int minPixelRow() const
void computeLorentzShifts() const
float the_eff_charge_cut_lowX
LocalError localError(const SiPixelCluster &cl) const
T sqrt(T t)
Definition: SSEVec.h:48
float generic_position_formula(int size, float Q_f, float Q_l, float upper_edge_first_pix, float lower_edge_last_pix, float half_lorentz_shift, 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) const
PixelCPEGeneric(edm::ParameterSet const &conf, const MagneticField *, const SiPixelLorentzAngle *, const SiPixelCPEGenericErrorParm *, const SiPixelTemplateDBObject *)
The constructor.
bool inflate_all_errors_no_trk_angle
float lorentzShiftInCmY_
Definition: PixelCPEBase.h:233
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const SiPixelTemplateDBObject * templateDBobject_
Definition: PixelCPEBase.h:246
double yPos
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:72
double f[11][100]
std::vector< float > xerr_endcap_
SiPixelTemplate templ_
tuple conf
Definition: dbtoconf.py:185
Definition: DetId.h:18
bool pushfile(int filenum)
const RectangularPixelTopology * theRecTopol
Definition: PixelCPEBase.h:169
const PixelTopology * theTopol
Definition: PixelCPEBase.h:168
float the_eff_charge_cut_lowY
int maxPixelCol() const
std::vector< float > yerr_barrel_l1_
std::vector< float > yerr_barrel_ln_
int sizeY() const
Pixel cluster – collection of neighboring pixels above threshold.
float lorentzShiftInCmX_
Definition: PixelCPEBase.h:232
Pixel pixel(int i) const
float y() const
tuple cout
Definition: gather_cfg.py:121
const PixelGeomDetUnit * theDet
Definition: PixelCPEBase.h:164
int sizeX() const
T x() const
Definition: PV3DBase.h:62
tuple size
Write out results.
float x() const
#define constexpr
const SiPixelCPEGenericErrorParm * genErrorParm_
Definition: PixelCPEBase.h:244
int nRecHitsUsedEdge_
Definition: PixelCPEBase.h:200
float the_eff_charge_cut_highX
int size() const