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 MeasurementPoint
00106 PixelCPETemplateReco::measurementPosition(const SiPixelCluster& cluster,
00107 const GeomDetUnit & det) const
00108 {
00109 LocalPoint lp = localPosition(cluster,det);
00110
00111
00112 if ( with_track_angle )
00113 return theTopol->measurementPosition(lp, Topology::LocalTrackAngles( loc_traj_param_.dxdz(), loc_traj_param_.dydz() ) );
00114 else
00115 {
00116 edm::LogError("PixelCPETemplateReco")
00117 << "@SUB = PixelCPETemplateReco::measurementPosition"
00118 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00119
00120 return theTopol->measurementPosition( lp );
00121 }
00122
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 LocalPoint
00134 PixelCPETemplateReco::localPosition(const SiPixelCluster& cluster, const GeomDetUnit & det) const
00135 {
00136 setTheDet( det, cluster );
00137
00138 bool fpix;
00139 if ( thePart == GeomDetEnumerators::PixelBarrel )
00140 fpix = false;
00141 else
00142 fpix = true;
00143
00144 int ID = -9999;
00145
00146 if ( LoadTemplatesFromDB_ )
00147 {
00148 ID = templateDBobject_->getTemplateID(theDet->geographicalId());
00149 }
00150 else
00151 {
00152 if ( !fpix )
00153 ID = 40;
00154 else
00155 ID = 41;
00156 }
00157
00158
00159
00160
00161
00162
00163 boost::multi_array<float, 2> clust_array_2d(boost::extents[cluster_matrix_size_x][cluster_matrix_size_y]);
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 int row_offset = cluster.minPixelRow();
00174 int col_offset = cluster.minPixelCol();
00175
00176
00177
00178
00179 float tmp_x = float(cluster.minPixelRow()) + 0.5;
00180 float tmp_y = float(cluster.minPixelCol()) + 0.5;
00181
00182
00183
00184
00185
00186 LocalPoint lp;
00187
00188 if ( with_track_angle )
00189 lp = theTopol->localPosition( MeasurementPoint(tmp_x, tmp_y), loc_trk_pred_ );
00190 else
00191 {
00192 edm::LogError("PixelCPETemplateReco")
00193 << "@SUB = PixelCPETemplateReco::localPosition"
00194 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00195
00196 lp = theTopol->localPosition( MeasurementPoint(tmp_x, tmp_y) );
00197 }
00198
00199 const std::vector<SiPixelCluster::Pixel> & pixVec = cluster.pixels();
00200 std::vector<SiPixelCluster::Pixel>::const_iterator
00201 pixIter = pixVec.begin(), pixEnd = pixVec.end();
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 for ( ; pixIter != pixEnd; ++pixIter )
00237 {
00238
00239
00240
00241
00242 int irow = int(pixIter->x) - row_offset;
00243 int icol = int(pixIter->y) - col_offset;
00244
00245
00246
00247 if ( irow<cluster_matrix_size_x && icol<cluster_matrix_size_y )
00248
00249 clust_array_2d[irow][icol] = (float)pixIter->adc;
00250 }
00251
00252
00253 std::vector<bool> ydouble(cluster_matrix_size_y), xdouble(cluster_matrix_size_x);
00254
00255 for (int irow = 0; irow < cluster_matrix_size_x; ++irow)
00256 {
00257 xdouble[irow] = theTopol->isItBigPixelInX( irow+row_offset );
00258 }
00259
00260
00261 for (int icol = 0; icol < cluster_matrix_size_y; ++icol)
00262 {
00263 ydouble[icol] = theTopol->isItBigPixelInY( icol+col_offset );
00264 }
00265
00266
00267 float nonsense = -99999.9;
00268 templXrec_ = templYrec_ = templSigmaX_ = templSigmaY_ = nonsense;
00269
00270 templProbY_ = templProbX_ = templProbQ_ = 1.0;
00271 templQbin_ = 0;
00272
00273 hasFilledProb_ = false;
00274
00275 float templYrec1_ = nonsense;
00276 float templXrec1_ = nonsense;
00277 float templYrec2_ = nonsense;
00278 float templXrec2_ = nonsense;
00279
00280
00281
00282
00283 GlobalVector bfield = magfield_->inTesla( theDet->surface().position() );
00284
00285 Frame detFrame( theDet->surface().position(), theDet->surface().rotation() );
00286 LocalVector Bfield = detFrame.toLocal( bfield );
00287 float locBz = Bfield.z();
00288
00289 ierr =
00290 PixelTempReco2D( ID, cotalpha_, cotbeta_,
00291 locBz,
00292 clust_array_2d, ydouble, xdouble,
00293 templ_,
00294 templYrec_, templSigmaY_, templProbY_,
00295 templXrec_, templSigmaX_, templProbX_,
00296 templQbin_,
00297 speed_,
00298 templProbQ_
00299 );
00300
00301
00302
00303
00304 if ( ierr != 0 )
00305 {
00306 LogDebug("PixelCPETemplateReco::localPosition") <<
00307 "reconstruction failed with error " << ierr << "\n";
00308
00309
00310
00311
00312 double lorentz_drift = -999.9;
00313 if ( thePart == GeomDetEnumerators::PixelBarrel )
00314 lorentz_drift = 60.0;
00315 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00316 lorentz_drift = 10.0;
00317 else
00318 throw cms::Exception("PixelCPETemplateReco::localPosition :")
00319 << "A non-pixel detector type in here?" << "\n";
00320
00321 if ( with_track_angle )
00322 {
00323 templXrec_ = theTopol->localX( cluster.x(), loc_trk_pred_ ) - lorentz_drift * micronsToCm;
00324 templYrec_ = theTopol->localY( cluster.y(), loc_trk_pred_ );
00325 }
00326 else
00327 {
00328 edm::LogError("PixelCPETemplateReco")
00329 << "@SUB = PixelCPETemplateReco::localPosition"
00330 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00331
00332 templXrec_ = theTopol->localX( cluster.x() ) - lorentz_drift * micronsToCm;
00333 templYrec_ = theTopol->localY( cluster.y() );
00334 }
00335 }
00336 else if ( UseClusterSplitter_ && templQbin_ == 0 )
00337 {
00338 cout << " PixelCPETemplateReco : We should never be here !!!!!!!!!!!!!!!!!!!!!!" << endl;
00339 cout << " (int)UseClusterSplitter_ = " << (int)UseClusterSplitter_ << endl;
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 float dchisq;
00351 float templProbQ_;
00352 SiPixelTemplate2D templ2D_;
00353 templ2D_.pushfile(ID);
00354
00355 ierr =
00356 SiPixelTemplateSplit::PixelTempSplit( ID, cotalpha_, cotbeta_,
00357 clust_array_2d,
00358 ydouble, xdouble,
00359 templ_,
00360 templYrec1_, templYrec2_, templSigmaY_, templProbY_,
00361 templXrec1_, templXrec2_, templSigmaX_, templProbX_,
00362 templQbin_,
00363 templProbQ_,
00364 true,
00365 dchisq,
00366 templ2D_ );
00367
00368
00369 if ( ierr != 0 )
00370 {
00371 LogDebug("PixelCPETemplateReco::localPosition") <<
00372 "reconstruction failed with error " << ierr << "\n";
00373
00374
00375
00376
00377 double lorentz_drift = -999.9;
00378 if ( thePart == GeomDetEnumerators::PixelBarrel )
00379 lorentz_drift = 60.0;
00380 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00381 lorentz_drift = 10.0;
00382 else
00383 throw cms::Exception("PixelCPETemplateReco::localPosition :")
00384 << "A non-pixel detector type in here?" << "\n";
00385
00386
00387 if ( with_track_angle )
00388 {
00389 templXrec_ = theTopol->localX( cluster.x(),loc_trk_pred_ ) - lorentz_drift * micronsToCm;
00390 templYrec_ = theTopol->localY( cluster.y(),loc_trk_pred_ );
00391 }
00392 else
00393 {
00394 edm::LogError("PixelCPETemplateReco")
00395 << "@SUB = PixelCPETemplateReco::localPosition"
00396 << "Should never be here. PixelCPETemplateReco should always be called with track angles. This is a bad error !!! ";
00397
00398 templXrec_ = theTopol->localX( cluster.x() ) - lorentz_drift * micronsToCm;
00399 templYrec_ = theTopol->localY( cluster.y() );
00400
00401 }
00402 }
00403 else
00404 {
00405
00406 templXrec1_ *= micronsToCm;
00407 templYrec1_ *= micronsToCm;
00408 templXrec2_ *= micronsToCm;
00409 templYrec2_ *= micronsToCm;
00410
00411
00412 templXrec1_ += lp.x();
00413 templYrec1_ += lp.y();
00414 templXrec2_ += lp.x();
00415 templYrec2_ += lp.y();
00416
00417
00418
00419 float distance11 = sqrt( (templXrec1_ - trk_lp_x)*(templXrec1_ - trk_lp_x) +
00420 (templYrec1_ - trk_lp_y)*(templYrec1_ - trk_lp_y) );
00421
00422 float distance12 = sqrt( (templXrec1_ - trk_lp_x)*(templXrec1_ - trk_lp_x) +
00423 (templYrec2_ - trk_lp_y)*(templYrec2_ - trk_lp_y) );
00424
00425 float distance21 = sqrt( (templXrec2_ - trk_lp_x)*(templXrec2_ - trk_lp_x) +
00426 (templYrec1_ - trk_lp_y)*(templYrec1_ - trk_lp_y) );
00427
00428 float distance22 = sqrt( (templXrec2_ - trk_lp_x)*(templXrec2_ - trk_lp_x) +
00429 (templYrec2_ - trk_lp_y)*(templYrec2_ - trk_lp_y) );
00430
00431 float min_templXrec_ = -999.9;
00432 float min_templYrec_ = -999.9;
00433 float distance_min = 9999999999.9;
00434 if ( distance11 < distance_min )
00435 {
00436 distance_min = distance11;
00437 min_templXrec_ = templXrec1_;
00438 min_templYrec_ = templYrec1_;
00439 }
00440 if ( distance12 < distance_min )
00441 {
00442 distance_min = distance12;
00443 min_templXrec_ = templXrec1_;
00444 min_templYrec_ = templYrec2_;
00445 }
00446 if ( distance21 < distance_min )
00447 {
00448 distance_min = distance21;
00449 min_templXrec_ = templXrec2_;
00450 min_templYrec_ = templYrec1_;
00451 }
00452 if ( distance22 < distance_min )
00453 {
00454 distance_min = distance22;
00455 min_templXrec_ = templXrec2_;
00456 min_templYrec_ = templYrec2_;
00457 }
00458
00459 templXrec_ = min_templXrec_;
00460 templYrec_ = min_templYrec_;
00461 }
00462 }
00463 else
00464 {
00465
00466 templXrec_ *= micronsToCm;
00467 templYrec_ *= micronsToCm;
00468
00469
00470 templXrec_ += lp.x();
00471 templYrec_ += lp.y();
00472 }
00473
00474
00475
00476 probabilityX_ = templProbX_;
00477 probabilityY_ = templProbY_;
00478 probabilityQ_ = templProbQ_;
00479 qBin_ = templQbin_;
00480
00481 if ( ierr == 0 )
00482 hasFilledProb_ = true;
00483
00484 LocalPoint template_lp = LocalPoint( nonsense, nonsense );
00485 template_lp = LocalPoint( templXrec_, templYrec_ );
00486
00487 return template_lp;
00488
00489 }
00490
00491
00492
00493
00494 LocalError
00495 PixelCPETemplateReco::localError( const SiPixelCluster& cluster,
00496 const GeomDetUnit& det ) const
00497 {
00498
00499
00500
00501
00502
00503
00504 float xerr = thePitchX / sqrt(12.0);
00505 float yerr = thePitchY / sqrt(12.0);
00506
00507
00508 if ( cluster.getSplitClusterErrorX() > 0.0 && cluster.getSplitClusterErrorX() < 7777.7 &&
00509 cluster.getSplitClusterErrorY() > 0.0 && cluster.getSplitClusterErrorY() < 7777.7 )
00510 {
00511 xerr = cluster.getSplitClusterErrorX() * micronsToCm;
00512 yerr = cluster.getSplitClusterErrorY() * micronsToCm;
00513
00514
00515
00516
00517 }
00518 else
00519 {
00520
00521
00522
00523
00524 setTheDet( det, cluster );
00525
00526 int maxPixelCol = cluster.maxPixelCol();
00527 int maxPixelRow = cluster.maxPixelRow();
00528 int minPixelCol = cluster.minPixelCol();
00529 int minPixelRow = cluster.minPixelRow();
00530
00531
00532 bool edgex = ( theTopol->isItEdgePixelInX( minPixelRow ) || theTopol->isItEdgePixelInX( maxPixelRow ) );
00533 bool edgey = ( theTopol->isItEdgePixelInY( minPixelCol ) || theTopol->isItEdgePixelInY( maxPixelCol ) );
00534
00535 if ( ierr !=0 )
00536 {
00537
00538
00539
00540
00541
00542
00543 if ( thePart == GeomDetEnumerators::PixelBarrel )
00544 {
00545 xerr = 55.0 * micronsToCm;
00546 yerr = 36.0 * micronsToCm;
00547 }
00548 else if ( thePart == GeomDetEnumerators::PixelEndcap )
00549 {
00550 xerr = 42.0 * micronsToCm;
00551 yerr = 39.0 * micronsToCm;
00552 }
00553 else
00554 throw cms::Exception("PixelCPETemplateReco::localError :") << "A non-pixel detector type in here?" ;
00555
00556
00557
00558
00559
00560 }
00561 else if ( edgex || edgey )
00562 {
00563
00564 if ( edgex && !edgey )
00565 {
00566 xerr = 23.0 * micronsToCm;
00567 yerr = 39.0 * micronsToCm;
00568 }
00569 else if ( !edgex && edgey )
00570 {
00571 xerr = 24.0 * micronsToCm;
00572 yerr = 96.0 * micronsToCm;
00573 }
00574 else if ( edgex && edgey )
00575 {
00576 xerr = 31.0 * micronsToCm;
00577 yerr = 90.0 * micronsToCm;
00578 }
00579 else
00580 {
00581 throw cms::Exception(" PixelCPETemplateReco::localError: Something wrong with pixel edge flag !!!");
00582 }
00583
00584
00585
00586 }
00587 else
00588 {
00589
00590
00591
00592 xerr = templSigmaX_ * micronsToCm;
00593 yerr = templSigmaY_ * micronsToCm;
00594
00595
00596
00597
00598
00599
00600 }
00601
00602 if (theVerboseLevel > 9)
00603 {
00604 LogDebug("PixelCPETemplateReco") <<
00605 " Sizex = " << cluster.sizeX() << " Sizey = " << cluster.sizeY() << " Edgex = " << edgex << " Edgey = " << edgey <<
00606 " ErrX = " << xerr << " ErrY = " << yerr;
00607 }
00608
00609 }
00610
00611 if ( !(xerr > 0.0) )
00612 throw cms::Exception("PixelCPETemplateReco::localError")
00613 << "\nERROR: Negative pixel error xerr = " << xerr << "\n\n";
00614
00615 if ( !(yerr > 0.0) )
00616 throw cms::Exception("PixelCPETemplateReco::localError")
00617 << "\nERROR: Negative pixel error yerr = " << yerr << "\n\n";
00618
00619
00620
00621
00622
00623
00624
00625 return LocalError(xerr*xerr, 0, yerr*yerr);
00626 }
00627