CMS 3D CMS Logo

StripCPEfromTrackAngle2.cc

Go to the documentation of this file.
00001 #include <memory>
00002 #include <string>
00003 #include <iostream>
00004 #include "RecoLocalTracker/SiStripRecHitConverter/interface/StripCPEfromTrackAngle2.h"
00005 #include "Geometry/CommonTopologies/interface/StripTopology.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include <algorithm>
00008 
00009 using namespace std;
00010 
00011 StripClusterParameterEstimator::LocalValues StripCPEfromTrackAngle2::localParameters( const SiStripCluster & cl,const LocalTrajectoryParameters & ltp)const{
00012 
00013   //
00014   // get the det from the geometry
00015   //
00016 
00017   //cout<<"StripCPEfromTrackAngle2 NEW"<<endl;
00018 
00019   StripCPE::Param const & p = param(DetId(cl.geographicalId()));
00020   
00021   LocalPoint middlepoint = ltp.position();
00022   LocalVector atrackUnit = ltp.momentum()/ltp.momentum().mag();
00023 
00024 
00025   LocalPoint  position = p.topology->localPosition(cl.barycenter());
00026   
00027   
00028   LocalVector trackDir = atrackUnit;
00029       
00030   if(p.drift.z() == 0.) {
00031     edm::LogError("StripCPE") <<"No drift towards anodes !!!";
00032     LocalError eresult = p.topology->localError(cl.barycenter(),1/12.);
00033     return std::make_pair(position-p.drift*(p.thickness/2),eresult);
00034   }      
00035 
00036   if(trackDir.z()*p.drift.z() > 0.) trackDir *= -1.;
00037 
00038   if(trackDir.z() !=0.) {
00039     trackDir *= fabs(p.thickness/trackDir.z());
00040   } else {
00041     trackDir *= p.maxLength/trackDir.mag();
00042   }
00043 
00044   // covered length along U
00045       
00046   LocalVector middleOfProjection = 0.5*(trackDir + p.drift);
00047 
00048   LocalPoint middlePointOnStrips = middlepoint + 0.5*p.drift;
00049 
00050   LocalPoint p1 = LocalPoint(middlePointOnStrips.x() + middleOfProjection.x()
00051                              ,middlePointOnStrips.y() + middleOfProjection.y());
00052   LocalPoint p2 = LocalPoint(middlePointOnStrips.x() - middleOfProjection.x()
00053                              ,middlePointOnStrips.y() - middleOfProjection.y());
00054 
00055   MeasurementPoint m1 = p.topology->measurementPosition(p1);
00056   MeasurementPoint m2 = p.topology->measurementPosition(p2);
00057   float u1 = m1.x();
00058   float u2 = m2.x();
00059   float uProj = std::min( float(fabs( u1 - u2)), float(p.nstrips));
00060 
00061   int clusterWidth ;
00062   clusterWidth = cl.amplitudes().size();
00063 
00064   int expectedWidth;
00065   if (u1<u2) expectedWidth = 1 + int(u2) -int(u1);
00066   if (u1>u2) expectedWidth = 1 + int(u1) -int(u2);
00067   if (u1==u2) expectedWidth = 1;
00068   //  expectedWidth = 1 + int(u2) -int(u1);
00069 
00070 
00071   // Coefficients P0, P1 & P2 of quadratic parametrization of 
00072   // resolution in terms of track width.
00073   // The "nbin" bins each correspond to different classes of clusters that
00074   // need different parametrizations (iopt=0,1,2 below).
00075 
00076   float projectionOnU ;
00077   projectionOnU = uProj;
00078   const unsigned int nbins = 3;
00079   //const float P0[nbins] =  { 0.329,   0.069,   0.549};
00080   //const float P1[nbins] =  {-0.088,   0.049,  -0.619};
00081   //const float P2[nbins] =  {-0.115,   0.004,   0.282};
00082 
00083   // Good param
00084   /*
00085   const float P0[nbins] =  {2.45226e-01,9.09088e-02, 2.43403e-01 };
00086   const float P1[nbins] =  {-3.50310e-02,-1.37922e-02,-1.93286e-01  };
00087   const float P2[nbins] =  {-1.14758e-01,1.31774e-02,7.68252e-02};
00088   */
00089   const float P0[nbins] =  {2.62868e-01 ,2.07353e-01,2.56743e-01};//best
00090   const float P1[nbins] =  {-1.11246e-01 ,-1.44337e-01,-1.84289e-01};//best
00091   const float P2[nbins] =  {-3.86084e-02,4.76344e-02,6.69619e-02};//best
00092   //
00093 
00094     //
00095   const float minError = 0.1;
00096 
00097   // Coefficients of linear parametrization in terms of cluster
00098   // width that is used for bad clusters (iopt=999 below).
00099   //const float q0 = 1.80;
00100   //const float q1 = 2.83;
00101 
00102   // Good param 
00103   const float q0 = 9.07253e-01; //best
00104   const float q1 = 3.10393e+00;//best
00105   //const float q0 = 3.83120e-01;
00106   //const float q1 = 1.80999e+00;
00107 
00108   unsigned int iopt;
00109   if (clusterWidth > expectedWidth + 2) {
00110     // This cluster is not good - much wider than expected ...
00111     // (Happens for about 3% of clusters in typical events).
00112     iopt = 999;
00113   } else if (expectedWidth == 1) {
00114     // In this case, charge sharing doesn't improve resolution.
00115     // (Happens for about 70% of clusters in typical events).
00116     iopt = 0;
00117   } else if (clusterWidth <= expectedWidth) {
00118     // Resolution rather good in this case.
00119     // (Happens for about 18% of clusters in typical events).
00120     iopt = 1;
00121   } else {
00122     // Can happen due to inter-strip coupling or noise.
00123     // (Happens for about 6% of clusters in typical events).
00124     iopt = 2;
00125   }
00126 
00127   float uerr;
00128   if (iopt == 999) {
00129     // Cluster much wider than expected (delta ray ?), so 
00130     // assign large error.
00131     uerr = q0*(clusterWidth - q1)/sqrt(12.);
00132 
00133   } else if (iopt < nbins) {
00134    // Quadratic parametrization.
00135     uerr = P0[iopt] + P1[iopt]*projectionOnU 
00136                     + P2[iopt]*projectionOnU*projectionOnU;
00137 
00138 
00139   } else {
00140     cout<<"Bug in StripCPEfromTrackAngle2"<<endl;
00141     exit(9);
00142   }
00143 
00144 
00145 
00146   // For the sake of stability, avoid very small resolution.
00147   if (uerr < minError) uerr = minError;
00148   
00149   short firstStrip = cl.firstStrip();
00150 
00151   short lastStrip = firstStrip + clusterWidth - 1;
00152   
00153   // If cluster reaches edge of sensor, inflate its error.
00154     if (firstStrip == 0 || lastStrip == p.nstrips - 1) {
00155       uerr += 0.5*(1 + projectionOnU);
00156   }
00157      
00158     //if((cl.amplitudes().size() - (uProj+2.5)) > 1) uerr=cl.amplitudes().size()  * (1./sqrt(12.));
00159   
00160   MeasurementError merror=MeasurementError( uerr*uerr, 0., 1./12.);
00161   LocalPoint result=LocalPoint(position.x()-0.5*p.drift.x(),position.y()-0.5*p.drift.y(),0);
00162   MeasurementPoint mpoint=p.topology->measurementPosition(result);
00163   LocalError eresult=p.topology->localError(mpoint,merror);
00164 
00165 
00166   return std::make_pair(result,eresult);
00167   
00168 }
00169 
00170 

Generated on Tue Jun 9 17:44:01 2009 for CMSSW by  doxygen 1.5.4