00001 #include "RecoLocalTracker/SiPixelRecHits/interface/PixelCPEGeneric.h"
00002
00003 #include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h"
00004 #include "Geometry/TrackerTopology/interface/RectangularPixelTopology.h"
00005
00006
00007
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "MagneticField/Engine/interface/MagneticField.h"
00010
00011
00012 #include <iostream>
00013 using namespace std;
00014
00015 const double HALF_PI = 1.57079632679489656;
00016
00017
00019
00020 PixelCPEGeneric::PixelCPEGeneric(edm::ParameterSet const & conf,
00021 const MagneticField *mag, const SiPixelLorentzAngle * lorentzAngle)
00022 : PixelCPEBase(conf, mag, lorentzAngle)
00023 {
00024 if (theVerboseLevel > 0)
00025 LogDebug("PixelCPEGeneric")
00026 << " constructing a generic algorithm for ideal pixel detector.\n"
00027 << " CPEGeneric:: VerboseLevel = " << theVerboseLevel;
00028
00029
00030 the_eff_charge_cut_lowX = conf.getUntrackedParameter<double>("eff_charge_cut_lowX");
00031 the_eff_charge_cut_lowY = conf.getUntrackedParameter<double>("eff_charge_cut_lowY");
00032 the_eff_charge_cut_highX = conf.getUntrackedParameter<double>("eff_charge_cut_highX");
00033 the_eff_charge_cut_highY = conf.getUntrackedParameter<double>("eff_charge_cut_highY");
00034 the_size_cutX = conf.getUntrackedParameter<double>("size_cutX");
00035 the_size_cutY = conf.getUntrackedParameter<double>("size_cutY");
00036 }
00037
00038
00039 MeasurementPoint
00040 PixelCPEGeneric::measurementPosition(const SiPixelCluster& cluster,
00041 const GeomDetUnit & det) const
00042 {
00043 LocalPoint lp = localPosition(cluster,det);
00044 return theTopol->measurementPosition(lp);
00045 }
00046
00047
00048
00049
00053
00054 LocalPoint
00055 PixelCPEGeneric::localPosition(const SiPixelCluster& cluster,
00056 const GeomDetUnit & det) const
00057 {
00058 setTheDet( det );
00059 computeLorentzShifts();
00060
00061 float Q_f_X = 0.0;
00062 float Q_l_X = 0.0;
00063 float Q_m_X = 0.0;
00064 float Q_f_Y = 0.0;
00065 float Q_l_Y = 0.0;
00066 float Q_m_Y = 0.0;
00067 collect_edge_charges( cluster,
00068 Q_f_X, Q_l_X, Q_m_X,
00069 Q_f_Y, Q_l_Y, Q_m_Y );
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 MeasurementPoint meas_URcorn_LLpix( cluster.minPixelRow()+1.0,
00080 cluster.minPixelCol()+1.0 );
00081
00082
00083 MeasurementPoint meas_LLcorn_URpix( cluster.maxPixelRow(),
00084 cluster.maxPixelCol() );
00085
00086
00087 LocalPoint local_URcorn_LLpix = theTopol->localPosition(meas_URcorn_LLpix);
00088 LocalPoint local_LLcorn_URpix = theTopol->localPosition(meas_LLcorn_URpix);
00089 if (theVerboseLevel > 20) {
00090 cout
00091 << "\n\t >>> cluster.x = " << cluster.x()
00092 << "\n\t >>> cluster.y = " << cluster.y()
00093 << "\n\t >>> cluster: minRow = " << cluster.minPixelRow()
00094 << " minCol = " << cluster.minPixelCol()
00095 << "\n\t >>> cluster: maxRow = " << cluster.maxPixelRow()
00096 << " maxCol = " << cluster.maxPixelCol()
00097 << "\n\t >>> meas: inner lower left = " << meas_URcorn_LLpix.x()
00098 << "," << meas_URcorn_LLpix.y()
00099 << "\n\t >>> meas: inner upper right = " << meas_LLcorn_URpix.x()
00100 << "," << meas_LLcorn_URpix.y()
00101 << endl;
00102 }
00103
00104
00105
00106
00107
00108 double angle_from_clust = 0;
00109
00110
00111 if (theVerboseLevel > 20)
00112 cout << "\t >>> Generic:: processing X" << endl;
00113 float xPos =
00114 generic_position_formula( cluster.sizeX(),
00115 Q_f_X, Q_l_X,
00116 local_URcorn_LLpix.x(), local_LLcorn_URpix.x(),
00117 0.5*lorentzShiftInCmX_,
00118 cotalpha_,
00119 thePitchX,
00120 theTopol->isItBigPixelInX( cluster.minPixelRow() ),
00121 theTopol->isItBigPixelInX( cluster.maxPixelRow() ),
00122 the_eff_charge_cut_lowX,
00123 the_eff_charge_cut_highX,
00124 the_size_cutX,
00125 cotAlphaFromCluster_ );
00126
00127
00128 if (theVerboseLevel > 20)
00129 cout << "\t >>> Generic:: processing Y" << endl;
00130 float yPos =
00131 generic_position_formula( cluster.sizeY(),
00132 Q_f_Y, Q_l_Y,
00133 local_URcorn_LLpix.y(), local_LLcorn_URpix.y(),
00134 0.5*lorentzShiftInCmY_,
00135 cotbeta_,
00136 thePitchY,
00137 theTopol->isItBigPixelInY( cluster.minPixelCol() ),
00138 theTopol->isItBigPixelInY( cluster.maxPixelCol() ),
00139 the_eff_charge_cut_lowY,
00140 the_eff_charge_cut_highY,
00141 the_size_cutY,
00142 cotBetaFromCluster_ );
00143
00144
00145
00146 LocalPoint pos_in_local(xPos,yPos);
00147 return pos_in_local;
00148 }
00149
00150
00151
00152
00157
00158 double
00159 PixelCPEGeneric::
00160 generic_position_formula( int size,
00161 double Q_f,
00162 double Q_l,
00163 double upper_edge_first_pix,
00164 double lower_edge_last_pix,
00165 double half_lorentz_shift,
00166 double cot_angle,
00167 double pitch,
00168 bool first_is_big,
00169 bool last_is_big,
00170 double eff_charge_cut_low,
00171 double eff_charge_cut_high,
00172 double size_cut,
00173 float & cot_angle_from_length
00174 ) const
00175 {
00176 double geom_center = 0.5 * ( upper_edge_first_pix + lower_edge_last_pix );
00177
00178
00179
00180
00181 if (size == 1) {
00182 return geom_center + half_lorentz_shift;
00183 }
00184
00185
00186
00187
00188 double W_inner = lower_edge_last_pix - upper_edge_first_pix;
00189
00190
00191
00192 double W_pred =
00193 theThickness * cot_angle
00194 - 2 * half_lorentz_shift;
00195
00196
00197
00198 double sum_of_edge = 0.0;
00199 if (first_is_big) sum_of_edge += 2.0;
00200 else sum_of_edge += 1.0;
00201
00202 if (last_is_big) sum_of_edge += 2.0;
00203 else sum_of_edge += 1.0;
00204
00205
00206
00207 double W_eff = fabs( W_pred ) - W_inner;
00208
00209
00210
00211
00212
00213
00214
00215 bool usedEdgeAlgo = false;
00216 if (( W_eff/pitch < eff_charge_cut_low ) ||
00217 ( W_eff/pitch > eff_charge_cut_high ) || (size >= size_cut))
00218 {
00219 W_eff = pitch * 0.5 * sum_of_edge;
00220 usedEdgeAlgo = true;
00221 nRecHitsUsedEdge_++;
00222 }
00223
00224
00225
00226 double Qdiff = Q_l - Q_f;
00227 double Qsum = Q_l + Q_f;
00228 double hit_pos = geom_center + 0.5*(Qdiff/Qsum) * W_eff + half_lorentz_shift;
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 double ave_path_length_projected =
00239 pitch*0.5*sum_of_edge + W_inner - 2*half_lorentz_shift;
00240 cot_angle_from_length = ave_path_length_projected / theThickness;
00241
00242
00243
00244 if (theVerboseLevel > 20) {
00245 if ( thePart == GeomDetEnumerators::PixelBarrel ) {
00246 cout << "\t >>> We are in the Barrel." ;
00247 } else {
00248 cout << "\t >>> We are in the Forward." ;
00249 }
00250 cout
00251 << "\n\t >>> cot(angle) = " << cot_angle << " pitch = " << pitch << " size = " << size
00252 << "\n\t >>> upper_edge_first_pix = " << upper_edge_first_pix
00253 << "\n\t >>> lower_edge_last_pix = " << lower_edge_last_pix
00254 << "\n\t >>> geom_center = " << geom_center
00255 << "\n\t >>> half_lorentz_shift = " << half_lorentz_shift
00256 << "\n\t >>> W_inner = " << W_inner
00257 << "\n\t >>> W_pred = " << W_pred
00258 << "\n\t >>> W_eff(orig) = " << fabs( W_pred ) - W_inner
00259 << "\n\t >>> W_eff(used) = " << W_eff
00260 << "\n\t >>> sum_of_edge = " << sum_of_edge
00261 << "\n\t >>> Qdiff = " << Qdiff << " Qsum = " << Qsum
00262 << "\n\t >>> hit_pos = " << hit_pos
00263 << "\n\t >>> RecHits: total = " << nRecHitsTotal_
00264 << " used edge = " << nRecHitsUsedEdge_
00265 << endl;
00266 if (usedEdgeAlgo)
00267 cout << "\n\t >>> Used Edge algorithm." ;
00268 else
00269 cout << "\n\t >>> Used angle information." ;
00270 cout << endl;
00271 }
00272
00273
00274 return hit_pos;
00275 }
00276
00277
00278
00279
00280
00281
00285
00286 void
00287 PixelCPEGeneric::
00288 collect_edge_charges(const SiPixelCluster& cluster,
00289 float & Q_f_X,
00290 float & Q_l_X,
00291 float & Q_m_X,
00292 float & Q_f_Y,
00293 float & Q_l_Y,
00294 float & Q_m_Y
00295 ) const
00296 {
00297
00298 Q_f_X = Q_l_X = Q_m_X = 0.0;
00299 Q_f_Y = Q_l_Y = Q_m_Y = 0.0;
00300
00301
00302 const vector<SiPixelCluster::Pixel>& pixelsVec = cluster.pixels();
00303
00304
00305 int xmin = cluster.minPixelRow();
00306 int xmax = cluster.maxPixelRow();
00307 int ymin = cluster.minPixelCol();
00308 int ymax = cluster.maxPixelCol();
00309
00310
00311
00312
00313
00314
00315
00316
00317 int isize = pixelsVec.size();
00318 for (int i = 0; i < isize; ++i) {
00319
00320
00321 if (pixelsVec[i].x == xmin)
00322 Q_f_X += float(pixelsVec[i].adc);
00323 else if (pixelsVec[i].x == xmax)
00324 Q_l_X += float(pixelsVec[i].adc);
00325 else
00326 Q_m_X += float(pixelsVec[i].adc);
00327
00328
00329 if (pixelsVec[i].y == ymin)
00330 Q_f_Y += float(pixelsVec[i].adc);
00331 else if (pixelsVec[i].y == ymax)
00332 Q_l_Y += float(pixelsVec[i].adc);
00333 else
00334 Q_m_Y += float(pixelsVec[i].adc);
00335 }
00336
00337 return;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 LocalError
00361 PixelCPEGeneric::localError( const SiPixelCluster& cluster,
00362 const GeomDetUnit & det) const {
00363 setTheDet( det );
00364 int sizex = cluster.sizeX();
00365 int sizey = cluster.sizeY();
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 int maxPixelCol = cluster.maxPixelCol();
00377 int maxPixelRow = cluster.maxPixelRow();
00378 int minPixelCol = cluster.minPixelCol();
00379 int minPixelRow = cluster.minPixelRow();
00380
00381 bool edgex = (theTopol->isItEdgePixelInX(minPixelRow)) ||
00382 (theTopol->isItEdgePixelInX(maxPixelRow));
00383 bool edgey = (theTopol->isItEdgePixelInY(minPixelCol)) ||
00384 (theTopol->isItEdgePixelInY(maxPixelCol));
00385
00386
00387 if (theVerboseLevel > 9) {
00388 LogDebug("PixelCPEGeneric") <<
00389 "Sizex = " << sizex <<
00390 " Sizey = " << sizey <<
00391 " Edgex = " << edgex <<
00392 " Edgey = " << edgey ;
00393 }
00394
00395 return LocalError( err2X(edgex, sizex), 0, err2Y(edgey, sizey) );
00396 }
00397
00398
00399
00400
00401
00402 float
00403 PixelCPEGeneric::err2X(bool& edgex, int& sizex) const
00404 {
00405
00406
00407
00408 float xerr = thePitchX/3.464;
00409
00410
00411
00412
00413 if (!edgex){
00414
00415 if (thePart == GeomDetEnumerators::PixelBarrel) {
00416 if ( sizex == 1) xerr = 0.00115;
00417 else if ( sizex == 2) xerr = 0.0012;
00418 else if ( sizex == 3) xerr = 0.00088;
00419 else xerr = 0.0103;
00420 } else {
00421 if ( sizex == 1) {
00422 xerr = 0.0020;
00423 } else if ( sizex == 2) {
00424 xerr = 0.0020;
00425
00426 } else {
00427 xerr = 0.0020;
00428
00429 }
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 }
00444 return xerr*xerr;
00445 }
00446
00447
00448
00449
00450
00451
00452 float
00453
00454 PixelCPEGeneric::err2Y(bool& edgey, int& sizey) const
00455 {
00456
00457
00458
00459 float yerr = thePitchY/3.464;
00460 if (!edgey){
00461 if (thePart == GeomDetEnumerators::PixelBarrel) {
00462 if ( sizey == 1) {
00463 yerr = 0.00375;
00464 } else if ( sizey == 2) {
00465 yerr = 0.0023;
00466 } else if ( sizey == 3) {
00467 yerr = 0.0025;
00468 } else if ( sizey == 4) {
00469 yerr = 0.0025;
00470 } else if ( sizey == 5) {
00471 yerr = 0.0023;
00472 } else if ( sizey == 6) {
00473 yerr = 0.0023;
00474 } else if ( sizey == 7) {
00475 yerr = 0.0021;
00476 } else if ( sizey == 8) {
00477 yerr = 0.0021;
00478 } else if ( sizey == 9) {
00479 yerr = 0.0024;
00480 } else if ( sizey >= 10) {
00481 yerr = 0.0021;
00482 }
00483 } else {
00484 if ( sizey == 1) yerr = 0.0021;
00485 else if ( sizey >= 2) yerr = 0.00075;
00486 }
00487 }
00488 return yerr*yerr;
00489 }
00490
00491
00492
00493