CMS 3D CMS Logo

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