00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h"
00016 #include "Geometry/TrackerGeometryBuilder/interface/RectangularPixelTopology.h"
00017 #include "Geometry/TrackerGeometryBuilder/interface/ProxyPixelTopology.h"
00018
00019 #include "RecoLocalTracker/SiPixelRecHits/interface/PixelCPEBase.h"
00020
00021
00022 #define CORRECT_FOR_BIG_PIXELS
00023
00024
00025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00026
00027
00028 #include "MagneticField/Engine/interface/MagneticField.h"
00029
00030 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00031 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00032 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00033
00034 #include <iostream>
00035
00036 using namespace std;
00037
00038 const float PI = 3.141593;
00039 const float degsPerRad = 57.29578;
00040
00041
00042
00043
00044
00045 PixelCPEBase::PixelCPEBase(edm::ParameterSet const & conf, const MagneticField *mag, const SiPixelLorentzAngle * lorentzAngle,
00046 const SiPixelCPEGenericErrorParm * genErrorParm, const SiPixelTemplateDBObject * templateDBobject)
00047 : theDet(nullptr), theTopol(nullptr), theRecTopol(nullptr), theParam(nullptr), nRecHitsTotal_(0), nRecHitsUsedEdge_(0),
00048 probabilityX_(0.0), probabilityY_(0.0),
00049 probabilityQ_(0.0), qBin_(0),
00050 isOnEdge_(false), hasBadPixels_(false),
00051 spansTwoROCs_(false), hasFilledProb_(false),
00052 loc_trk_pred_(0.0, 0.0, 0.0, 0.0)
00053 {
00054
00055
00056 lorentzAngle_ = lorentzAngle;
00057
00058
00059 theVerboseLevel =
00060 conf.getUntrackedParameter<int>("VerboseLevel",0);
00061
00062
00063 magfield_ = mag;
00064
00065
00066 genErrorParm_ = genErrorParm;
00067
00068
00069 templateDBobject_ = templateDBobject;
00070
00071
00072 alpha2Order = conf.getParameter<bool>("Alpha2Order");
00073
00074
00075
00076
00077
00078
00079
00080 clusterProbComputationFlag_
00081 = (unsigned int) conf.getParameter<int>("ClusterProbComputationFlag");
00082
00083 }
00084
00085
00086
00087
00088 void
00089 PixelCPEBase::setTheDet( const GeomDetUnit & det, const SiPixelCluster & cluster ) const
00090 {
00091 if ( theDet == &det )
00092 return;
00093
00094
00095 theDet = dynamic_cast<const PixelGeomDetUnit*>( &det );
00096
00097 if ( !theDet )
00098 {
00099 throw cms::Exception(" PixelCPEBase::setTheDet : ")
00100 << " Wrong pointer to PixelGeomDetUnit object !!!";
00101 }
00102
00103
00104 thePart = theDet->type().subDetector();
00105 switch ( thePart )
00106 {
00107 case GeomDetEnumerators::PixelBarrel:
00108
00109 break;
00110 case GeomDetEnumerators::PixelEndcap:
00111
00112 break;
00113 default:
00114 throw cms::Exception("PixelCPEBase::setTheDet :")
00115 << "PixelCPEBase: A non-pixel detector type in here?" ;
00116 }
00117
00118
00119
00120
00121
00122 theDetR = theDet->surface().position().perp();
00123 theDetZ = theDet->surface().position().z();
00124
00125
00126
00127 theThickness = theDet->surface().bounds().thickness();
00128
00129
00130
00131
00132
00133
00134 auto topol = &(theDet->specificTopology());
00135 if unlikely(topol!=theTopol) {
00136 theTopol=topol;
00137 auto const proxyT = dynamic_cast<const ProxyPixelTopology*>(theTopol);
00138 if (proxyT) theRecTopol = dynamic_cast<const RectangularPixelTopology*>(&(proxyT->specificTopology()));
00139 else theRecTopol = dynamic_cast<const RectangularPixelTopology*>(theTopol);
00140 assert(theRecTopol);
00141
00142
00143 theNumOfRow = theRecTopol->nrows();
00144 theNumOfCol = theRecTopol->ncolumns();
00145 std::pair<float,float> pitchxy = theRecTopol->pitch();
00146 thePitchX = pitchxy.first;
00147 thePitchY = pitchxy.second;
00148 }
00149
00150 theSign = isFlipped() ? -1 : 1;
00151
00152
00153
00154 theParam = ¶m();
00155
00156
00157 driftDirection_ = (*theParam).drift;
00158
00159
00160
00161 theLShiftX = lorentzShiftX();
00162
00163 theLShiftY = lorentzShiftY();
00164
00165
00166 if(thePart == GeomDetEnumerators::PixelBarrel) {
00167
00168 theLShiftY=0.;
00169 }
00170
00171
00172 int minInX,minInY,maxInX,maxInY=0;
00173 minInX = cluster.minPixelRow();
00174 minInY = cluster.minPixelCol();
00175 maxInX = cluster.maxPixelRow();
00176 maxInY = cluster.maxPixelCol();
00177
00178 if(theRecTopol->isItEdgePixelInX(minInX) || theRecTopol->isItEdgePixelInX(maxInX) ||
00179 theRecTopol->isItEdgePixelInY(minInY) || theRecTopol->isItEdgePixelInY(maxInY) ) {
00180 isOnEdge_ = true;
00181 }
00182 else isOnEdge_ = false;
00183
00184
00185 hasBadPixels_ = false;
00186 for(unsigned int i=0; i<cluster.pixelADC().size(); ++i) {
00187 if(cluster.pixelADC()[i] == 0) hasBadPixels_ = true;
00188 }
00189
00190 if(theRecTopol->containsBigPixelInX(minInX,maxInX) ||
00191 theRecTopol->containsBigPixelInY(minInY,maxInY) ) {
00192 spansTwoROCs_ = true;
00193 }
00194 else spansTwoROCs_ = false;
00195
00196
00197 if (theVerboseLevel > 1)
00198 {
00199 LogDebug("PixelCPEBase") << "***** PIXEL LAYOUT *****"
00200 << " thePart = " << thePart
00201 << " theThickness = " << theThickness
00202 << " thePitchX = " << thePitchX
00203 << " thePitchY = " << thePitchY
00204
00205
00206 << " theLShiftX = " << theLShiftX;
00207 }
00208
00209 }
00210
00211
00212
00213
00214
00215
00216 void PixelCPEBase::
00217 computeAnglesFromTrajectory( const SiPixelCluster & cl,
00218 const GeomDetUnit & det,
00219 const LocalTrajectoryParameters & ltp) const
00220 {
00221 loc_traj_param_ = ltp;
00222
00223 LocalVector localDir = ltp.momentum()/ltp.momentum().mag();
00224
00225
00226
00227
00228
00229 float locx = localDir.x();
00230 float locy = localDir.y();
00231 float locz = localDir.z();
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 alpha_ = atan2( locz, locx );
00244 beta_ = atan2( locz, locy );
00245
00246 cotalpha_ = locx/locz;
00247 cotbeta_ = locy/locz;
00248
00249 LocalPoint trk_lp = ltp.position();
00250 trk_lp_x = trk_lp.x();
00251 trk_lp_y = trk_lp.y();
00252
00253 with_track_angle = true;
00254
00255
00256
00257 AlgebraicVector5 vec_trk_parameters = ltp.mixedFormatVector();
00258
00259 loc_trk_pred_ = Topology::LocalTrackPred( vec_trk_parameters );
00260
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 LocalPoint
00281 PixelCPEBase::localPosition( const SiPixelCluster& cluster,
00282 const GeomDetUnit & det) const {
00283 setTheDet( det, cluster );
00284
00285 float lpx = xpos(cluster);
00286 float lpy = ypos(cluster);
00287 float lxshift = theLShiftX * thePitchX;
00288 float lyshift = theLShiftY * thePitchY;
00289 LocalPoint cdfsfs(lpx-lxshift, lpy-lyshift);
00290 return cdfsfs;
00291 }
00292
00293
00294
00295
00296 MeasurementPoint
00297 PixelCPEBase::measurementPosition( const SiPixelCluster& cluster,
00298 const GeomDetUnit & det) const {
00299
00300 LocalPoint lp = localPosition(cluster,det);
00301
00302
00303
00304 if ( with_track_angle )
00305 return theTopol->measurementPosition( lp, Topology::LocalTrackAngles( loc_traj_param_.dxdz(), loc_traj_param_.dydz() ) );
00306 else
00307 return theTopol->measurementPosition( lp );
00308
00309 }
00310
00311
00312
00313
00314
00315
00316
00317 MeasurementError
00318 PixelCPEBase::measurementError( const SiPixelCluster& cluster, const GeomDetUnit & det) const
00319 {
00320 LocalPoint lp( localPosition(cluster, det) );
00321 LocalError le( localError( cluster, det) );
00322
00323
00324 if ( with_track_angle )
00325 return theTopol->measurementError( lp, le, Topology::LocalTrackAngles( loc_traj_param_.dxdz(), loc_traj_param_.dydz() ) );
00326 else
00327 return theTopol->measurementError( lp, le );
00328 }
00329
00330
00331
00332
00333
00334
00335
00336 void PixelCPEBase::
00337 computeAnglesFromDetPosition(const SiPixelCluster & cl,
00338 const GeomDetUnit & det ) const
00339 {
00340
00341 theDet = dynamic_cast<const PixelGeomDetUnit*>( &det );
00342 if ( ! theDet )
00343 {
00344 throw cms::Exception("PixelCPEBase::computeAngleFromDetPosition")
00345 << " Wrong pointer to pixel detector !!!" << endl;
00346
00347 }
00348
00349
00350 float xcenter = cl.x();
00351 float ycenter = cl.y();
00352
00353
00354
00355
00356
00357 LocalPoint lp = theTopol->localPosition( MeasurementPoint(xcenter, ycenter) );
00358
00359
00360
00361 GlobalPoint gp = theDet->surface().toGlobal( lp );
00362 float gp_mod = sqrt( gp.x()*gp.x() + gp.y()*gp.y() + gp.z()*gp.z() );
00363
00364
00365 float gpx = gp.x()/gp_mod;
00366 float gpy = gp.y()/gp_mod;
00367 float gpz = gp.z()/gp_mod;
00368
00369
00370
00371 GlobalVector gv(gpx, gpy, gpz);
00372
00373
00374 const Local3DVector lvx(1.0, 0.0, 0.0);
00375
00376
00377 GlobalVector gvx = theDet->surface().toGlobal( lvx );
00378
00379
00380 const Local3DVector lvy(0.0, 1.0, 0.0);
00381
00382
00383 GlobalVector gvy = theDet->surface().toGlobal( lvy );
00384
00385
00386 const Local3DVector lvz(0.0, 0.0, 1.0);
00387
00388
00389 GlobalVector gvz = theDet->surface().toGlobal( lvz );
00390
00391
00392
00393
00394 float gv_dot_gvx = gv.x()*gvx.x() + gv.y()*gvx.y() + gv.z()*gvx.z();
00395 float gv_dot_gvy = gv.x()*gvy.x() + gv.y()*gvy.y() + gv.z()*gvy.z();
00396 float gv_dot_gvz = gv.x()*gvz.x() + gv.y()*gvz.y() + gv.z()*gvz.z();
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 alpha_ = atan2( gv_dot_gvz, gv_dot_gvx );
00410 beta_ = atan2( gv_dot_gvz, gv_dot_gvy );
00411
00412 cotalpha_ = gv_dot_gvx / gv_dot_gvz;
00413 cotbeta_ = gv_dot_gvy / gv_dot_gvz;
00414
00415 with_track_angle = false;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 bool PixelCPEBase::isFlipped() const
00433 {
00434
00435 float tmp1 = theDet->surface().toGlobal(Local3DPoint(0.,0.,0.)).perp2();
00436 float tmp2 = theDet->surface().toGlobal(Local3DPoint(0.,0.,1.)).perp2();
00437
00438 if ( tmp2<tmp1 ) return true;
00439 else return false;
00440 }
00441
00442 PixelCPEBase::Param const & PixelCPEBase::param() const {
00443 Param & p = m_Params[ theDet->geographicalId().rawId() ];
00444 if unlikely ( p.bz<-1.e10f ) {
00445 LocalVector Bfield = theDet->surface().toLocal(magfield_->inTesla(theDet->surface().position()));
00446 p.drift = driftDirection(Bfield );
00447 p.bz = Bfield.z();
00448 }
00449 return p;
00450 }
00451
00452
00453
00454
00455
00456
00457
00458 float PixelCPEBase::lorentzShiftX() const
00459 {
00460 LocalVector dir = getDrift();
00461
00462
00463 float xdrift = dir.x()/dir.z() * theThickness;
00464
00465
00466 float lshift = xdrift / (thePitchX*2.);
00467
00468 return lshift;
00469
00470
00471 }
00472
00473 float PixelCPEBase::lorentzShiftY() const
00474 {
00475
00476 LocalVector dir = getDrift();
00477
00478 float ydrift = dir.y()/dir.z() * theThickness;
00479 float lshift = ydrift / (thePitchY * 2.f);
00480 return lshift;
00481
00482
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 LocalVector
00497 PixelCPEBase::driftDirection( GlobalVector bfield ) const {
00498
00499 Frame detFrame(theDet->surface().position(), theDet->surface().rotation());
00500 LocalVector Bfield = detFrame.toLocal(bfield);
00501 return driftDirection(Bfield);
00502
00503 }
00504
00505 LocalVector
00506 PixelCPEBase::driftDirection( LocalVector Bfield ) const {
00507
00508 if(lorentzAngle_ == 0){
00509 throw cms::Exception("invalidPointer") << "[PixelCPEBase::driftDirection] zero pointer to lorentz angle record ";
00510 }
00511 double langle = lorentzAngle_->getLorentzAngle(theDet->geographicalId().rawId());
00512 float alpha2;
00513 if (alpha2Order) {
00514 alpha2 = langle*langle;
00515 } else {
00516 alpha2 = 0.0;
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526 float dir_x = ( langle * Bfield.y() + alpha2* Bfield.z()* Bfield.x() );
00527 float dir_y = -( langle * Bfield.x() - alpha2* Bfield.z()* Bfield.y() );
00528 float dir_z = -( 1.f + alpha2* Bfield.z()*Bfield.z() );
00529 double scale = 1.f/std::abs( dir_z );
00530 LocalVector dd(dir_x*scale, dir_y*scale, -1.f );
00531 if ( theVerboseLevel > 9 )
00532 LogDebug("PixelCPEBase") << " The drift direction in local coordinate is "
00533 << dd ;
00534
00535 return dd;
00536 }
00537
00538
00539
00540
00541 void
00542 PixelCPEBase::computeLorentzShifts() const
00543 {
00544
00545 driftDirection_ = getDrift();
00546
00547
00548 lorentzShiftInCmX_ = -driftDirection_.x()/driftDirection_.z() * theThickness;
00549
00550 lorentzShiftX_ = lorentzShiftInCmX_ / thePitchX ;
00551
00552
00553 lorentzShiftInCmY_ = -driftDirection_.y()/driftDirection_.z() * theThickness;
00554
00555 lorentzShiftY_ = lorentzShiftInCmY_ / thePitchY;
00556
00557
00558 if ( theVerboseLevel > 9 ) {
00559 LogDebug("PixelCPEBase") << " The drift direction in local coordinate is "
00560 << driftDirection_ ;
00561
00562 }
00563 }
00564
00565
00570
00571 SiPixelRecHitQuality::QualWordType
00572 PixelCPEBase::rawQualityWord() const
00573 {
00574 SiPixelRecHitQuality::QualWordType qualWord(0);
00575
00576 SiPixelRecHitQuality::thePacking.setProbabilityXY ( probabilityXY() ,
00577 qualWord );
00578
00579 SiPixelRecHitQuality::thePacking.setProbabilityQ ( probabilityQ_ ,
00580 qualWord );
00581
00582 SiPixelRecHitQuality::thePacking.setQBin ( (int)qBin_,
00583 qualWord );
00584
00585 SiPixelRecHitQuality::thePacking.setIsOnEdge ( isOnEdge_,
00586 qualWord );
00587
00588 SiPixelRecHitQuality::thePacking.setHasBadPixels ( hasBadPixels_,
00589 qualWord );
00590
00591 SiPixelRecHitQuality::thePacking.setSpansTwoROCs ( spansTwoROCs_,
00592 qualWord );
00593
00594 SiPixelRecHitQuality::thePacking.setHasFilledProb ( hasFilledProb_,
00595 qualWord );
00596
00597 return qualWord;
00598 }