00001
00002 #include "RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h"
00003
00004
00005 #include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h"
00006 #include "Geometry/TrackerGeometryBuilder/interface/RectangularPixelTopology.h"
00007
00008
00009
00010
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012
00013
00014 #include "MagneticField/Engine/interface/MagneticField.h"
00015
00016
00017 #include "RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateReco.h"
00018
00019 #include "RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateSplit.h"
00020
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022
00023 #include <vector>
00024 #include "boost/multi_array.hpp"
00025
00026 #include <iostream>
00027
00028 using namespace SiPixelTemplateReco;
00029
00030 using namespace std;
00031
00032 const float PI = 3.141593;
00033 const float HALFPI = PI * 0.5;
00034 const float degsPerRad = 57.29578;
00035
00036
00037 const float micronsToCm = 1.0e-4;
00038
00039 const int cluster_matrix_size_x = 13;
00040 const int cluster_matrix_size_y = 21;
00041
00042
00043
00044
00045
00046 PixelCPETemplateReco::PixelCPETemplateReco(edm::ParameterSet const & conf,
00047 const MagneticField * mag, const SiPixelLorentzAngle * lorentzAngle,
00048 const SiPixelTemplateDBObject * templateDBobject)
00049 : PixelCPEBase(conf, mag, lorentzAngle, 0, templateDBobject)
00050 {
00051
00052
00053
00054
00055
00056
00057
00058
00059 DoCosmics_ = conf.getParameter<bool>("DoCosmics");
00060 LoadTemplatesFromDB_ = conf.getParameter<bool>("LoadTemplatesFromDB");
00061
00062
00063
00064
00065 if ( LoadTemplatesFromDB_ )
00066 {
00067
00068
00069
00070 if ( !templ_.pushfile( *templateDBobject_) )
00071 throw cms::Exception("PixelCPETemplateReco")
00072 << "\nERROR: Templates not filled correctly. Check the sqlite file. Using SiPixelTemplateDBObject version "
00073 << (*templateDBobject_).version() << "\n\n";
00074 }
00075 else
00076 {
00077
00078
00079 if ( !templ_.pushfile( 40 ) )
00080 throw cms::Exception("PixelCPETemplateReco")
00081 << "\nERROR: Templates 40 not loaded correctly from text file. Reconstruction will fail.\n\n";
00082
00083 if ( !templ_.pushfile( 41 ) )
00084 throw cms::Exception("PixelCPETemplateReco")
00085 << "\nERROR: Templates 41 not loaded correctly from text file. Reconstruction will fail.\n\n";
00086 }
00087
00088 speed_ = conf.getParameter<int>( "speed");
00089 LogDebug("PixelCPETemplateReco::PixelCPETemplateReco:") <<
00090 "Template speed = " << speed_ << "\n";
00091
00092 UseClusterSplitter_ = conf.getParameter<bool>("UseClusterSplitter");
00093
00094 }
00095
00096
00097
00098
00099 PixelCPETemplateReco::~PixelCPETemplateReco()
00100 {
00101
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 LocalPoint
00114 PixelCPETemplateReco::localPosition(const SiPixelCluster& cluster, const GeomDetUnit & det) const
00115 {
00116 setTheDet( det, cluster );
00117
00118 bool fpix;
00119 if ( thePart == GeomDetEnumerators::PixelBarrel )
00120 fpix = false;
00121 else
00122 fpix = true;
00123
00124 int ID = -9999;
00125
00126 if ( LoadTemplatesFromDB_ )
00127 {
00128 ID = templateDBobject_->getTemplateID(theDet->geographicalId());
00129 }
00130 else
00131 {
00132 if ( !fpix )
00133 ID = 40;
00134 else
00135 ID = 41;
00136 }
00137
00138
00139
00140
00141
00142
00143 boost::multi_array<float, 2> clust_array_2d(boost::extents[cluster_matrix_size_x][cluster_matrix_size_y]);
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 int row_offset = cluster.minPixelRow();
00155 int col_offset = cluster.minPixelCol();
00156
00157
00158
00159
00160 float tmp_x = float(row_offset) + 0.5f;
00161 float tmp_y = float(col_offset) + 0.5f;
00162
00163
00164
00165
00166
00167 LocalPoint lp;
00168
00169 if ( with_track_angle )
00170 lp = theTopol->localPosition( MeasurementPoint(tmp_x, tmp_y), loc_trk_pred_ );
00171 else
00172 {
00173 edm::LogError("PixelCPETemplateReco")
00174 << "@SUB = PixelCPETemplateReco::localPosition"
00175 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00176
00177 lp = theTopol->localPosition( MeasurementPoint(tmp_x, tmp_y) );
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 for (int i=0 ; i!=cluster.size(); ++i )
00215 {
00216 auto pix = cluster.pixel(i);
00217
00218
00219
00220
00221 int irow = int(pix.x) - row_offset;
00222 int icol = int(pix.y) - col_offset;
00223
00224
00225
00226 if ( irow<cluster_matrix_size_x && icol<cluster_matrix_size_y )
00227
00228 clust_array_2d[irow][icol] = (float)pix.adc;
00229 }
00230
00231
00232 std::vector<bool> ydouble(cluster_matrix_size_y), xdouble(cluster_matrix_size_x);
00233
00234 for (int irow = 0; irow < cluster_matrix_size_x; ++irow)
00235 {
00236 xdouble[irow] = theRecTopol->isItBigPixelInX( irow+row_offset );
00237 }
00238
00239
00240 for (int icol = 0; icol < cluster_matrix_size_y; ++icol)
00241 {
00242 ydouble[icol] = theRecTopol->isItBigPixelInY( icol+col_offset );
00243 }
00244
00245
00246 float nonsense = -99999.9f;
00247 templXrec_ = templYrec_ = templSigmaX_ = templSigmaY_ = nonsense;
00248
00249 templProbY_ = templProbX_ = templProbQ_ = 1.0f;
00250 templQbin_ = 0;
00251
00252 hasFilledProb_ = false;
00253
00254 float templYrec1_ = nonsense;
00255 float templXrec1_ = nonsense;
00256 float templYrec2_ = nonsense;
00257 float templXrec2_ = nonsense;
00258
00259
00260
00261
00262
00263 float locBz = (*theParam).bz;
00264
00265 ierr =
00266 PixelTempReco2D( ID, cotalpha_, cotbeta_,
00267 locBz,
00268 clust_array_2d, ydouble, xdouble,
00269 templ_,
00270 templYrec_, templSigmaY_, templProbY_,
00271 templXrec_, templSigmaX_, templProbX_,
00272 templQbin_,
00273 speed_,
00274 templProbQ_
00275 );
00276
00277
00278
00279
00280 if unlikely( ierr != 0 )
00281 {
00282 LogDebug("PixelCPETemplateReco::localPosition") <<
00283 "reconstruction failed with error " << ierr << "\n";
00284
00285
00286
00287
00288 float lorentz_drift = -999.9;
00289 if ( thePart == GeomDetEnumerators::PixelBarrel )
00290 lorentz_drift = 60.0f;
00291 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00292 lorentz_drift = 10.0f;
00293 else
00294 throw cms::Exception("PixelCPETemplateReco::localPosition :")
00295 << "A non-pixel detector type in here?" << "\n";
00296
00297 if ( with_track_angle )
00298 {
00299 templXrec_ = theTopol->localX( cluster.x(), loc_trk_pred_ ) - lorentz_drift * micronsToCm;
00300 templYrec_ = theTopol->localY( cluster.y(), loc_trk_pred_ );
00301 }
00302 else
00303 {
00304 edm::LogError("PixelCPETemplateReco")
00305 << "@SUB = PixelCPETemplateReco::localPosition"
00306 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00307
00308 templXrec_ = theTopol->localX( cluster.x() ) - lorentz_drift * micronsToCm;
00309 templYrec_ = theTopol->localY( cluster.y() );
00310 }
00311 }
00312 else if unlikely( UseClusterSplitter_ && templQbin_ == 0 )
00313 {
00314 cout << " PixelCPETemplateReco : We should never be here !!!!!!!!!!!!!!!!!!!!!!" << endl;
00315 cout << " (int)UseClusterSplitter_ = " << (int)UseClusterSplitter_ << endl;
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 float dchisq;
00327 float templProbQ_;
00328 SiPixelTemplate2D templ2D_;
00329 templ2D_.pushfile(ID);
00330
00331 ierr =
00332 SiPixelTemplateSplit::PixelTempSplit( ID, cotalpha_, cotbeta_,
00333 clust_array_2d,
00334 ydouble, xdouble,
00335 templ_,
00336 templYrec1_, templYrec2_, templSigmaY_, templProbY_,
00337 templXrec1_, templXrec2_, templSigmaX_, templProbX_,
00338 templQbin_,
00339 templProbQ_,
00340 true,
00341 dchisq,
00342 templ2D_ );
00343
00344
00345 if ( ierr != 0 )
00346 {
00347 LogDebug("PixelCPETemplateReco::localPosition") <<
00348 "reconstruction failed with error " << ierr << "\n";
00349
00350
00351
00352
00353 float lorentz_drift = -999.9f;
00354 if ( thePart == GeomDetEnumerators::PixelBarrel )
00355 lorentz_drift = 60.0f;
00356 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00357 lorentz_drift = 10.0f;
00358 else
00359 throw cms::Exception("PixelCPETemplateReco::localPosition :")
00360 << "A non-pixel detector type in here?" << "\n";
00361
00362
00363 if ( with_track_angle )
00364 {
00365 templXrec_ = theTopol->localX( cluster.x(),loc_trk_pred_ ) - lorentz_drift * micronsToCm;
00366 templYrec_ = theTopol->localY( cluster.y(),loc_trk_pred_ );
00367 }
00368 else
00369 {
00370 edm::LogError("PixelCPETemplateReco")
00371 << "@SUB = PixelCPETemplateReco::localPosition"
00372 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00373
00374 templXrec_ = theTopol->localX( cluster.x() ) - lorentz_drift * micronsToCm;
00375 templYrec_ = theTopol->localY( cluster.y() );
00376
00377 }
00378 }
00379 else
00380 {
00381
00382 templXrec1_ *= micronsToCm;
00383 templYrec1_ *= micronsToCm;
00384 templXrec2_ *= micronsToCm;
00385 templYrec2_ *= micronsToCm;
00386
00387
00388 templXrec1_ += lp.x();
00389 templYrec1_ += lp.y();
00390 templXrec2_ += lp.x();
00391 templYrec2_ += lp.y();
00392
00393
00394
00395 float distance11 = sqrt( (templXrec1_ - trk_lp_x)*(templXrec1_ - trk_lp_x) +
00396 (templYrec1_ - trk_lp_y)*(templYrec1_ - trk_lp_y) );
00397
00398 float distance12 = sqrt( (templXrec1_ - trk_lp_x)*(templXrec1_ - trk_lp_x) +
00399 (templYrec2_ - trk_lp_y)*(templYrec2_ - trk_lp_y) );
00400
00401 float distance21 = sqrt( (templXrec2_ - trk_lp_x)*(templXrec2_ - trk_lp_x) +
00402 (templYrec1_ - trk_lp_y)*(templYrec1_ - trk_lp_y) );
00403
00404 float distance22 = sqrt( (templXrec2_ - trk_lp_x)*(templXrec2_ - trk_lp_x) +
00405 (templYrec2_ - trk_lp_y)*(templYrec2_ - trk_lp_y) );
00406
00407 float min_templXrec_ = -999.9;
00408 float min_templYrec_ = -999.9;
00409 float distance_min = 9999999999.9;
00410 if ( distance11 < distance_min )
00411 {
00412 distance_min = distance11;
00413 min_templXrec_ = templXrec1_;
00414 min_templYrec_ = templYrec1_;
00415 }
00416 if ( distance12 < distance_min )
00417 {
00418 distance_min = distance12;
00419 min_templXrec_ = templXrec1_;
00420 min_templYrec_ = templYrec2_;
00421 }
00422 if ( distance21 < distance_min )
00423 {
00424 distance_min = distance21;
00425 min_templXrec_ = templXrec2_;
00426 min_templYrec_ = templYrec1_;
00427 }
00428 if ( distance22 < distance_min )
00429 {
00430 distance_min = distance22;
00431 min_templXrec_ = templXrec2_;
00432 min_templYrec_ = templYrec2_;
00433 }
00434
00435 templXrec_ = min_templXrec_;
00436 templYrec_ = min_templYrec_;
00437 }
00438 }
00439
00440 else
00441 {
00442
00443 templXrec_ *= micronsToCm;
00444 templYrec_ *= micronsToCm;
00445
00446
00447 templXrec_ += lp.x();
00448 templYrec_ += lp.y();
00449 }
00450
00451
00452
00453 probabilityX_ = templProbX_;
00454 probabilityY_ = templProbY_;
00455 probabilityQ_ = templProbQ_;
00456 qBin_ = templQbin_;
00457
00458 if ( ierr == 0 )
00459 hasFilledProb_ = true;
00460
00461 return LocalPoint( templXrec_, templYrec_ );
00462
00463 }
00464
00465
00466
00467
00468 LocalError
00469 PixelCPETemplateReco::localError( const SiPixelCluster& cluster,
00470 const GeomDetUnit& det ) const
00471 {
00472
00473
00474
00475
00476
00477
00478 const float sig12 = 1./sqrt(12.0);
00479 float xerr = thePitchX *sig12;
00480 float yerr = thePitchY *sig12;
00481
00482
00483 if ( cluster.getSplitClusterErrorX() > 0.0f && cluster.getSplitClusterErrorX() < 7777.7f &&
00484 cluster.getSplitClusterErrorY() > 0.0f && cluster.getSplitClusterErrorY() < 7777.7f )
00485 {
00486 xerr = cluster.getSplitClusterErrorX() * micronsToCm;
00487 yerr = cluster.getSplitClusterErrorY() * micronsToCm;
00488
00489
00490
00491
00492 }
00493 else
00494 {
00495
00496
00497
00498
00499 setTheDet( det, cluster );
00500
00501 int maxPixelCol = cluster.maxPixelCol();
00502 int maxPixelRow = cluster.maxPixelRow();
00503 int minPixelCol = cluster.minPixelCol();
00504 int minPixelRow = cluster.minPixelRow();
00505
00506
00507 bool edgex = ( theRecTopol->isItEdgePixelInX( minPixelRow ) || theRecTopol->isItEdgePixelInX( maxPixelRow ) );
00508 bool edgey = ( theRecTopol->isItEdgePixelInY( minPixelCol ) || theRecTopol->isItEdgePixelInY( maxPixelCol ) );
00509
00510 if ( ierr !=0 )
00511 {
00512
00513
00514
00515
00516
00517
00518 if ( thePart == GeomDetEnumerators::PixelBarrel )
00519 {
00520 xerr = 55.0f * micronsToCm;
00521 yerr = 36.0f * micronsToCm;
00522 }
00523 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00524 {
00525 xerr = 42.0f * micronsToCm;
00526 yerr = 39.0f * micronsToCm;
00527 }
00528 else
00529 throw cms::Exception("PixelCPETemplateReco::localError :") << "A non-pixel detector type in here?" ;
00530
00531
00532
00533
00534
00535 }
00536 else if ( edgex || edgey )
00537 {
00538
00539 if ( edgex && !edgey )
00540 {
00541 xerr = 23.0f * micronsToCm;
00542 yerr = 39.0f * micronsToCm;
00543 }
00544 else if ( !edgex && edgey )
00545 {
00546 xerr = 24.0f * micronsToCm;
00547 yerr = 96.0f * micronsToCm;
00548 }
00549 else if ( edgex && edgey )
00550 {
00551 xerr = 31.0f * micronsToCm;
00552 yerr = 90.0f * micronsToCm;
00553 }
00554 else
00555 {
00556 throw cms::Exception(" PixelCPETemplateReco::localError: Something wrong with pixel edge flag !!!");
00557 }
00558
00559
00560
00561 }
00562 else
00563 {
00564
00565
00566
00567 xerr = templSigmaX_ * micronsToCm;
00568 yerr = templSigmaY_ * micronsToCm;
00569
00570
00571
00572
00573
00574
00575 }
00576
00577 if (theVerboseLevel > 9)
00578 {
00579 LogDebug("PixelCPETemplateReco") <<
00580 " Sizex = " << cluster.sizeX() << " Sizey = " << cluster.sizeY() << " Edgex = " << edgex << " Edgey = " << edgey <<
00581 " ErrX = " << xerr << " ErrY = " << yerr;
00582 }
00583
00584 }
00585
00586 if ( !(xerr > 0.0f) )
00587 throw cms::Exception("PixelCPETemplateReco::localError")
00588 << "\nERROR: Negative pixel error xerr = " << xerr << "\n\n";
00589
00590 if ( !(yerr > 0.0f) )
00591 throw cms::Exception("PixelCPETemplateReco::localError")
00592 << "\nERROR: Negative pixel error yerr = " << yerr << "\n\n";
00593
00594
00595
00596
00597
00598
00599
00600 return LocalError(xerr*xerr, 0, yerr*yerr);
00601 }
00602