00001
00002 #include "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 "SiPixelTemplateReco.h"
00018
00019 #include "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 using namespace std;
00030
00031 const float PI = 3.141593;
00032 const float HALFPI = PI * 0.5;
00033 const float degsPerRad = 57.29578;
00034
00035
00036 const float micronsToCm = 1.0e-4;
00037
00038 const int cluster_matrix_size_x = 13;
00039 const int cluster_matrix_size_y = 21;
00040
00041
00042
00043
00044
00045 PixelCPETemplateReco::PixelCPETemplateReco(edm::ParameterSet const & conf,
00046 const MagneticField * mag, const SiPixelLorentzAngle * lorentzAngle,
00047 const SiPixelTemplateDBObject * templateDBobject)
00048 : PixelCPEBase(conf, mag, lorentzAngle, 0, templateDBobject)
00049 {
00050
00051
00052
00053
00054
00055
00056 DoCosmics_ = conf.getParameter<bool>("DoCosmics");
00057 LoadTemplatesFromDB_ = conf.getParameter<bool>("LoadTemplatesFromDB");
00058
00059
00060
00061
00062 if ( LoadTemplatesFromDB_ )
00063 {
00064
00065 if ( !templ_.pushfile( *templateDBobject_) )
00066 throw cms::Exception("PixelCPETemplateReco")
00067 << "\nERROR: Templates not filled correctly. Check the sqlite file. Using SiPixelTemplateDBObject version "
00068 << (*templateDBobject_).version() << "\n\n";
00069 }
00070 else
00071 {
00072 if ( !templ_.pushfile( templID_ ) )
00073 throw cms::Exception("PixelCPETemplateReco")
00074 << "\nERROR: Templates not loaded correctly from text file. Reconstruction will fail.\n\n";
00075 }
00076
00077 speed_ = conf.getParameter<int>( "speed");
00078 LogDebug("PixelCPETemplateReco::PixelCPETemplateReco:") <<
00079 "Template speed = " << speed_ << "\n";
00080
00081 UseClusterSplitter_ = conf.getParameter<bool>("UseClusterSplitter");
00082
00083 }
00084
00085
00086
00087
00088 PixelCPETemplateReco::~PixelCPETemplateReco()
00089 {
00090
00091 }
00092
00093
00094 MeasurementPoint
00095 PixelCPETemplateReco::measurementPosition(const SiPixelCluster& cluster,
00096 const GeomDetUnit & det) const
00097 {
00098 LocalPoint lp = localPosition(cluster,det);
00099
00100
00101 if ( with_track_angle )
00102 return theTopol->measurementPosition(lp, Topology::LocalTrackAngles( loc_traj_param_.dxdz(), loc_traj_param_.dydz() ) );
00103 else
00104 {
00105 edm::LogError("PixelCPETemplateReco")
00106 << "@SUB = PixelCPETemplateReco::measurementPosition"
00107 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00108
00109 return theTopol->measurementPosition( lp );
00110 }
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 LocalPoint
00122 PixelCPETemplateReco::localPosition(const SiPixelCluster& cluster, const GeomDetUnit & det) const
00123 {
00124 setTheDet( det, cluster );
00125 templID_ = templateDBobject_->getTemplateID(theDet->geographicalId());
00126
00127
00128 int ID = templID_;
00129
00130
00131 bool fpix;
00132 if ( thePart == GeomDetEnumerators::PixelBarrel )
00133 fpix = false;
00134 else
00135 fpix = true;
00136
00137
00138
00139 boost::multi_array<float, 2> clust_array_2d(boost::extents[cluster_matrix_size_x][cluster_matrix_size_y]);
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 int row_offset = cluster.minPixelRow();
00150 int col_offset = cluster.minPixelCol();
00151
00152
00153
00154
00155 float tmp_x = float(cluster.minPixelRow()) + 0.5;
00156 float tmp_y = float(cluster.minPixelCol()) + 0.5;
00157
00158
00159
00160
00161
00162 LocalPoint lp;
00163
00164 if ( with_track_angle )
00165 lp = theTopol->localPosition( MeasurementPoint(tmp_x, tmp_y), loc_trk_pred_ );
00166 else
00167 {
00168 edm::LogError("PixelCPETemplateReco")
00169 << "@SUB = PixelCPETemplateReco::localPosition"
00170 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00171
00172 lp = theTopol->localPosition( MeasurementPoint(tmp_x, tmp_y) );
00173 }
00174
00175 const std::vector<SiPixelCluster::Pixel> & pixVec = cluster.pixels();
00176 std::vector<SiPixelCluster::Pixel>::const_iterator
00177 pixIter = pixVec.begin(), pixEnd = pixVec.end();
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 for ( ; pixIter != pixEnd; ++pixIter )
00213 {
00214
00215
00216
00217
00218 int irow = int(pixIter->x) - row_offset;
00219 int icol = int(pixIter->y) - col_offset;
00220
00221
00222
00223 if ( irow<cluster_matrix_size_x && icol<cluster_matrix_size_y )
00224
00225 clust_array_2d[irow][icol] = (float)pixIter->adc;
00226 }
00227
00228
00229 std::vector<bool> ydouble(cluster_matrix_size_y), xdouble(cluster_matrix_size_x);
00230
00231 for (int irow = 0; irow < cluster_matrix_size_x; ++irow)
00232 {
00233 xdouble[irow] = theTopol->isItBigPixelInX( irow+row_offset );
00234 }
00235
00236
00237 for (int icol = 0; icol < cluster_matrix_size_y; ++icol)
00238 {
00239 ydouble[icol] = theTopol->isItBigPixelInY( icol+col_offset );
00240 }
00241
00242
00243 float nonsense = -99999.9;
00244 templXrec_ = templYrec_ = templSigmaX_ = templSigmaY_ = nonsense;
00245
00246 templProbY_ = templProbX_ = templProbQ_ = 1.0;
00247 templQbin_ = 0;
00248
00249 hasFilledProb_ = false;
00250
00251 float templYrec1_ = nonsense;
00252 float templXrec1_ = nonsense;
00253 float templYrec2_ = nonsense;
00254 float templXrec2_ = nonsense;
00255
00256
00257
00258
00259 GlobalVector bfield = magfield_->inTesla( theDet->surface().position() );
00260
00261 Frame detFrame( theDet->surface().position(), theDet->surface().rotation() );
00262 LocalVector Bfield = detFrame.toLocal( bfield );
00263 float locBz = Bfield.z();
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 ( ierr != 0 )
00281 {
00282 LogDebug("PixelCPETemplateReco::localPosition") <<
00283 "reconstruction failed with error " << ierr << "\n";
00284
00285
00286
00287
00288 double lorentz_drift = -999.9;
00289 if ( thePart == GeomDetEnumerators::PixelBarrel )
00290 lorentz_drift = 60.0;
00291 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00292 lorentz_drift = 10.0;
00293 else
00294 throw cms::Exception("PixelCPETemplateReco::localPosition :")
00295 << "A non-pixel detector type in here?" << "\n";
00296
00297
00298 if ( with_track_angle )
00299 {
00300 templXrec_ = theTopol->localX( cluster.x(), loc_trk_pred_ ) - lorentz_drift * micronsToCm;
00301 templYrec_ = theTopol->localY( cluster.y(), loc_trk_pred_ );
00302 }
00303 else
00304 {
00305 edm::LogError("PixelCPETemplateReco")
00306 << "@SUB = PixelCPETemplateReco::localPosition"
00307 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00308
00309 templXrec_ = theTopol->localX( cluster.x() ) - lorentz_drift * micronsToCm;
00310 templYrec_ = theTopol->localY( cluster.y() );
00311 }
00312
00313 }
00314 else if ( UseClusterSplitter_ && templQbin_ == 0 )
00315 {
00316 ierr =
00317 PixelTempSplit( ID, fpix, cotalpha_, cotbeta_,
00318 clust_array_2d, ydouble, xdouble,
00319 templ_,
00320 templYrec1_, templYrec2_, templSigmaY_, templProbY_,
00321 templXrec1_, templXrec2_, templSigmaX_, templProbX_,
00322 templQbin_ );
00323
00324 if ( ierr != 0 )
00325 {
00326 LogDebug("PixelCPETemplateReco::localPosition") <<
00327 "reconstruction failed with error " << ierr << "\n";
00328
00329
00330
00331
00332 double lorentz_drift = -999.9;
00333 if ( thePart == GeomDetEnumerators::PixelBarrel )
00334 lorentz_drift = 60.0;
00335 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00336 lorentz_drift = 10.0;
00337 else
00338 throw cms::Exception("PixelCPETemplateReco::localPosition :")
00339 << "A non-pixel detector type in here?" << "\n";
00340
00341
00342 if ( with_track_angle )
00343 {
00344 templXrec_ = theTopol->localX( cluster.x(),loc_trk_pred_ ) - lorentz_drift * micronsToCm;
00345 templYrec_ = theTopol->localY( cluster.y(),loc_trk_pred_ );
00346 }
00347 else
00348 {
00349 edm::LogError("PixelCPETemplateReco")
00350 << "@SUB = PixelCPETemplateReco::localPosition"
00351 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00352
00353 templXrec_ = theTopol->localX( cluster.x() ) - lorentz_drift * micronsToCm;
00354 templYrec_ = theTopol->localY( cluster.y() );
00355
00356 }
00357 }
00358 else
00359 {
00360
00361 templXrec1_ *= micronsToCm;
00362 templYrec1_ *= micronsToCm;
00363 templXrec2_ *= micronsToCm;
00364 templYrec2_ *= micronsToCm;
00365
00366
00367 templXrec1_ += lp.x();
00368 templYrec1_ += lp.y();
00369 templXrec2_ += lp.x();
00370 templYrec2_ += lp.y();
00371
00372
00373
00374 float distance11 = sqrt( (templXrec1_ - trk_lp_x)*(templXrec1_ - trk_lp_x) +
00375 (templYrec1_ - trk_lp_y)*(templYrec1_ - trk_lp_y) );
00376
00377 float distance12 = sqrt( (templXrec1_ - trk_lp_x)*(templXrec1_ - trk_lp_x) +
00378 (templYrec2_ - trk_lp_y)*(templYrec2_ - trk_lp_y) );
00379
00380 float distance21 = sqrt( (templXrec2_ - trk_lp_x)*(templXrec2_ - trk_lp_x) +
00381 (templYrec1_ - trk_lp_y)*(templYrec1_ - trk_lp_y) );
00382
00383 float distance22 = sqrt( (templXrec2_ - trk_lp_x)*(templXrec2_ - trk_lp_x) +
00384 (templYrec2_ - trk_lp_y)*(templYrec2_ - trk_lp_y) );
00385
00386 int index_dist = -999;
00387 float min_templXrec_ = -999.9;
00388 float min_templYrec_ = -999.9;
00389 float distance_min = 9999999999.9;
00390 if ( distance11 < distance_min )
00391 {
00392 distance_min = distance11;
00393 min_templXrec_ = templXrec1_;
00394 min_templYrec_ = templYrec1_;
00395 index_dist = 1;
00396 }
00397 if ( distance12 < distance_min )
00398 {
00399 distance_min = distance12;
00400 min_templXrec_ = templXrec1_;
00401 min_templYrec_ = templYrec2_;
00402 index_dist = 2;
00403 }
00404 if ( distance21 < distance_min )
00405 {
00406 distance_min = distance21;
00407 min_templXrec_ = templXrec2_;
00408 min_templYrec_ = templYrec1_;
00409 index_dist = 3;
00410 }
00411 if ( distance22 < distance_min )
00412 {
00413 distance_min = distance22;
00414 min_templXrec_ = templXrec2_;
00415 min_templYrec_ = templYrec2_;
00416 index_dist = 4;
00417 }
00418
00419 templXrec_ = min_templXrec_;
00420 templYrec_ = min_templYrec_;
00421 }
00422 }
00423 else
00424 {
00425
00426 templXrec_ *= micronsToCm;
00427 templYrec_ *= micronsToCm;
00428
00429
00430 templXrec_ += lp.x();
00431 templYrec_ += lp.y();
00432 }
00433
00434
00435
00436 probabilityX_ = templProbX_;
00437 probabilityY_ = templProbY_;
00438 probabilityQ_ = templProbQ_;
00439 qBin_ = templQbin_;
00440 if(ierr==0) hasFilledProb_ = true;
00441
00442 LocalPoint template_lp = LocalPoint( nonsense, nonsense );
00443 template_lp = LocalPoint( templXrec_, templYrec_ );
00444
00445 return template_lp;
00446
00447 }
00448
00449
00450
00451
00452 LocalError
00453 PixelCPETemplateReco::localError( const SiPixelCluster& cluster,
00454 const GeomDetUnit& det ) const
00455 {
00456 setTheDet( det, cluster );
00457
00458
00459 float xerr = thePitchX / sqrt(12.0);
00460 float yerr = thePitchY / sqrt(12.0);
00461
00462 int maxPixelCol = cluster.maxPixelCol();
00463 int maxPixelRow = cluster.maxPixelRow();
00464 int minPixelCol = cluster.minPixelCol();
00465 int minPixelRow = cluster.minPixelRow();
00466
00467
00468 bool edgex = ( theTopol->isItEdgePixelInX( minPixelRow ) || theTopol->isItEdgePixelInX( maxPixelRow ) );
00469 bool edgey = ( theTopol->isItEdgePixelInY( minPixelCol ) || theTopol->isItEdgePixelInY( maxPixelCol ) );
00470
00471 if ( ierr !=0 )
00472 {
00473
00474
00475
00476
00477
00478
00479 if ( thePart == GeomDetEnumerators::PixelBarrel )
00480 {
00481 xerr = 55.0 * micronsToCm;
00482 yerr = 36.0 * micronsToCm;
00483 }
00484 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00485 {
00486 xerr = 42.0 * micronsToCm;
00487 yerr = 39.0 * micronsToCm;
00488 }
00489 else
00490 throw cms::Exception("PixelCPETemplateReco::localError :") << "A non-pixel detector type in here?" ;
00491
00492
00493 return LocalError(xerr*xerr, 0, yerr*yerr);
00494 }
00495 else if ( edgex || edgey )
00496 {
00497
00498 if ( edgex && !edgey )
00499 {
00500 xerr = 23.0 * micronsToCm;
00501 yerr = 39.0 * micronsToCm;
00502 }
00503 else if ( !edgex && edgey )
00504 {
00505 xerr = 24.0 * micronsToCm;
00506 yerr = 96.0 * micronsToCm;
00507 }
00508 else if ( edgex && edgey )
00509 {
00510 xerr = 31.0 * micronsToCm;
00511 yerr = 90.0 * micronsToCm;
00512 }
00513 else
00514 {
00515 throw cms::Exception(" PixelCPETemplateReco::localError: Something wrong with pixel edge flag !!!");
00516 }
00517 }
00518 else
00519 {
00520
00521 const float micronsToCm = 1.0e-4;
00522
00523 xerr = templSigmaX_ * micronsToCm;
00524 yerr = templSigmaY_ * micronsToCm;
00525
00526
00527
00528 }
00529
00530 if (theVerboseLevel > 9)
00531 {
00532 LogDebug("PixelCPETemplateReco") <<
00533 " Sizex = " << cluster.sizeX() << " Sizey = " << cluster.sizeY() << " Edgex = " << edgex << " Edgey = " << edgey <<
00534 " ErrX = " << xerr << " ErrY = " << yerr;
00535 }
00536
00537 return LocalError(xerr*xerr, 0, yerr*yerr);
00538 }
00539