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 //#define NEW_CPEERROR // must be constistent with base.cc, generic cc/h and genericProducer.cc
22 
23 namespace {
24  constexpr float micronsToCm = 1.0e-4;
25 #ifndef NEW_CPEERROR
26  //const bool useNewSimplerErrors = true; // must be the same as in base
27  const bool useNewSimplerErrors = false; // must be the same as in base
28 #endif
29  const bool MYDEBUG = false;
30 }
31 
32 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
35 #ifdef NEW_CPEERROR
37  const MagneticField * mag,
38  const TrackerGeometry& geom,
39  const SiPixelLorentzAngle * lorentzAngle,
40  const SiPixelGenErrorDBObject * genErrorDBObject,
41  const SiPixelLorentzAngle * lorentzAngleWidth=0)
42  : PixelCPEBase(conf, mag, geom, lorentzAngle, genErrorDBObject, 0,lorentzAngleWidth,0) {
43 #else
45  const MagneticField * mag,
46  const TrackerGeometry& geom,
47  const SiPixelLorentzAngle * lorentzAngle,
48  const SiPixelGenErrorDBObject * genErrorDBObject,
49  const SiPixelTemplateDBObject * templateDBobject,
50  const SiPixelLorentzAngle * lorentzAngleWidth=0)
51  : PixelCPEBase(conf, mag, geom, lorentzAngle, genErrorDBObject, templateDBobject,lorentzAngleWidth,0) {
52 #endif
53 
54  if (theVerboseLevel > 0)
55  LogDebug("PixelCPEGeneric")
56  << " constructing a generic algorithm for ideal pixel detector.\n"
57  << " CPEGeneric:: VerboseLevel = " << theVerboseLevel;
58 
59  // Externally settable cuts
60  the_eff_charge_cut_lowX = conf.getParameter<double>("eff_charge_cut_lowX");
61  the_eff_charge_cut_lowY = conf.getParameter<double>("eff_charge_cut_lowY");
62  the_eff_charge_cut_highX = conf.getParameter<double>("eff_charge_cut_highX");
63  the_eff_charge_cut_highY = conf.getParameter<double>("eff_charge_cut_highY");
64  the_size_cutX = conf.getParameter<double>("size_cutX");
65  the_size_cutY = conf.getParameter<double>("size_cutY");
66 
67  EdgeClusterErrorX_ = conf.getParameter<double>("EdgeClusterErrorX");
68  EdgeClusterErrorY_ = conf.getParameter<double>("EdgeClusterErrorY");
69 
70  // Externally settable flags to inflate errors
71  inflate_errors = conf.getParameter<bool>("inflate_errors");
72  inflate_all_errors_no_trk_angle = conf.getParameter<bool>("inflate_all_errors_no_trk_angle");
73 
74  UseErrorsFromTemplates_ = conf.getParameter<bool>("UseErrorsFromTemplates");
75  TruncatePixelCharge_ = conf.getParameter<bool>("TruncatePixelCharge");
76  IrradiationBiasCorrection_ = conf.getParameter<bool>("IrradiationBiasCorrection");
77  DoCosmics_ = conf.getParameter<bool>("DoCosmics");
78  //LoadTemplatesFromDB_ = conf.getParameter<bool>("LoadTemplatesFromDB");
79 
80  bool isUpgrade=false;
81  if ( conf.exists("Upgrade") && conf.getParameter<bool>("Upgrade")) {
82  isUpgrade=true;
83  xerr_barrel_ln_= {0.00114,0.00104,0.00214};
84  xerr_barrel_ln_def_=0.00425;
85  yerr_barrel_ln_= {0.00299,0.00203,0.0023,0.00237,0.00233,0.00243,0.00232,0.00259,0.00176};
86  yerr_barrel_ln_def_=0.00245;
87  xerr_endcap_= {0.00151,0.000813,0.00221};
88  xerr_endcap_def_=0.00218;
89  yerr_endcap_= {0.00261,0.00107,0.00264};
90  yerr_endcap_def_=0.00357;
91 
92  if ( conf.exists("SmallPitch") && conf.getParameter<bool>("SmallPitch")) {
93  xerr_barrel_l1_= {0.00104, 0.000691, 0.00122};
94  xerr_barrel_l1_def_=0.00321;
95  yerr_barrel_l1_= {0.00199,0.00136,0.0015,0.00153,0.00152,0.00171,0.00154,0.00157,0.00154};
96  yerr_barrel_l1_def_=0.00164;
97  }
98  else{
99  xerr_barrel_l1_= {0.00114,0.00104,0.00214};
100  xerr_barrel_l1_def_=0.00425;
101  yerr_barrel_l1_= {0.00299,0.00203,0.0023,0.00237,0.00233,0.00243,0.00232,0.00259,0.00176};
102  yerr_barrel_l1_def_=0.00245;
103  }
104  }
105  isUpgrade_=isUpgrade;
106 
107  // Select the position error source
108  // For upgrde and cosmics force the use simple errors
109  if( isUpgrade_ || (DoCosmics_) ) UseErrorsFromTemplates_ = false;
110 
111  if ( !UseErrorsFromTemplates_ && ( TruncatePixelCharge_ ||
112  IrradiationBiasCorrection_ ||
113  DoCosmics_ ||
115  throw cms::Exception("PixelCPEGeneric::PixelCPEGeneric: ")
116  << "\nERROR: UseErrorsFromTemplates_ is set to False in PixelCPEGeneric_cfi.py. "
117  << " In this case it does not make sense to set any of the following to True: "
118  << " TruncatePixelCharge_, IrradiationBiasCorrection_, DoCosmics_, LoadTemplatesFromDB_ !!!"
119  << "\n\n";
120  }
121 
122  // Use errors from templates
123  if ( UseErrorsFromTemplates_ ) {
124 
125 #ifdef NEW_CPEERROR
126 
127  if ( LoadTemplatesFromDB_ ) { // From DB
129  throw cms::Exception("InvalidCalibrationLoaded")
130  << "ERROR: Templates not filled correctly. Check the sqlite file. Using SiPixelTemplateDBObject version "
131  << ( *genErrorDBObject_ ).version();
132  } else { // From file
134  throw cms::Exception("InvalidCalibrationLoaded")
135  << "ERROR: Templates not loaded correctly from text file. Reconstruction will fail.";
136  } // if load from DB
137 
138 #else
139 
140  if(useNewSimplerErrors) { // use new errors from mini templates
141 
142  //cout<<" load errors "<<LoadTemplatesFromDB_<<endl;
143 
144  if ( LoadTemplatesFromDB_ ) { // From DB
146  throw cms::Exception("InvalidCalibrationLoaded")
147  << "ERROR: Templates not filled correctly. Check the sqlite file. Using SiPixelTemplateDBObject version "
148  << ( *genErrorDBObject_ ).version();
149  } else { // From file
151  throw cms::Exception("InvalidCalibrationLoaded")
152  << "ERROR: Templates not loaded correctly from text file. Reconstruction will fail.";
153  } // if load from DB
154 
155  } else { // use old errors from full templates
156 
157  if ( LoadTemplatesFromDB_ ) {
158  // Initialize template store to the selected ID [Morris, 6/25/08]
160  throw cms::Exception("InvalidCalibrationLoaded")
161  << "ERROR: Templates not filled correctly. Check the sqlite file. Using SiPixelTemplateDBObject version "
162  << ( *templateDBobject_ ).version();
163  } else {
165  throw cms::Exception("InvalidCalibrationLoaded")
166  << "ERROR: Templates not loaded correctly from text file. Reconstruction will fail.";
167  } // if load from DB
168 
169  } // if useNewSimpleErrors
170 #endif // NEW_CPEERROR
171 
172  } // if ( UseErrorsFromTemplates_ )
173 
174  //cout << endl;
175  //cout << "From PixelCPEGeneric::PixelCPEGeneric(...)" << endl;
176  //cout << "(int)UseErrorsFromTemplates_ = " << (int)UseErrorsFromTemplates_ << endl;
177  //cout << "TruncatePixelCharge_ = " << (int)TruncatePixelCharge_ << endl;
178  //cout << "IrradiationBiasCorrection_ = " << (int)IrradiationBiasCorrection_ << endl;
179  //cout << "(int)DoCosmics_ = " << (int)DoCosmics_ << endl;
180  //cout << "(int)LoadTemplatesFromDB_ = " << (int)LoadTemplatesFromDB_ << endl;
181  //cout << endl;
182 
183 
184  // Default case for rechit errors in case other, more correct, errors are not vailable
185  // This are constants. Maybe there is a more efficienct way to store them.
186  xerr_barrel_l1_= {0.00115, 0.00120, 0.00088};
187  xerr_barrel_l1_def_=0.01030;
188  yerr_barrel_l1_= {0.00375,0.00230,0.00250,0.00250,0.00230,0.00230,0.00210,0.00210,0.00240};
189  yerr_barrel_l1_def_=0.00210;
190  xerr_barrel_ln_= {0.00115, 0.00120, 0.00088};
191  xerr_barrel_ln_def_=0.01030;
192  yerr_barrel_ln_= {0.00375,0.00230,0.00250,0.00250,0.00230,0.00230,0.00210,0.00210,0.00240};
193  yerr_barrel_ln_def_=0.00210;
194  xerr_endcap_= {0.0020, 0.0020};
195  xerr_endcap_def_=0.0020;
196  yerr_endcap_= {0.00210};
197  yerr_endcap_def_=0.00075;
198 
199 }
200 
202 {
203  return new ClusterParamGeneric(cl);
204 }
205 
206 
207 
208 //-----------------------------------------------------------------------------
212 //-----------------------------------------------------------------------------
214 PixelCPEGeneric::localPosition(DetParam const & theDetParam, ClusterParam & theClusterParamBase) const
215 {
216 
217  ClusterParamGeneric & theClusterParam = static_cast<ClusterParamGeneric &>(theClusterParamBase);
218 
219  //cout<<" in PixelCPEGeneric:localPosition - "<<endl; //dk
220 
221  float chargeWidthX = (theDetParam.lorentzShiftInCmX * theDetParam.widthLAFractionX);
222  float chargeWidthY = (theDetParam.lorentzShiftInCmY * theDetParam.widthLAFractionY);
223  float shiftX = 0.5f*theDetParam.lorentzShiftInCmX;
224  float shiftY = 0.5f*theDetParam.lorentzShiftInCmY;
225 
226  //cout<<" main la width "<<chargeWidthX<<" "<<chargeWidthY<<endl;
227 
228  if ( UseErrorsFromTemplates_ ) {
229 
230  float qclus = theClusterParam.theCluster->charge();
231  float locBz = theDetParam.bz;
232  //cout << "PixelCPEGeneric::localPosition(...) : locBz = " << locBz << endl;
233 
234  theClusterParam.pixmx = -999.9; // max pixel charge for truncation of 2-D cluster
235  theClusterParam.sigmay = -999.9; // CPE Generic y-error for multi-pixel cluster
236  theClusterParam.deltay = -999.9; // CPE Generic y-bias for multi-pixel cluster
237  theClusterParam.sigmax = -999.9; // CPE Generic x-error for multi-pixel cluster
238  theClusterParam.deltax = -999.9; // CPE Generic x-bias for multi-pixel cluster
239  theClusterParam.sy1 = -999.9; // CPE Generic y-error for single single-pixel
240  theClusterParam.dy1 = -999.9; // CPE Generic y-bias for single single-pixel cluster
241  theClusterParam.sy2 = -999.9; // CPE Generic y-error for single double-pixel cluster
242  theClusterParam.dy2 = -999.9; // CPE Generic y-bias for single double-pixel cluster
243  theClusterParam.sx1 = -999.9; // CPE Generic x-error for single single-pixel cluster
244  theClusterParam.dx1 = -999.9; // CPE Generic x-bias for single single-pixel cluster
245  theClusterParam.sx2 = -999.9; // CPE Generic x-error for single double-pixel cluster
246  theClusterParam.dx2 = -999.9; // CPE Generic x-bias for single double-pixel cluster
247 
248 
249 #ifdef NEW_CPEERROR
250 
252  int gtemplID_ = theDetParam.detTemplateId;
253 
254  //int gtemplID0 = genErrorDBObject_->getGenErrorID(theDetParam.theDet->geographicalId().rawId());
255  //if(gtemplID0!=gtemplID_) cout<<" different id "<< gtemplID_<<" "<<gtemplID0<<endl;
256 
257  theClusterParam.qBin_ = gtempl.qbin( gtemplID_, theClusterParam.cotalpha, theClusterParam.cotbeta, locBz, qclus,
258  theClusterParam.pixmx, theClusterParam.sigmay, theClusterParam.deltay,
259  theClusterParam.sigmax, theClusterParam.deltax, theClusterParam.sy1,
260  theClusterParam.dy1, theClusterParam.sy2, theClusterParam.dy2, theClusterParam.sx1,
261  theClusterParam.dx1, theClusterParam.sx2, theClusterParam.dx2 );
262 
263  // now use the charge widths stored in the new generic template headers (change to the
264  // incorrect sign convention of the base class)
265  bool useLAWidthFromGenError = false;
266  if(useLAWidthFromGenError) {
267  chargeWidthX = (-micronsToCm*gtempl.lorxwidth());
268  chargeWidthY = (-micronsToCm*gtempl.lorywidth());
269  //cout<< " redefine la width (gen-error) "<< chargeWidthX<<" "<< chargeWidthY <<endl;
270  }
271  if(MYDEBUG) cout<<" new errors "<<gtemplID_<<" "<<theClusterParam.sy1<<endl;
272 
273 #else // select which one
274 
275  if(useNewSimplerErrors) { // errors from new light templates
276 
278  int gtemplID_ = theDetParam.detTemplateId;
279 
280  //int gtemplID0 = genErrorDBObject_->getGenErrorID(theDetParam.theDet->geographicalId().rawId());
281  //if(gtemplID0!=gtemplID_) cout<<" different id "<< gtemplID_<<" "<<gtemplID0<<endl;
282 
283  theClusterParam.qBin_ = gtempl.qbin( gtemplID_, theClusterParam.cotalpha, theClusterParam.cotbeta, locBz, qclus, // inputs
284  theClusterParam.pixmx, // returned by reference
285  theClusterParam.sigmay, theClusterParam.deltay, theClusterParam.sigmax, theClusterParam.deltax, // returned by reference
286  theClusterParam.sy1, theClusterParam.dy1, theClusterParam.sy2, theClusterParam.dy2, theClusterParam.sx1, theClusterParam.dx1, theClusterParam.sx2, theClusterParam.dx2 ); // returned by reference
287 
288 
289  // OK, now use the charge widths stored in the new generic template headers (change to the
290  // incorrect sign convention of the base class)
291  bool useLAWidthFromGenError = false;
292  if(useLAWidthFromGenError) {
293  chargeWidthX = (-micronsToCm*gtempl.lorxwidth());
294  chargeWidthY = (-micronsToCm*gtempl.lorywidth());
295  //cout<< " redefine la width (gen-error) "<< chargeWidthX<<" "<< chargeWidthY <<endl;
296  }
297  if(MYDEBUG) cout<<" new errors "<<gtemplID_<<" "<<theClusterParam.sy1<<endl;
298 
299 
300  } else { // errors from full templates
301 
303  //int templID0 = templateDBobject_->getTemplateID(theDetParam.theDet->geographicalId().rawId());
304  int templID_ = theDetParam.detTemplateId;
305  //if(templID0!=templID_) cout<<" different id"<< templID_<<" "<<templID0<<endl;
306 
307  theClusterParam.qBin_ = templ.qbin( templID_, theClusterParam.cotalpha, theClusterParam.cotbeta, locBz, qclus, // inputs
308  theClusterParam.pixmx, // returned by reference
309  theClusterParam.sigmay, theClusterParam.deltay, theClusterParam.sigmax, theClusterParam.deltax, // returned by reference
310  theClusterParam.sy1, theClusterParam.dy1, theClusterParam.sy2, theClusterParam.dy2, theClusterParam.sx1, theClusterParam.dx1, theClusterParam.sx2, theClusterParam.dx2 ); // returned by reference
311 
312  if(MYDEBUG) cout<<" errors "<<templID_<<" "<<theClusterParam.sy1<<endl;
313 
314  } // if iseNewSimplerErrors
315 
316 #endif // NEW_CPEERROR
317 
318  // These numbers come in microns from the qbin(...) call. Transform them to cm.
319  theClusterParam.deltax = theClusterParam.deltax * micronsToCm;
320  theClusterParam.dx1 = theClusterParam.dx1 * micronsToCm;
321  theClusterParam.dx2 = theClusterParam.dx2 * micronsToCm;
322 
323  theClusterParam.deltay = theClusterParam.deltay * micronsToCm;
324  theClusterParam.dy1 = theClusterParam.dy1 * micronsToCm;
325  theClusterParam.dy2 = theClusterParam.dy2 * micronsToCm;
326 
327  theClusterParam.sigmax = theClusterParam.sigmax * micronsToCm;
328  theClusterParam.sx1 = theClusterParam.sx1 * micronsToCm;
329  theClusterParam.sx2 = theClusterParam.sx2 * micronsToCm;
330 
331  theClusterParam.sigmay = theClusterParam.sigmay * micronsToCm;
332  theClusterParam.sy1 = theClusterParam.sy1 * micronsToCm;
333  theClusterParam.sy2 = theClusterParam.sy2 * micronsToCm;
334 
335  } // if ( UseErrorsFromTemplates_ )
336 
337  float Q_f_X = 0.0;
338  float Q_l_X = 0.0;
339  float Q_f_Y = 0.0;
340  float Q_l_Y = 0.0;
341  collect_edge_charges( theClusterParam,
342  Q_f_X, Q_l_X,
343  Q_f_Y, Q_l_Y );
344 
345  //--- Find the inner widths along X and Y in one shot. We
346  //--- compute the upper right corner of the inner pixels
347  //--- (== lower left corner of upper right pixel) and
348  //--- the lower left corner of the inner pixels
349  //--- (== upper right corner of lower left pixel), and then
350  //--- subtract these two points in the formula.
351 
352  //--- Upper Right corner of Lower Left pixel -- in measurement frame
353  MeasurementPoint meas_URcorn_LLpix( theClusterParam.theCluster->minPixelRow()+1.0,
354  theClusterParam.theCluster->minPixelCol()+1.0 );
355 
356  //--- Lower Left corner of Upper Right pixel -- in measurement frame
357  MeasurementPoint meas_LLcorn_URpix( theClusterParam.theCluster->maxPixelRow(),
358  theClusterParam.theCluster->maxPixelCol() );
359 
360  //--- These two now converted into the local
361  LocalPoint local_URcorn_LLpix;
362  LocalPoint local_LLcorn_URpix;
363 
364  // PixelCPEGeneric can be used with or without track angles
365  // If PixelCPEGeneric is called with track angles, use them to correct for bows/kinks:
366  if ( theClusterParam.with_track_angle ) {
367  local_URcorn_LLpix = theDetParam.theTopol->localPosition(meas_URcorn_LLpix, theClusterParam.loc_trk_pred);
368  local_LLcorn_URpix = theDetParam.theTopol->localPosition(meas_LLcorn_URpix, theClusterParam.loc_trk_pred);
369  } else {
370  local_URcorn_LLpix = theDetParam.theTopol->localPosition(meas_URcorn_LLpix);
371  local_LLcorn_URpix = theDetParam.theTopol->localPosition(meas_LLcorn_URpix);
372  }
373 
374  #ifdef EDM_ML_DEBUG
375  if (theVerboseLevel > 20) {
376  cout
377  << "\n\t >>> theClusterParam.theCluster->x = " << theClusterParam.theCluster->x()
378  << "\n\t >>> theClusterParam.theCluster->y = " << theClusterParam.theCluster->y()
379  << "\n\t >>> cluster: minRow = " << theClusterParam.theCluster->minPixelRow()
380  << " minCol = " << theClusterParam.theCluster->minPixelCol()
381  << "\n\t >>> cluster: maxRow = " << theClusterParam.theCluster->maxPixelRow()
382  << " maxCol = " << theClusterParam.theCluster->maxPixelCol()
383  << "\n\t >>> meas: inner lower left = " << meas_URcorn_LLpix.x()
384  << "," << meas_URcorn_LLpix.y()
385  << "\n\t >>> meas: inner upper right = " << meas_LLcorn_URpix.x()
386  << "," << meas_LLcorn_URpix.y()
387  << endl;
388  }
389 #endif
390 
391  //--- &&& Note that the cuts below should not be hardcoded (like in Orca and
392  //--- &&& CPEFromDetPosition/PixelCPEInitial), but rather be
393  //--- &&& externally settable (but tracked) parameters.
394 
395  //--- Position, including the half lorentz shift
396 
397  #ifdef EDM_ML_DEBUG
398  if (theVerboseLevel > 20)
399  cout << "\t >>> Generic:: processing X" << endl;
400 #endif
401 
402  float xPos =
403  generic_position_formula( theClusterParam.theCluster->sizeX(),
404  Q_f_X, Q_l_X,
405  local_URcorn_LLpix.x(), local_LLcorn_URpix.x(),
406  chargeWidthX, // lorentz shift in cm
407  theDetParam.theThickness,
408  theClusterParam.cotalpha,
409  theDetParam.thePitchX,
410  theDetParam.theRecTopol->isItBigPixelInX( theClusterParam.theCluster->minPixelRow() ),
411  theDetParam.theRecTopol->isItBigPixelInX( theClusterParam.theCluster->maxPixelRow() ),
414  the_size_cutX); // cut for eff charge width &&&
415 
416 
417  // apply the lorentz offset correction
418  xPos = xPos + shiftX;
419 
420 #ifdef EDM_ML_DEBUG
421  if (theVerboseLevel > 20)
422  cout << "\t >>> Generic:: processing Y" << endl;
423 #endif
424 
425  float yPos =
426  generic_position_formula( theClusterParam.theCluster->sizeY(),
427  Q_f_Y, Q_l_Y,
428  local_URcorn_LLpix.y(), local_LLcorn_URpix.y(),
429  chargeWidthY, // lorentz shift in cm
430  theDetParam.theThickness,
431  theClusterParam.cotbeta,
432  theDetParam.thePitchY,
433  theDetParam.theRecTopol->isItBigPixelInY( theClusterParam.theCluster->minPixelCol() ),
434  theDetParam.theRecTopol->isItBigPixelInY( theClusterParam.theCluster->maxPixelCol() ),
437  the_size_cutY); // cut for eff charge width &&&
438 
439  // apply the lorentz offset correction
440  yPos = yPos + shiftY;
441 
442  // Apply irradiation corrections. NOT USED FOR NOW
444  if ( theClusterParam.theCluster->sizeX() == 1 ) { // size=1
445  // ggiurgiu@jhu.edu, 02/03/09 : for size = 1, the Lorentz shift is already accounted by the irradiation correction
446  xPos = xPos - (0.5 * theDetParam.lorentzShiftInCmX);
447  // Find if pixel is double (big).
448  bool bigInX = theDetParam.theRecTopol->isItBigPixelInX( theClusterParam.theCluster->maxPixelRow() );
449  if ( !bigInX ) xPos -= theClusterParam.dx1;
450  else xPos -= theClusterParam.dx2;
451 
452  } else { // size>1
453  //cout << "Apply correction correction_deltax = " << deltax << " to xPos = " << xPos << endl;
454  xPos -= theClusterParam.deltax;
455  }
456 
457  if ( theClusterParam.theCluster->sizeY() == 1 ) {
458  // ggiurgiu@jhu.edu, 02/03/09 : for size = 1, the Lorentz shift is already accounted by the irradiation correction
459  yPos = yPos - (0.5 * theDetParam.lorentzShiftInCmY);
460 
461  // Find if pixel is double (big).
462  bool bigInY = theDetParam.theRecTopol->isItBigPixelInY( theClusterParam.theCluster->maxPixelCol() );
463  if ( !bigInY ) yPos -= theClusterParam.dy1;
464  else yPos -= theClusterParam.dy2;
465 
466  } else {
467  yPos -= theClusterParam.deltay;
468  }
469 
470  } // if ( IrradiationBiasCorrection_ )
471 
472  //cout<<" in PixelCPEGeneric:localPosition - pos = "<<xPos<<" "<<yPos<<endl; //dk
473 
474  //--- Now put the two together
475  LocalPoint pos_in_local( xPos, yPos );
476  return pos_in_local;
477 }
478 
479 
480 
481 //-----------------------------------------------------------------------------
486 //-----------------------------------------------------------------------------
487 float
490  float Q_f,
491  float Q_l,
492  float upper_edge_first_pix,
493  float lower_edge_last_pix,
494  float lorentz_shift,
495  float theThickness, //detector thickness
496  float cot_angle,
497  float pitch,
498  bool first_is_big,
499  bool last_is_big,
500  float eff_charge_cut_low,
501  float eff_charge_cut_high,
502  float size_cut
503  ) const
504 {
505 
506  //cout<<" in PixelCPEGeneric:generic_position_formula - "<<endl; //dk
507 
508  float geom_center = 0.5f * ( upper_edge_first_pix + lower_edge_last_pix );
509 
510  //--- The case of only one pixel in this projection is separate. Note that
511  //--- here first_pix == last_pix, so the average of the two is still the
512  //--- center of the pixel.
513  if ( size == 1 ) {return geom_center;}
514 
515  //--- Width of the clusters minus the edge (first and last) pixels.
516  //--- In the note, they are denoted x_F and x_L (and y_F and y_L)
517  float W_inner = lower_edge_last_pix - upper_edge_first_pix; // in cm
518 
519  //--- Predicted charge width from geometry
520  float W_pred = theThickness * cot_angle // geometric correction (in cm)
521  - lorentz_shift; // (in cm) &&& check fpix!
522 
523  //cout<<" in PixelCPEGeneric:generic_position_formula - "<<W_inner<<" "<<W_pred<<endl; //dk
524 
525  //--- Total length of the two edge pixels (first+last)
526  float sum_of_edge = 2.0f;
527  if (first_is_big) sum_of_edge += 1.0f;
528  if (last_is_big) sum_of_edge += 1.0f;
529 
530 
531  //--- The `effective' charge width -- particle's path in first and last pixels only
532  float W_eff = std::abs( W_pred ) - W_inner;
533 
534 
535  //--- If the observed charge width is inconsistent with the expectations
536  //--- based on the track, do *not* use W_pred-W_innner. Instead, replace
537  //--- it with an *average* effective charge width, which is the average
538  //--- length of the edge pixels.
539  //
540  // bool usedEdgeAlgo = false;
541  if ( (size >= size_cut) || (
542  ( W_eff/pitch < eff_charge_cut_low ) |
543  ( W_eff/pitch > eff_charge_cut_high ) ) )
544  {
545  W_eff = pitch * 0.5f * sum_of_edge; // ave. length of edge pixels (first+last) (cm)
546  // usedEdgeAlgo = true;
547 #ifdef EDM_ML_DEBUG
548  nRecHitsUsedEdge_++;
549 #endif
550  }
551 
552 
553  //--- Finally, compute the position in this projection
554  float Qdiff = Q_l - Q_f;
555  float Qsum = Q_l + Q_f;
556 
557  //--- Temporary fix for clusters with both first and last pixel with charge = 0
558  if(Qsum==0) Qsum=1.0f;
559  //float hit_pos = geom_center + 0.5f*(Qdiff/Qsum) * W_eff + half_lorentz_shift;
560  float hit_pos = geom_center + 0.5f*(Qdiff/Qsum) * W_eff;
561 
562  //cout<<" in PixelCPEGeneric:generic_position_formula - "<<hit_pos<<" "<<lorentz_shift*0.5<<endl; //dk
563 
564  #ifdef EDM_ML_DEBUG
565  //--- Debugging output
566  if (theVerboseLevel > 20) {
567  if ( theDetParam.thePart == GeomDetEnumerators::PixelBarrel ) {
568  cout << "\t >>> We are in the Barrel." ;
569  } else {
570  cout << "\t >>> We are in the Forward." ;
571  }
572  cout
573  << "\n\t >>> cot(angle) = " << cot_angle << " pitch = " << pitch << " size = " << size
574  << "\n\t >>> upper_edge_first_pix = " << upper_edge_first_pix
575  << "\n\t >>> lower_edge_last_pix = " << lower_edge_last_pix
576  << "\n\t >>> geom_center = " << geom_center
577  << "\n\t >>> half_lorentz_shift = " << half_lorentz_shift
578  << "\n\t >>> W_inner = " << W_inner
579  << "\n\t >>> W_pred = " << W_pred
580  << "\n\t >>> W_eff(orig) = " << fabs( W_pred ) - W_inner
581  << "\n\t >>> W_eff(used) = " << W_eff
582  << "\n\t >>> sum_of_edge = " << sum_of_edge
583  << "\n\t >>> Qdiff = " << Qdiff << " Qsum = " << Qsum
584  << "\n\t >>> hit_pos = " << hit_pos
585  << "\n\t >>> RecHits: total = " << nRecHitsTotal_
586  << " used edge = " << nRecHitsUsedEdge_
587  << endl;
588  if (usedEdgeAlgo)
589  cout << "\n\t >>> Used Edge algorithm." ;
590  else
591  cout << "\n\t >>> Used angle information." ;
592  cout << endl;
593  }
594 #endif
595 
596  return hit_pos;
597 }
598 
599 
600 //-----------------------------------------------------------------------------
604 //-----------------------------------------------------------------------------
605 void
607 collect_edge_charges(ClusterParam & theClusterParamBase,
608  float & Q_f_X,
609  float & Q_l_X,
610  float & Q_f_Y,
611  float & Q_l_Y
612  ) const
613 {
614  ClusterParamGeneric & theClusterParam = static_cast<ClusterParamGeneric &>(theClusterParamBase);
615 
616  // Initialize return variables.
617  Q_f_X = Q_l_X = 0.0;
618  Q_f_Y = Q_l_Y = 0.0;
619 
620 
621  // Obtain boundaries in index units
622  int xmin = theClusterParam.theCluster->minPixelRow();
623  int xmax = theClusterParam.theCluster->maxPixelRow();
624  int ymin = theClusterParam.theCluster->minPixelCol();
625  int ymax = theClusterParam.theCluster->maxPixelCol();
626 
627 
628  // Iterate over the pixels.
629  int isize = theClusterParam.theCluster->size();
630  for (int i = 0; i != isize; ++i)
631  {
632  auto const & pixel = theClusterParam.theCluster->pixel(i);
633  // ggiurgiu@fnal.gov: add pixel charge truncation
634  float pix_adc = pixel.adc;
636  pix_adc = std::min(pix_adc, theClusterParam.pixmx );
637 
638  //
639  // X projection
640  if ( pixel.x == xmin ) Q_f_X += pix_adc;
641  if ( pixel.x == xmax ) Q_l_X += pix_adc;
642  //
643  // Y projection
644  if ( pixel.y == ymin ) Q_f_Y += pix_adc;
645  if ( pixel.y == ymax ) Q_l_Y += pix_adc;
646  }
647 
648  return;
649 }
650 
651 
652 //============== INFLATED ERROR AND ERRORS FROM DB BELOW ================
653 
654 //-------------------------------------------------------------------------
655 // Hit error in the local frame
656 //-------------------------------------------------------------------------
657 LocalError
658 PixelCPEGeneric::localError(DetParam const & theDetParam, ClusterParam & theClusterParamBase) const
659 {
660 
661  ClusterParamGeneric & theClusterParam = static_cast<ClusterParamGeneric &>(theClusterParamBase);
662 
663  const bool localPrint = false;
664  // Default errors are the maximum error used for edge clusters.
665  // These are determined by looking at residuals for edge clusters
666  float xerr = EdgeClusterErrorX_ * micronsToCm;
667  float yerr = EdgeClusterErrorY_ * micronsToCm;
668 
669 
670  // Find if cluster is at the module edge.
671  int maxPixelCol = theClusterParam.theCluster->maxPixelCol();
672  int maxPixelRow = theClusterParam.theCluster->maxPixelRow();
673  int minPixelCol = theClusterParam.theCluster->minPixelCol();
674  int minPixelRow = theClusterParam.theCluster->minPixelRow();
675 
676  bool edgex = ( theDetParam.theRecTopol->isItEdgePixelInX( minPixelRow ) ) || ( theDetParam.theRecTopol->isItEdgePixelInX( maxPixelRow ) );
677  bool edgey = ( theDetParam.theRecTopol->isItEdgePixelInY( minPixelCol ) ) || ( theDetParam.theRecTopol->isItEdgePixelInY( maxPixelCol ) );
678 
679  unsigned int sizex = theClusterParam.theCluster->sizeX();
680  unsigned int sizey = theClusterParam.theCluster->sizeY();
681  if( int(sizex) != (maxPixelRow - minPixelRow+1) ) cout<<" wrong x"<<endl;
682  if( int(sizey) != (maxPixelCol - minPixelCol+1) ) cout<<" wrong y"<<endl;
683 
684  // Find if cluster contains double (big) pixels.
685  bool bigInX = theDetParam.theRecTopol->containsBigPixelInX( minPixelRow, maxPixelRow );
686  bool bigInY = theDetParam.theRecTopol->containsBigPixelInY( minPixelCol, maxPixelCol );
687 
688  if(localPrint) {
689  cout<<" endge clus "<<xerr<<" "<<yerr<<endl; //dk
690  if(bigInX || bigInY) cout<<" big "<<bigInX<<" "<<bigInY<<endl;
691  if(edgex || edgey) cout<<" edge "<<edgex<<" "<<edgey<<endl;
692  cout<<" before if "<<UseErrorsFromTemplates_<<" "<<theClusterParam.qBin_<<endl;
693  if(theClusterParam.qBin_ == 0)
694  cout<<" qbin 0! "<<edgex<<" "<<edgey<<" "<<bigInX<<" "<<bigInY<<" "
695  <<sizex<<" "<<sizey<<endl;
696  if(sizex==2 && sizey==2) cout<<" size 2*2 "<<theClusterParam.qBin_<<endl;
697  }
698 
699  //if likely(UseErrorsFromTemplates_ && (qBin_!= 0) ) {
701  //
702  // Use template errors
703  //cout << "Track angles are known. We can use either errors from templates or the error parameterization from DB." << endl;
704 
705 
706  if ( !edgex ) { // Only use this for non-edge clusters
707  if ( sizex == 1 ) {
708  if ( !bigInX ) {xerr = theClusterParam.sx1;}
709  else {xerr = theClusterParam.sx2;}
710  } else {xerr = theClusterParam.sigmax;}
711  }
712 
713  if ( !edgey ) { // Only use for non-edge clusters
714  if ( sizey == 1 ) {
715  if ( !bigInY ) {yerr = theClusterParam.sy1;}
716  else {yerr = theClusterParam.sy2;}
717  } else {yerr = theClusterParam.sigmay;}
718  }
719 
720  if(localPrint) {
721  cout<<" in if "<<edgex<<" "<<edgey<<" "<<sizex<<" "<<sizey<<endl;
722  cout<<" errors "<<xerr<<" "<<yerr<<" "<<theClusterParam.sx1<<" "<<theClusterParam.sx2<<" "<<theClusterParam.sigmax<<endl; //dk
723  }
724 
725  } else { // simple errors
726 
727  // This are the simple errors, hardcoded in the code
728  cout << "Track angles are not known and we are processing cosmics." << endl;
729  //cout << "Default angle estimation which assumes track from PV (0,0,0) does not work." << endl;
730 
731  if ( theDetParam.thePart == GeomDetEnumerators::PixelBarrel ) {
732 
733  DetId id = (theDetParam.theDet->geographicalId());
734  int layer=PXBDetId(id).layer();
735  if ( layer==1 ) {
736  if ( !edgex ) {
737  if ( sizex<=xerr_barrel_l1_.size() ) xerr=xerr_barrel_l1_[sizex-1];
738  else xerr=xerr_barrel_l1_def_;
739  }
740 
741  if ( !edgey ) {
742  if ( sizey<=yerr_barrel_l1_.size() ) yerr=yerr_barrel_l1_[sizey-1];
743  else yerr=yerr_barrel_l1_def_;
744  }
745  } else{ // layer 2,3
746  if ( !edgex ) {
747  if ( sizex<=xerr_barrel_ln_.size() ) xerr=xerr_barrel_ln_[sizex-1];
748  else xerr=xerr_barrel_ln_def_;
749  }
750 
751  if ( !edgey ) {
752  if ( sizey<=yerr_barrel_ln_.size() ) yerr=yerr_barrel_ln_[sizey-1];
753  else yerr=yerr_barrel_ln_def_;
754  }
755  }
756 
757  } else { // EndCap
758 
759  if ( !edgex ) {
760  if ( sizex<=xerr_endcap_.size() ) xerr=xerr_endcap_[sizex-1];
761  else xerr=xerr_endcap_def_;
762  }
763 
764  if ( !edgey ) {
765  if ( sizey<=yerr_endcap_.size() ) yerr=yerr_endcap_[sizey-1];
766  else yerr=yerr_endcap_def_;
767  }
768  } // end endcap
769 
770  if(inflate_errors) {
771  int n_bigx = 0;
772  int n_bigy = 0;
773 
774  for (int irow = 0; irow < 7; ++irow) {
775  if ( theDetParam.theRecTopol->isItBigPixelInX( irow+minPixelRow ) ) ++n_bigx;
776  }
777 
778  for (int icol = 0; icol < 21; ++icol) {
779  if ( theDetParam.theRecTopol->isItBigPixelInY( icol+minPixelCol ) ) ++n_bigy;
780  }
781 
782  xerr = (float)(sizex + n_bigx) * theDetParam.thePitchX / std::sqrt( 12.0f );
783  yerr = (float)(sizey + n_bigy) * theDetParam.thePitchY / std::sqrt( 12.0f );
784 
785  } // if(inflate_errors)
786 
787  } // end
788 
789 #ifdef EDM_ML_DEBUG
790  if ( !(xerr > 0.0) )
791  throw cms::Exception("PixelCPEGeneric::localError")
792  << "\nERROR: Negative pixel error xerr = " << xerr << "\n\n";
793 
794  if ( !(yerr > 0.0) )
795  throw cms::Exception("PixelCPEGeneric::localError")
796  << "\nERROR: Negative pixel error yerr = " << yerr << "\n\n";
797 #endif
798 
799  if(localPrint) {
800  cout<<" errors "<<xerr<<" "<<yerr<<endl; //dk
801  if(theClusterParam.qBin_ == 0) cout<<" qbin 0 "<<xerr<<" "<<yerr<<endl;
802  }
803 
804  auto xerr_sq = xerr*xerr;
805  auto yerr_sq = yerr*yerr;
806 
807  return LocalError( xerr_sq, 0, yerr_sq );
808 
809 }
810 
811 
812 
813 
814 
815 
#define LogDebug(id)
T getParameter(std::string const &) const
bool containsBigPixelInY(int iymin, int iymax) const
std::vector< float > xerr_barrel_l1_
int i
Definition: DBlmapReader.cc:9
float charge() const
int minPixelCol() const
bool isItEdgePixelInY(int iybin) const
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
float the_eff_charge_cut_highY
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_
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
virtual bool isItBigPixelInY(const int iybin) const
const SiPixelCluster * theCluster
Definition: PixelCPEBase.h:89
bool isItEdgePixelInX(int ixbin) const
static bool pushfile(int filenum, std::vector< SiPixelTemplateStore > &thePixelTemp_)
T y() const
Definition: PV3DBase.h:63
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::vector< SiPixelGenErrorStore > thePixelGenError_
PixelCPEGeneric(edm::ParameterSet const &conf, const MagneticField *, const TrackerGeometry &, const SiPixelLorentzAngle *, const SiPixelGenErrorDBObject *, const SiPixelTemplateDBObject *, const SiPixelLorentzAngle *)
The constructor.
const PixelGeomDetUnit * theDet
Definition: PixelCPEBase.h:59
GeomDetType::SubDetector thePart
Definition: PixelCPEBase.h:64
bool IrradiationBiasCorrection_
#define constexpr
unsigned int layer() const
layer id
Definition: PXBDetId.h:35
const RectangularPixelTopology * theRecTopol
Definition: PixelCPEBase.h:62
std::vector< float > yerr_endcap_
int maxPixelRow() const
double xPos
#define likely(x)
const PixelTopology * theTopol
Definition: PixelCPEBase.h:61
int minPixelRow() const
bool LoadTemplatesFromDB_
Definition: PixelCPEBase.h:253
float the_eff_charge_cut_lowX
T sqrt(T t)
Definition: SSEVec.h:48
bool inflate_all_errors_no_trk_angle
void collect_edge_charges(ClusterParam &theClusterParam, float &Q_f_X, float &Q_l_X, float &Q_f_Y, float &Q_l_Y) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const SiPixelTemplateDBObject * templateDBobject_
Definition: PixelCPEBase.h:249
double yPos
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:72
double f[11][100]
T min(T a, T b)
Definition: MathUtil.h:58
float lorxwidth()
signed lorentz x-width (microns)
float generic_position_formula(int size, float Q_f, float 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) const
bool containsBigPixelInX(int ixmin, int ixmax) const
std::vector< float > xerr_endcap_
tuple conf
Definition: dbtoconf.py:185
Definition: DetId.h:18
Topology::LocalTrackPred loc_trk_pred
Definition: PixelCPEBase.h:102
const SiPixelGenErrorDBObject * genErrorDBObject_
Definition: PixelCPEBase.h:246
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.
LocalError localError(DetParam const &theDetParam, ClusterParam &theClusterParam) const
Pixel pixel(int i) const
float lorywidth()
signed lorentz y-width (microns)
virtual bool isItBigPixelInX(const int ixbin) const
std::vector< SiPixelTemplateStore > thePixelTemp_
float y() const
tuple cout
Definition: gather_cfg.py:121
static bool pushfile(int filenum, std::vector< SiPixelGenErrorStore > &thePixelTemp_)
int sizeX() const
T x() const
Definition: PV3DBase.h:62
LocalPoint localPosition(DetParam const &theDetParam, ClusterParam &theClusterParam) const
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)
tuple size
Write out results.
float x() const
float the_eff_charge_cut_highX
ClusterParam * createClusterParam(const SiPixelCluster &cl) const
int size() const