CMS 3D CMS Logo

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