CMS 3D CMS Logo

PixelCPETemplateReco.cc
Go to the documentation of this file.
1 // Include our own header first
3 
4 // Geometry services
7 
8 //#define DEBUG
9 
10 // MessageLogger
12 
13 // Magnetic field
15 
16 // The template header files
18 
19 // Commented for now (3/10/17) until we figure out how to resuscitate 2D template splitter
21 
23 
24 #include <vector>
25 #include "boost/multi_array.hpp"
26 
27 #include <iostream>
28 
29 using namespace SiPixelTemplateReco;
30 //using namespace SiPixelTemplateSplit;
31 using namespace std;
32 
33 namespace {
34  constexpr float micronsToCm = 1.0e-4;
35  constexpr int cluster_matrix_size_x = 13;
36  constexpr int cluster_matrix_size_y = 21;
37 }
38 
39 //-----------------------------------------------------------------------------
40 // Constructor.
41 //
42 //-----------------------------------------------------------------------------
44  const MagneticField * mag,
45  const TrackerGeometry& geom,
46  const TrackerTopology& ttopo,
47  const SiPixelLorentzAngle * lorentzAngle,
48  const SiPixelTemplateDBObject * templateDBobject)
49 : PixelCPEBase(conf, mag, geom, ttopo, lorentzAngle, 0, templateDBobject, 0,1)
50 {
51  //cout << endl;
52  //cout << "Constructing PixelCPETemplateReco::PixelCPETemplateReco(...)................................................." << endl;
53  //cout << endl;
54 
55  // Configurable parameters
56  //DoCosmics_ = conf.getParameter<bool>("DoCosmics"); // Not used in templates
57  //LoadTemplatesFromDB_ = conf.getParameter<bool>("LoadTemplatesFromDB"); // Moved to Base
58 
59  //cout << " PixelCPETemplateReco : (int)LoadTemplatesFromDB_ = " << (int)LoadTemplatesFromDB_ << endl;
60  //cout << "field_magnitude = " << field_magnitude << endl;
61 
62  // configuration parameter to decide between DB or text file template access
63 
65  {
66  //cout << "PixelCPETemplateReco: Loading templates from database (DB) --------- " << endl;
67 
68  // Initialize template store to the selected ID [Morris, 6/25/08]
70  throw cms::Exception("PixelCPETemplateReco")
71  << "\nERROR: Templates not filled correctly. Check the sqlite file. Using SiPixelTemplateDBObject version "
72  << (*templateDBobject_).version() << "\n\n";
73  }
74  else
75  {
76  //cout << "PixelCPETemplateReco : Loading templates 40 and 41 from ASCII files ------------------------" << endl;
77 
79  throw cms::Exception("PixelCPETemplateReco")
80  << "\nERROR: Templates 40 not loaded correctly from text file. Reconstruction will fail.\n\n";
81 
83  throw cms::Exception("PixelCPETemplateReco")
84  << "\nERROR: Templates 41 not loaded correctly from text file. Reconstruction will fail.\n\n";
85  }
86 
87  speed_ = conf.getParameter<int>( "speed");
88  LogDebug("PixelCPETemplateReco::PixelCPETemplateReco:") <<
89  "Template speed = " << speed_ << "\n";
90 
91  UseClusterSplitter_ = conf.getParameter<bool>("UseClusterSplitter");
92 
93 }
94 
95 //-----------------------------------------------------------------------------
96 // Clean up.
97 //-----------------------------------------------------------------------------
99 {
100  // &&& delete template store?
101 }
102 
104 {
105  return new ClusterParamTemplate(cl);
106 }
107 
108 
109 //------------------------------------------------------------------
110 // Public methods mandated by the base class.
111 //------------------------------------------------------------------
112 
113 //------------------------------------------------------------------
114 // The main call to the template code.
115 //------------------------------------------------------------------
117 PixelCPETemplateReco::localPosition(DetParam const & theDetParam, ClusterParam & theClusterParamBase) const
118 {
119 
120  ClusterParamTemplate & theClusterParam = static_cast<ClusterParamTemplate &>(theClusterParamBase);
121 
123  throw cms::Exception("PixelCPETemplateReco::localPosition :")
124  << "A non-pixel detector type in here?";
125  // barrel(false) or forward(true)
126  const bool fpix = GeomDetEnumerators::isEndcap(theDetParam.thePart);
127 
128  int ID = -9999;
129  if ( LoadTemplatesFromDB_ ) {
130  int ID0 = templateDBobject_->getTemplateID(theDetParam.theDet->geographicalId()); // just to comapre
131  ID = theDetParam.detTemplateId;
132  if(ID0!=ID) cout<<" different id"<< ID<<" "<<ID0<<endl;
133  } else { // from asci file
134  if ( !fpix ) ID = 40; // barrel
135  else ID = 41; // endcap
136  }
137  //cout << "PixelCPETemplateReco : ID = " << ID << endl;
138 
140 
141  // Preparing to retrieve ADC counts from the SiPixeltheClusterParam.theCluster-> In the cluster,
142  // we have the following:
143  // int minPixelRow(); // Minimum pixel index in the x direction (low edge).
144  // int maxPixelRow(); // Maximum pixel index in the x direction (top edge).
145  // int minPixelCol(); // Minimum pixel index in the y direction (left edge).
146  // int maxPixelCol(); // Maximum pixel index in the y direction (right edge).
147  // So the pixels from minPixelRow() will go into clust_array_2d[0][*],
148  // and the pixels from minPixelCol() will go into clust_array_2d[*][0].
149 
150  int row_offset = theClusterParam.theCluster->minPixelRow();
151  int col_offset = theClusterParam.theCluster->minPixelCol();
152 
153  // Store the coordinates of the center of the (0,0) pixel of the array that
154  // gets passed to PixelTempReco2D
155  // Will add these values to the output of PixelTempReco2D
156  float tmp_x = float(row_offset) + 0.5f;
157  float tmp_y = float(col_offset) + 0.5f;
158 
159  // Store these offsets (to be added later) in a LocalPoint after tranforming
160  // them from measurement units (pixel units) to local coordinates (cm)
161 
162  // ggiurgiu@jhu.edu 12/09/2010 : update call with trk angles needed for bow/kink corrections
163  LocalPoint lp;
164 
165  if ( theClusterParam.with_track_angle )
166  lp = theDetParam.theTopol->localPosition( MeasurementPoint(tmp_x, tmp_y), theClusterParam.loc_trk_pred );
167  else
168  {
169  edm::LogError("PixelCPETemplateReco")
170  << "@SUB = PixelCPETemplateReco::localPosition"
171  << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
172 
173  lp = theDetParam.theTopol->localPosition( MeasurementPoint(tmp_x, tmp_y) );
174  }
175 
176  // first compute matrix size
177  int mrow=0, mcol=0;
178  for (int i=0 ; i!=theClusterParam.theCluster->size(); ++i )
179  {
180  auto pix = theClusterParam.theCluster->pixel(i);
181  int irow = int(pix.x);
182  int icol = int(pix.y);
183  mrow = std::max(mrow,irow);
184  mcol = std::max(mcol,icol);
185  }
186  mrow -= row_offset; mrow+=1; mrow = std::min(mrow,cluster_matrix_size_x);
187  mcol -= col_offset; mcol+=1; mcol = std::min(mcol,cluster_matrix_size_y);
188  assert(mrow>0); assert(mcol>0);
189 
190  float clustMatrix[mrow][mcol];
191  memset(clustMatrix,0,sizeof(float)*mrow*mcol);
192 
193  // Copy clust's pixels (calibrated in electrons) into clusMatrix;
194  for (int i=0 ; i!=theClusterParam.theCluster->size(); ++i )
195  {
196  auto pix = theClusterParam.theCluster->pixel(i);
197  int irow = int(pix.x) - row_offset;
198  int icol = int(pix.y) - col_offset;
199 
200  // Gavril : what do we do here if the row/column is larger than cluster_matrix_size_x/cluster_matrix_size_y ?
201  // Ignore them for the moment...
202  if ( (irow<mrow) & (icol<mcol) ) clustMatrix[irow][icol] = float(pix.adc);
203 
204  }
205 
206 
207  // Make and fill the bool arrays flagging double pixels
208  bool xdouble[mrow], ydouble[mcol];
209  // x directions (shorter), rows
210  for (int irow = 0; irow < mrow; ++irow)
211  xdouble[irow] = theDetParam.theRecTopol->isItBigPixelInX( irow+row_offset );
212 
213  // y directions (longer), columns
214  for (int icol = 0; icol < mcol; ++icol)
215  ydouble[icol] = theDetParam.theRecTopol->isItBigPixelInY( icol+col_offset );
216 
217  SiPixelTemplateReco::ClusMatrix clusterPayload{&clustMatrix[0][0], xdouble, ydouble, mrow,mcol};
218 
219  // Output:
220  float nonsense = -99999.9f; // nonsense init value
221  theClusterParam.templXrec_ = theClusterParam.templYrec_ = theClusterParam.templSigmaX_ = theClusterParam.templSigmaY_ = nonsense;
222  // If the template recontruction fails, we want to return 1.0 for now
223  theClusterParam.templProbY_ = theClusterParam.templProbX_ = theClusterParam.templProbQ_ = 1.0f;
224  theClusterParam.templQbin_ = 0;
225  // We have a boolean denoting whether the reco failed or not
226  theClusterParam.hasFilledProb_ = false;
227 
228  float templYrec1_ = nonsense;
229  float templXrec1_ = nonsense;
230  float templYrec2_ = nonsense;
231  float templXrec2_ = nonsense;
232 
233  // ******************************************************************
234  // Do it! Use cotalpha_ and cotbeta_ calculated in PixelCPEBase
235 
236 
237  float locBz = theDetParam.bz;
238  float locBx = theDetParam.bx;
239 
240  theClusterParam.ierr =
241  PixelTempReco2D( ID, theClusterParam.cotalpha, theClusterParam.cotbeta,
242  locBz, locBx,
243  clusterPayload,
244  templ,
245  theClusterParam.templYrec_, theClusterParam.templSigmaY_, theClusterParam.templProbY_,
246  theClusterParam.templXrec_, theClusterParam.templSigmaX_, theClusterParam.templProbX_,
247  theClusterParam.templQbin_,
248  speed_,
249  theClusterParam.templProbQ_
250  );
251 
252  // ******************************************************************
253 
254  // Check exit status
255  if unlikely( theClusterParam.ierr != 0 )
256  {
257  LogDebug("PixelCPETemplateReco::localPosition") <<
258  "reconstruction failed with error " << theClusterParam.ierr << "\n";
259 
260  // Gavril: what do we do in this case ? For now, just return the cluster center of gravity in microns
261  // In the x case, apply a rough Lorentz drift average correction
262  // To do: call PixelCPEGeneric whenever PixelTempReco2D fails
263  float lorentz_drift = -999.9;
264  if ( !fpix )
265  lorentz_drift = 60.0f; // in microns
266  else
267  lorentz_drift = 10.0f; // in microns
268  // ggiurgiu@jhu.edu, 21/09/2010 : trk angles needed to correct for bows/kinks
269  if ( theClusterParam.with_track_angle )
270  {
271  theClusterParam.templXrec_ = theDetParam.theTopol->localX( theClusterParam.theCluster->x(), theClusterParam.loc_trk_pred ) - lorentz_drift * micronsToCm; // rough Lorentz drift correction
272  theClusterParam.templYrec_ = theDetParam.theTopol->localY( theClusterParam.theCluster->y(), theClusterParam.loc_trk_pred );
273  }
274  else
275  {
276  edm::LogError("PixelCPETemplateReco")
277  << "@SUB = PixelCPETemplateReco::localPosition"
278  << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
279 
280  theClusterParam.templXrec_ = theDetParam.theTopol->localX( theClusterParam.theCluster->x() ) - lorentz_drift * micronsToCm; // rough Lorentz drift correction
281  theClusterParam.templYrec_ = theDetParam.theTopol->localY( theClusterParam.theCluster->y() );
282  }
283  }
284  else if unlikely( UseClusterSplitter_ && theClusterParam.templQbin_ == 0 )
285  {
286  cout << " PixelCPETemplateReco : We should never be here !!!!!!!!!!!!!!!!!!!!!!" << endl;
287  cout << " (int)UseClusterSplitter_ = " << (int)UseClusterSplitter_ << endl;
288 
289  //ierr =
290  //PixelTempSplit( ID, fpix, cotalpha_, cotbeta_,
291  // clust_array_2d, ydouble, xdouble,
292  // templ,
293  // templYrec1_, templYrec2_, templSigmaY_, templProbY_,
294  // templXrec1_, templXrec2_, templSigmaX_, templProbX_,
295  // templQbin_ );
296 
297 
298  // Commented for now (3/10/17) until we figure out how to resuscitate 2D template splitter
302 
303  theClusterParam.ierr = -123;
304  /*
305  float dchisq;
306  float templProbQ_;
307  SiPixelTemplateSplit::PixelTempSplit( ID, theClusterParam.cotalpha, theClusterParam.cotbeta,
308  clust_array_2d,
309  ydouble, xdouble,
310  templ,
311  templYrec1_, templYrec2_, theClusterParam.templSigmaY_, theClusterParam.templProbY_,
312  templXrec1_, templXrec2_, theClusterParam.templSigmaX_, theClusterParam.templProbX_,
313  theClusterParam.templQbin_,
314  templProbQ_,
315  true,
316  dchisq,
317  templ2D_ );
318 
319  */
320  if ( theClusterParam.ierr != 0 )
321  {
322  LogDebug("PixelCPETemplateReco::localPosition") <<
323  "reconstruction failed with error " << theClusterParam.ierr << "\n";
324 
325  // Gavril: what do we do in this case ? For now, just return the cluster center of gravity in microns
326  // In the x case, apply a rough Lorentz drift average correction
327  // To do: call PixelCPEGeneric whenever PixelTempReco2D fails
328  float lorentz_drift = -999.9f;
329  if ( !fpix )
330  lorentz_drift = 60.0f; // in microns
331  else
332  lorentz_drift = 10.0f; // in microns
333 
334  // ggiurgiu@jhu.edu, 12/09/2010 : trk angles needed to correct for bows/kinks
335  if ( theClusterParam.with_track_angle )
336  {
337  theClusterParam.templXrec_ = theDetParam.theTopol->localX( theClusterParam.theCluster->x(),theClusterParam.loc_trk_pred ) - lorentz_drift * micronsToCm; // rough Lorentz drift correction
338  theClusterParam.templYrec_ = theDetParam.theTopol->localY( theClusterParam.theCluster->y(),theClusterParam.loc_trk_pred );
339  }
340  else
341  {
342  edm::LogError("PixelCPETemplateReco")
343  << "@SUB = PixelCPETemplateReco::localPosition"
344  << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
345 
346  theClusterParam.templXrec_ = theDetParam.theTopol->localX( theClusterParam.theCluster->x() ) - lorentz_drift * micronsToCm; // very rough Lorentz drift correction
347  theClusterParam.templYrec_ = theDetParam.theTopol->localY( theClusterParam.theCluster->y() );
348 
349  }
350  }
351  else
352  {
353  // go from micrometer to centimeter
354  templXrec1_ *= micronsToCm;
355  templYrec1_ *= micronsToCm;
356  templXrec2_ *= micronsToCm;
357  templYrec2_ *= micronsToCm;
358 
359  // go back to the module coordinate system
360  templXrec1_ += lp.x();
361  templYrec1_ += lp.y();
362  templXrec2_ += lp.x();
363  templYrec2_ += lp.y();
364 
365  // calculate distance from each hit to the track and choose the
366  // hit closest to the track
367  float distance11 = sqrt( (templXrec1_ - theClusterParam.trk_lp_x)*(templXrec1_ - theClusterParam.trk_lp_x) +
368  (templYrec1_ - theClusterParam.trk_lp_y)*(templYrec1_ - theClusterParam.trk_lp_y) );
369 
370  float distance12 = sqrt( (templXrec1_ - theClusterParam.trk_lp_x)*(templXrec1_ - theClusterParam.trk_lp_x) +
371  (templYrec2_ - theClusterParam.trk_lp_y)*(templYrec2_ - theClusterParam.trk_lp_y) );
372 
373  float distance21 = sqrt( (templXrec2_ - theClusterParam.trk_lp_x)*(templXrec2_ - theClusterParam.trk_lp_x) +
374  (templYrec1_ - theClusterParam.trk_lp_y)*(templYrec1_ - theClusterParam.trk_lp_y) );
375 
376  float distance22 = sqrt( (templXrec2_ - theClusterParam.trk_lp_x)*(templXrec2_ - theClusterParam.trk_lp_x) +
377  (templYrec2_ - theClusterParam.trk_lp_y)*(templYrec2_ - theClusterParam.trk_lp_y) );
378 
379  float min_templXrec_ = -999.9;
380  float min_templYrec_ = -999.9;
381  float distance_min = 9999999999.9;
382  if ( distance11 < distance_min )
383  {
384  distance_min = distance11;
385  min_templXrec_ = templXrec1_;
386  min_templYrec_ = templYrec1_;
387  }
388  if ( distance12 < distance_min )
389  {
390  distance_min = distance12;
391  min_templXrec_ = templXrec1_;
392  min_templYrec_ = templYrec2_;
393  }
394  if ( distance21 < distance_min )
395  {
396  distance_min = distance21;
397  min_templXrec_ = templXrec2_;
398  min_templYrec_ = templYrec1_;
399  }
400  if ( distance22 < distance_min )
401  {
402  distance_min = distance22;
403  min_templXrec_ = templXrec2_;
404  min_templYrec_ = templYrec2_;
405  }
406 
407  theClusterParam.templXrec_ = min_templXrec_;
408  theClusterParam.templYrec_ = min_templYrec_;
409  }
410  } // else if ( UseClusterSplitter_ && templQbin_ == 0 )
411 
412  else // apparenly this is he good one!
413  {
414  // go from micrometer to centimeter
415  theClusterParam.templXrec_ *= micronsToCm;
416  theClusterParam.templYrec_ *= micronsToCm;
417 
418  // go back to the module coordinate system
419  theClusterParam.templXrec_ += lp.x();
420  theClusterParam.templYrec_ += lp.y();
421 
422  // Compute the Alignment Group Corrections [template ID should already be selected from call to reco procedure]
423  if ( DoLorentz_ ) {
424  // Do only if the lotentzshift has meaningfull numbers
425  if( theDetParam.lorentzShiftInCmX!= 0.0 || theDetParam.lorentzShiftInCmY!= 0.0 ) {
426  // the LA width/shift returned by templates use (+)
427  // the LA width/shift produced by PixelCPEBase for positive LA is (-)
428  // correct this by iserting (-)
429  //float temp1 = -micronsToCm*templ.lorxwidth(); // old
430  //float temp2 = -micronsToCm*templ.lorywidth(); // does not incl 1/2
431  float templateLorbiasCmX = -micronsToCm*templ.lorxbias(); // new
432  float templateLorbiasCmY = -micronsToCm*templ.lorybias(); //incl. 1/2
433  // now, correctly, we can use the difference of shifts
434  //theClusterParam.templXrec_ += 0.5*(theDetParam.lorentzShiftInCmX - templateLorbiasCmX);
435  //theClusterParam.templYrec_ += 0.5*(theDetParam.lorentzShiftInCmY - templateLorbiasCmY);
436  theClusterParam.templXrec_ += (0.5*(theDetParam.lorentzShiftInCmX) - templateLorbiasCmX);
437  theClusterParam.templYrec_ += (0.5*(theDetParam.lorentzShiftInCmY) - templateLorbiasCmY);
438  //cout << "Templates: la lorentz offset = "
439  // <<(0.5*(theDetParam.lorentzShiftInCmX)-templateLorbiasCmX)
440  // <<" "<<templateLorbiasCmX<<" "<<templateLorbiasCmY
441  // <<" "<<temp1<<" "<<temp2
442  // <<" "<<theDetParam.lorentzShiftInCmX
443  // <<" "<<theDetParam.lorentzShiftInCmY
444  // << endl; //dk
445  } //else {cout<<" LA is 0, disable offset corrections "<<endl;} //dk
446  } //else {cout<<" Do not do LA offset correction "<<endl;} //dk
447 
448  }
449 
450  // Save probabilities and qBin in the quantities given to us by the base class
451  // (for which there are also inline getters). &&& templProbX_ etc. should be retired...
452  theClusterParam.probabilityX_ = theClusterParam.templProbX_;
453  theClusterParam.probabilityY_ = theClusterParam.templProbY_;
454  theClusterParam.probabilityQ_ = theClusterParam.templProbQ_;
455  theClusterParam.qBin_ = theClusterParam.templQbin_;
456 
457  if ( theClusterParam.ierr == 0 ) // always true here
458  theClusterParam.hasFilledProb_ = true;
459 
460  return LocalPoint( theClusterParam.templXrec_, theClusterParam.templYrec_ );
461 
462 }
463 
464 //------------------------------------------------------------------
465 // localError() relies on localPosition() being called FIRST!!!
466 //------------------------------------------------------------------
468 PixelCPETemplateReco::localError(DetParam const & theDetParam, ClusterParam & theClusterParamBase) const
469 {
470 
471  ClusterParamTemplate & theClusterParam = static_cast<ClusterParamTemplate &>(theClusterParamBase);
472 
473  //cout << endl;
474  //cout << "Set PixelCPETemplate errors .............................................." << endl;
475 
476  //cout << "CPETemplate : " << endl;
477 
478  //--- Default is the maximum error used for edge clusters.
479  const float sig12 = 1./sqrt(12.0);
480  float xerr = theDetParam.thePitchX *sig12;
481  float yerr = theDetParam.thePitchY *sig12;
482 
483  // Check if the errors were already set at the clusters splitting level
484  if ( theClusterParam.theCluster->getSplitClusterErrorX() > 0.0f && theClusterParam.theCluster->getSplitClusterErrorX() < 7777.7f &&
485  theClusterParam.theCluster->getSplitClusterErrorY() > 0.0f && theClusterParam.theCluster->getSplitClusterErrorY() < 7777.7f )
486  {
487  xerr = theClusterParam.theCluster->getSplitClusterErrorX() * micronsToCm;
488  yerr = theClusterParam.theCluster->getSplitClusterErrorY() * micronsToCm;
489 
490  //cout << "Errors set at cluster splitting level : " << endl;
491  //cout << "xerr = " << xerr << endl;
492  //cout << "yerr = " << yerr << endl;
493  }
494  else
495  {
496  // If errors are not split at the cluster splitting level, set the errors here
497 
498  //cout << "Errors are not split at the cluster splitting level, set the errors here : " << endl;
499 
500  int maxPixelCol = theClusterParam.theCluster->maxPixelCol();
501  int maxPixelRow = theClusterParam.theCluster->maxPixelRow();
502  int minPixelCol = theClusterParam.theCluster->minPixelCol();
503  int minPixelRow = theClusterParam.theCluster->minPixelRow();
504 
505  //--- Are we near either of the edges?
506  bool edgex = ( theDetParam.theRecTopol->isItEdgePixelInX( minPixelRow ) || theDetParam.theRecTopol->isItEdgePixelInX( maxPixelRow ) );
507  bool edgey = ( theDetParam.theRecTopol->isItEdgePixelInY( minPixelCol ) || theDetParam.theRecTopol->isItEdgePixelInY( maxPixelCol ) );
508 
509  if ( theClusterParam.ierr !=0 )
510  {
511  // If reconstruction fails the hit position is calculated from cluster center of gravity
512  // corrected in x by average Lorentz drift. Assign huge errors.
513  //xerr = 10.0 * (float)theClusterParam.theCluster->sizeX() * xerr;
514  //yerr = 10.0 * (float)theClusterParam.theCluster->sizeX() * yerr;
515 
517  throw cms::Exception("PixelCPETemplateReco::localPosition :")
518  << "A non-pixel detector type in here?";
519 
520  // Assign better errors based on the residuals for failed template cases
521  if ( GeomDetEnumerators::isBarrel(theDetParam.thePart) )
522  {
523  xerr = 55.0f * micronsToCm;
524  yerr = 36.0f * micronsToCm;
525  }
526  else
527  {
528  xerr = 42.0f * micronsToCm;
529  yerr = 39.0f * micronsToCm;
530  }
531 
532  //cout << "xerr = " << xerr << endl;
533  //cout << "yerr = " << yerr << endl;
534 
535  //return LocalError(xerr*xerr, 0, yerr*yerr);
536  }
537  else if ( edgex || edgey )
538  {
539  // for edge pixels assign errors according to observed residual RMS
540  if ( edgex && !edgey )
541  {
542  xerr = 23.0f * micronsToCm;
543  yerr = 39.0f * micronsToCm;
544  }
545  else if ( !edgex && edgey )
546  {
547  xerr = 24.0f * micronsToCm;
548  yerr = 96.0f * micronsToCm;
549  }
550  else if ( edgex && edgey )
551  {
552  xerr = 31.0f * micronsToCm;
553  yerr = 90.0f * micronsToCm;
554  }
555  else
556  {
557  throw cms::Exception(" PixelCPETemplateReco::localError: Something wrong with pixel edge flag !!!");
558  }
559 
560  //cout << "xerr = " << xerr << endl;
561  //cout << "yerr = " << yerr << endl;
562  }
563  else
564  {
565  // &&& need a class const
566  //const float micronsToCm = 1.0e-4;
567 
568  xerr = theClusterParam.templSigmaX_ * micronsToCm;
569  yerr = theClusterParam.templSigmaY_ * micronsToCm;
570 
571  //cout << "xerr = " << xerr << endl;
572  //cout << "yerr = " << yerr << endl;
573 
574  // &&& should also check ierr (saved as class variable) and return
575  // &&& nonsense (another class static) if the template fit failed.
576  }
577 
578  if (theVerboseLevel > 9)
579  {
580  LogDebug("PixelCPETemplateReco") <<
581  " Sizex = " << theClusterParam.theCluster->sizeX() << " Sizey = " << theClusterParam.theCluster->sizeY() << " Edgex = " << edgex << " Edgey = " << edgey <<
582  " ErrX = " << xerr << " ErrY = " << yerr;
583  }
584 
585  } // else
586 
587  if ( !(xerr > 0.0f) )
588  throw cms::Exception("PixelCPETemplateReco::localError")
589  << "\nERROR: Negative pixel error xerr = " << xerr << "\n\n";
590 
591  if ( !(yerr > 0.0f) )
592  throw cms::Exception("PixelCPETemplateReco::localError")
593  << "\nERROR: Negative pixel error yerr = " << yerr << "\n\n";
594 
595  //cout << "Final errors set to: " << endl;
596  //cout << "xerr = " << xerr << endl;
597  //cout << "yerr = " << yerr << endl;
598  //cout << "Out of PixelCPETemplateREco..........................................................................." << endl;
599  //cout << endl;
600 
601  return LocalError(xerr*xerr, 0, yerr*yerr);
602 }
603 
#define LogDebug(id)
T getParameter(std::string const &) const
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:32
LocalError localError(DetParam const &theDetParam, ClusterParam &theClusterParam) const
short getTemplateID(const uint32_t &detid) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
uint32_t ID
Definition: Definitions.h:26
bool isBarrel(GeomDetEnumerators::SubDetector m)
static bool pushfile(int filenum, std::vector< SiPixelTemplateStore > &thePixelTemp_)
T y() const
Definition: PV3DBase.h:63
int PixelTempReco2D(int id, float cotalpha, float cotbeta, float locBz, float locBx, ClusMatrix &cluster, SiPixelTemplate &templ, float &yrec, float &sigmay, float &proby, float &xrec, float &sigmax, float &probx, int &qbin, int speed, bool deadpix, std::vector< std::pair< int, int > > &zeropix, float &probQ, int &nypix, int &nxpix)
const PixelGeomDetUnit * theDet
Definition: PixelCPEBase.h:60
GeomDetType::SubDetector thePart
Definition: PixelCPEBase.h:65
#define constexpr
const RectangularPixelTopology * theRecTopol
Definition: PixelCPEBase.h:63
std::vector< SiPixelTemplateStore > thePixelTemp_
PixelCPETemplateReco(edm::ParameterSet const &conf, const MagneticField *, const TrackerGeometry &, const TrackerTopology &, const SiPixelLorentzAngle *, const SiPixelTemplateDBObject *)
#define unlikely(x)
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
bool isItEdgePixelInX(int ixbin) const override
const PixelTopology * theTopol
Definition: PixelCPEBase.h:62
bool LoadTemplatesFromDB_
Definition: PixelCPEBase.h:253
T sqrt(T t)
Definition: SSEVec.h:18
const SiPixelTemplateDBObject * templateDBobject_
Definition: PixelCPEBase.h:249
virtual float localX(float mpX) const =0
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
bool isEndcap(GeomDetEnumerators::SubDetector m)
bool isItBigPixelInY(const int iybin) const override
bool isItBigPixelInX(const int ixbin) const override
float lorybias()
signed lorentz y-width (microns)
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
ClusterParam * createClusterParam(const SiPixelCluster &cl) const
Pixel cluster – collection of neighboring pixels above threshold.
float lorxbias()
signed lorentz x-width (microns)
LocalPoint localPosition(DetParam const &theDetParam, ClusterParam &theClusterParam) const
virtual float localY(float mpY) const =0
bool isItEdgePixelInY(int iybin) const override
T x() const
Definition: PV3DBase.h:62
bool isTrackerPixel(GeomDetEnumerators::SubDetector m)