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