CMS 3D CMS Logo

PixelCPEInitial.cc

Go to the documentation of this file.
00001 // Move geomCorrection from the base class, modify it. 
00002 // comment out etaCorrection. d.k. 06/06
00003 // change to use Lorentz angle from DB Lotte Wilke, Jan. 31st, 2008
00004 
00005 #include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h"
00006 #include "Geometry/TrackerTopology/interface/RectangularPixelTopology.h"
00007 
00008 #include "RecoLocalTracker/SiPixelRecHits/interface/PixelCPEInitial.h"
00009 
00010 // MessageLogger
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012 // Magnetic field
00013 #include "MagneticField/Engine/interface/MagneticField.h"
00014 
00015 #include <iostream>
00016 
00017 //#define TDEBUG
00018 using namespace std;
00019 
00020 const float PI = 3.141593;
00021 const float degsPerRad = 57.29578;
00022 
00023 //-----------------------------------------------------------------------------
00024 //  A fairly boring constructor.  All quantities are DetUnit-dependent, and
00025 //  will be initialized in setTheDet().
00026 //-----------------------------------------------------------------------------
00027 PixelCPEInitial::PixelCPEInitial(edm::ParameterSet const & conf, const MagneticField *mag, const SiPixelLorentzAngle * lorentzAngle) 
00028   : PixelCPEBase(conf,mag,lorentzAngle)
00029 {
00030 }
00031 
00032 
00033 //------------------------------------------------------------------
00034 //  Public methods mandated by the base class.
00035 //------------------------------------------------------------------
00036 
00037 //------------------------------------------------------------------
00038 //  localError() calls measurementError() after computing size and 
00039 //  edge (flag) along x and y.
00040 //------------------------------------------------------------------
00041 LocalError  
00042 PixelCPEInitial::localError( const SiPixelCluster& cluster, const GeomDetUnit & det)const 
00043 {
00044   setTheDet( det );
00045   int sizex = cluster.sizeX();
00046   int sizey = cluster.sizeY();
00047 
00048   // Find edge clusters
00049   // Use edge methods from the Toplogy class
00050   int maxPixelCol = cluster.maxPixelCol();
00051   int maxPixelRow = cluster.maxPixelRow();
00052   int minPixelCol = cluster.minPixelCol();
00053   int minPixelRow = cluster.minPixelRow();       
00054   // edge method moved to topologu class
00055   bool edgex = (theTopol->isItEdgePixelInX(minPixelRow)) ||
00056     (theTopol->isItEdgePixelInX(maxPixelRow));
00057   bool edgey = (theTopol->isItEdgePixelInY(minPixelCol)) ||
00058     (theTopol->isItEdgePixelInY(maxPixelCol));
00059 
00060   //&&& testing...
00061   if (theVerboseLevel > 9) {
00062     LogDebug("PixelCPEInitial") <<
00063       "Sizex = " << sizex << 
00064       " Sizey = " << sizey << 
00065       " Edgex = " << edgex << 
00066       " Edgey = " << edgey ;
00067   }
00068   //if (sizex>0) return LocalError( sizex, 0, sizey );
00069 
00070   return LocalError( err2X(edgex, sizex), 0, err2Y(edgey, sizey) );
00071 }
00072 
00073 //------------------------------------------------------------------
00074 //  Helper methods (protected)
00075 //------------------------------------------------------------------
00076 
00077 //-----------------------------------------------------------------------------
00078 //  Error along X, squared, as parameterized by Vincenzo.
00079 //-----------------------------------------------------------------------------
00080 float 
00081 PixelCPEInitial::err2X(bool& edgex, int& sizex) const
00082 {
00083 // Assign maximum error
00084   // if edge cluster the maximum error is assigned: Pitch/sqrt(12)=43mu
00085   //  float xerr = 0.0043; 
00086   float xerr = thePitchX/3.464;
00087   //
00088   // Pixels not at the edge: errors parameterized as function of the cluster size
00089   // V.Chiochia - 12/4/06
00090   //
00091   if (!edgex){
00092     //    if (fabs(thePitchX-0.010)<0.001){   // 100um pixel size
00093       if (thePart == GeomDetEnumerators::PixelBarrel) {
00094         if ( sizex == 1) xerr = 0.00115;      // Size = 1 -> Sigma = 11.5 um 
00095         else if ( sizex == 2) xerr = 0.0012;  // Size = 2 -> Sigma = 12 um      
00096         else if ( sizex == 3) xerr = 0.00088; // Size = 3 -> Sigma = 8.8 um
00097         else xerr = 0.0103;
00098       } else { //forward
00099         if ( sizex == 1) {
00100           xerr = 0.0020;
00101         }  else if ( sizex == 2) {
00102           xerr = 0.0020;
00103           // xerr = (0.005351 - atan(fabs(theDetZ/theDetR)) * 0.003291);  
00104         } else {
00105           xerr = 0.0020;
00106           //xerr = (0.003094 - atan(fabs(theDetZ/theDetR)) * 0.001854);  
00107         }
00108       }
00109       //    }
00110 //     }else if (fabs(thePitchX-0.015)<0.001){  // 150 um pixel size
00111 //       if (thePart == GeomDetEnumerators::PixelBarrel) {
00112 //      if ( sizex == 1) xerr = 0.0014;     // 14um 
00113 //      else xerr = 0.0008;   // 8um      
00114 //       } else { //forward
00115 //      if ( sizex == 1) 
00116 //        xerr = (-0.00385 + atan(fabs(theDetZ/theDetR)) * 0.00407);
00117 //      else xerr = (0.00366 - atan(fabs(theDetZ/theDetR)) * 0.00209);  
00118 //       }
00119 //     }
00120 
00121   }
00122   return xerr*xerr;
00123 }
00124 
00125 //-----------------------------------------------------------------------------
00126 //  Error along Y, squared, as parameterized by Vincenzo.
00127 //-----------------------------------------------------------------------------
00128 float 
00129 PixelCPEInitial::err2Y(bool& edgey, int& sizey) const
00130 {
00131 // Assign maximum error
00132 // if edge cluster the maximum error is assigned: Pitch/sqrt(12)=43mu
00133 //  float yerr = 0.0043;
00134   float yerr = thePitchY/3.464; 
00135   if (!edgey){
00136     if (thePart == GeomDetEnumerators::PixelBarrel) { // Barrel
00137       if ( sizey == 1) {
00138         yerr = 0.00375;     // 37.5um 
00139       } else if ( sizey == 2) {
00140         yerr = 0.0023;   // 23 um      
00141       } else if ( sizey == 3) {
00142         yerr = 0.0025; // 25 um
00143       } else if ( sizey == 4) {
00144         yerr = 0.0025; // 25um
00145       } else if ( sizey == 5) {
00146         yerr = 0.0023; // 23um
00147       } else if ( sizey == 6) {
00148         yerr = 0.0023; // 23um
00149       } else if ( sizey == 7) {
00150         yerr = 0.0021; // 21um
00151       } else if ( sizey == 8) {
00152         yerr = 0.0021; // 21um
00153       } else if ( sizey == 9) {
00154         yerr = 0.0024; // 24um
00155       } else if ( sizey >= 10) {
00156         yerr = 0.0021; // 21um
00157       }
00158     } else { // Endcaps
00159       if ( sizey == 1)      yerr = 0.0021; // 21 um
00160       else if ( sizey >= 2) yerr = 0.00075;// 7.5 um
00161     }
00162   }
00163   return yerr*yerr;
00164 }
00165 
00166 //-----------------------------------------------------------------------------
00167 // Position estimate in X-direction
00168 // Copy the code from CPEFromDetPosition
00169 //-----------------------------------------------------------------------------
00170 float 
00171 PixelCPEInitial::xpos(const SiPixelCluster& cluster) const {
00172 
00173   int size = cluster.sizeX();
00174                                                                                 
00175   if (size == 1) {
00176     float baryc = cluster.x();
00177     // the middle of only one pixel is equivalent to the baryc.
00178     // transform baryc to local
00179     return theTopol->localX(baryc);
00180   }
00181  
00182   //calculate center
00183   int imin = cluster.minPixelRow();
00184   int imax = cluster.maxPixelRow();
00185   float min = float(imin) + 0.5; // center of the edge
00186   float max = float(imax) + 0.5; // center of the edge
00187   float minEdge = theTopol->localX(float(imin+1)); // left inner edge
00188   float maxEdge = theTopol->localX(float(imax));   // right inner edge
00189   float center = (minEdge + maxEdge)/2.; // center of inner part
00190   float wInner = maxEdge-minEdge; // width of the inner part
00191    
00192   // get the charge in the edge pixels
00193   const vector<SiPixelCluster::Pixel>& pixelsVec = cluster.pixels();
00194   float q1 = 0.;
00195   float q2 = 0.;
00196   xCharge(pixelsVec, imin, imax, q1, q2); // get q1 and q2
00197    
00198   // Estimate the charge width. main contribution + 2nd order geom corr.
00199   float tmp = (max+min)/2.;
00200   float width = (chargeWidthX() + geomCorrectionX(tmp)) * thePitchX;
00201   
00202   // Check the valid chargewidth (WHY IS THERE THE FABS??)
00203   float effWidth = fabs(width) - wInner;
00204    
00205   // Check the residual width
00206   if( (effWidth>(2*thePitchX)) || (effWidth<0.) ) { // for illiegal wifth
00207     effWidth=thePitchX; // make it equal to pitch
00208   } 
00209 
00210     // For X (no angles) use the MSI formula.
00211   // position msI
00212   float pos = center + (q2-q1)/(2.*(q1+q2)) * effWidth;
00213  
00214   return pos;
00215 
00216 }
00217 //-----------------------------------------------------------------------------
00218 // Position estimate in the local y-direction
00219 //-----------------------------------------------------------------------------
00220 float 
00221 PixelCPEInitial::ypos(const SiPixelCluster& cluster) const {
00222 
00223   int size = cluster.sizeY();
00224  
00225   if (size == 1) {
00226     float baryc = cluster.y();
00227     // the middle of only one pixel is equivalent to the baryc.
00228     // transform baryc to local
00229     return theTopol->localY(baryc);
00230   }
00231  
00232   //calculate center
00233   int imin = cluster.minPixelCol();
00234   int imax = cluster.maxPixelCol();
00235   //float min = float(imin) + 0.5; // center of the edge
00236   //float max = float(imax) + 0.5; // center of the edge
00237   float minEdge = theTopol->localY(float(imin+1)); // left inner edge
00238   float maxEdge = theTopol->localY(float(imax));   // right inner edge
00239   float center = (minEdge + maxEdge)/2.; // center of inner part in LC
00240   //float wInner = maxEdge-minEdge; // width of the inner part in LC
00241    
00242   // get the charge in the edge pixels
00243   const vector<SiPixelCluster::Pixel>& pixelsVec = cluster.pixels();
00244   float q1 = 0.;
00245   float q2 = 0.;
00246   yCharge(pixelsVec, imin, imax, q1, q2);
00247     
00248   float pitch1 = thePitchY;
00249   float pitch2 = thePitchY;
00250   if(RectangularPixelTopology::isItBigPixelInY(imin) )
00251     pitch1= 2.*thePitchY;
00252   if(RectangularPixelTopology::isItBigPixelInY(imax) )
00253     pitch2= 2.*thePitchY;
00254    
00255   // position msII
00256   float pos = center + (q2-q1)/(2.*(q1+q2)) * (pitch1+pitch2)/2.;
00257   return pos;
00258 
00259 }
00260 
00261 //-----------------------------------------------------------------------------
00262 // This is the main contribution to the charge width in the X direction
00263 // Lorentz shift for the barrel and lorentz+geometry for the forward.
00264 //-----------------------------------------------------------------------------
00265 float PixelCPEInitial::chargeWidthX() const { 
00266   float chargeW = 0;
00267   float lorentzWidth = 2 * theLShiftX;
00268   if (thePart == GeomDetEnumerators::PixelBarrel) {
00269     chargeW = lorentzWidth; //  width from Lorentz shift
00270   } else { // forward
00271     chargeW = fabs(lorentzWidth) +                      // Lorentz shift
00272       theThickness * fabs(theDetR/theDetZ) / thePitchX; // + geometry
00273   }
00274   return chargeW;
00275 }
00276 
00277 //-----------------------------------------------------------------------------
00278 // This is the main contribution to the charge width in the Y direction
00279 //-----------------------------------------------------------------------------
00280 float PixelCPEInitial::chargeWidthY() const {
00281   float chargeW = 0;  
00282   float lorentzWidth = 2 * theLShiftY;
00283   if (thePart == GeomDetEnumerators::PixelBarrel) {
00284    // Charge width comes from the geometry (inclined angles)
00285     chargeW = theThickness * fabs(theDetZ/theDetR) / thePitchY;
00286   } else { //forward
00287    // Width comes from geometry only, given by the tilt angle
00288      if ( alpha2Order) {
00289        chargeW = -fabs(lorentzWidth)+ theThickness * tan(20./degsPerRad) / thePitchY;
00290      }else {
00291        chargeW = theThickness * tan(20./degsPerRad) / thePitchY;
00292      }
00293   }
00294   return chargeW;
00295 }
00296 
00297 //-----------------------------------------------------------------------------
00298 // This takes into account that the charge width is not the same across a
00299 // single detector module (sort of a 2nd order effect).
00300 // It makes more sense for the barrel since the barrel module are larger
00301 // and they are placed closer top the IP.
00302 //-----------------------------------------------------------------------------
00303 // Correction for the X-direction
00304 // This is better defined as the IP is well localized in the x-y plane.
00305 float PixelCPEInitial::geomCorrectionX(float xcenter) const {
00306   if (thePart == GeomDetEnumerators::PixelEndcap) return 0;
00307   else {
00308     float tmp = theSign * (theThickness / theDetR) * (xcenter-theOffsetX);
00309     return tmp;
00310   }
00311 }
00312 // Correction for the Y-direction
00313 // This is poorly defined becouse the IP is very smeared along the z direction.
00314 float PixelCPEInitial::geomCorrectionY(float ycenter) const {
00315   if (thePart == GeomDetEnumerators::PixelEndcap) return 0;
00316   else {
00317     float tmp = (ycenter - theOffsetY) * theThickness / theDetR;
00318     if(theDetZ>0.) tmp = -tmp; // it is the opposite for Z>0 and Z<0
00319     return tmp;
00320   }
00321 }
00322  
00323 
00324 

Generated on Tue Jun 9 17:43:59 2009 for CMSSW by  doxygen 1.5.4