CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoLocalTracker/SiStripRecHitConverter/src/StripCPEgeometric.cc

Go to the documentation of this file.
00001 #include "RecoLocalTracker/SiStripRecHitConverter/interface/StripCPEgeometric.h"
00002 #include "RecoLocalTracker/SiStripRecHitConverter/interface/CrosstalkInversion.h"
00003 #include "Geometry/CommonTopologies/interface/StripTopology.h"
00004 #include <numeric>
00005 
00006 StripClusterParameterEstimator::LocalValues StripCPEgeometric::
00007 localParameters( const SiStripCluster& cluster, const GeomDetUnit& det, const LocalTrajectoryParameters& ltp) const {
00008   StripCPE::Param const& p = param(det);
00009 
00010   const LocalPoint& pos = ltp.position();
00011   LocalVector track = ltp.momentum();
00012   track *=  (track.z()<0) ?  fabs(p.thickness/track.z()) : 
00013             (track.z()>0) ? -fabs(p.thickness/track.z()) :  
00014                              p.maxLength/track.mag() ;
00015 
00016   const float fullProjection = p.coveredStrips( track+p.drift, pos );
00017   stats_t<float> projection;
00018   {
00019     const float absProj = fabs( fullProjection );
00020     const float minProj = 2*p.thickness*tan_diffusion_angle/p.topology->localPitch(pos);
00021     const float projection_rel_err2 = thickness_rel_err2 + p.pitch_rel_err2;
00022     projection = stats_t<float>::from_relative_uncertainty2( std::max(absProj, minProj), projection_rel_err2);
00023   }
00024 
00025   const std::vector<stats_t<float> > Q = reco::InverseCrosstalkMatrix::unfold( cluster.amplitudes(), xtalk1[p.moduleGeom] );
00026   const stats_t<float> strip = cluster.firstStrip() + offset_from_firstStrip( Q, projection );
00027 
00028   const float corrected = strip() -  0.5*(1-shift[p.moduleGeom]) * fullProjection
00029     + 0.5*p.coveredStrips(track, ltp.position());
00030   const float error2 = std::max( strip.error2(), minimum_uncertainty_squared );  
00031 
00032   return std::make_pair( p.topology->localPosition( corrected, ltp.vector()),
00033                          p.topology->localError( corrected, error2, ltp.vector()));
00034 }
00035 
00036 
00037 stats_t<float> StripCPEgeometric::
00038 offset_from_firstStrip( const std::vector<stats_t<float> >& Q, const stats_t<float>& proj) const {
00039   WrappedCluster wc(Q);
00040   if(    useNPlusOne( wc, proj))  wc.addSuppressedEdgeStrip();  else 
00041   while( useNMinusOne( wc, proj)) wc.dropSmallerEdgeStrip();
00042 
00043   if( proj() < wc.N-2 )           return stats_t<float>( wc.middle(),  pow(wc.N-proj(),2) / 12.);
00044   if( wc.deformed()   )           return stats_t<float>( wc.centroid()(),               1 / 12.);
00045   if( proj > wc.maxProjection() ) return stats_t<float>( wc.centroid()(),               1 / 12.);
00046 
00047   if( ambiguousSize( wc, proj) ) {
00048     const stats_t<float> probably = geometric_position( wc, proj);
00049     wc.dropSmallerEdgeStrip();
00050     const stats_t<float> maybe = geometric_position( wc, proj);
00051     return stats_t<float>( probably(), std::max( probably.error2(), float(maybe.error2() + pow( probably()-maybe() ,2)/12 )) );
00052   }
00053   return geometric_position( wc, proj);
00054 }
00055 
00056 stats_t<float> StripCPEgeometric::
00057 geometric_position(const StripCPEgeometric::WrappedCluster& wc, const stats_t<float>& proj) const {
00058   const stats_t<float> x = wc.middle()  +  0.5 * proj * wc.eta();
00059   return wc.N==1 
00060     ?  stats_t<float>( x(), pow( 1-0.82*proj(), 2 ) / 12 ) 
00061     :  stats_t<float>( x(), scaling_squared * x.error2() ) ;
00062 }
00063 
00064 inline
00065 bool StripCPEgeometric::
00066 useNPlusOne(const WrappedCluster& wc, const stats_t<float>& proj) const 
00067 { return wc.maxProjection() < proj && proj() < wc.N+1 ; }
00068 
00069 inline
00070 bool StripCPEgeometric::
00071 useNMinusOne(const WrappedCluster& wc, const stats_t<float>& proj) const {
00072   if( proj() > wc.N-1) return false;
00073   if( wc.smallerEdgeStrip() < 0 ) return true;
00074   if( proj() < wc.N-3) return false;
00075   if( proj() < wc.N-2) return true;
00076   if( wc.eta().sigmaFrom(0) < 3) return false;
00077 
00078   WrappedCluster wcTest(wc); wcTest.dropSmallerEdgeStrip();
00079   if( proj >= wcTest.maxProjection() ) return false;
00080   if( wc.sign()*wc.eta()() > 1./(wc.N-1) ) return true;
00081 
00082   return wc.smallerEdgeStrip().sigmaFrom(0) < noise_threshold;
00083 }
00084 
00085 inline
00086 bool StripCPEgeometric::
00087 ambiguousSize( const WrappedCluster& wc, const stats_t<float>& proj) const 
00088 {  return 
00089      proj() < wc.N-1 && 
00090      wc.smallerEdgeStrip()()>0 && 
00091      wc.smallerEdgeStrip().sigmaFrom(0) < maybe_noise_threshold; }
00092 
00093 StripCPEgeometric::WrappedCluster::
00094 WrappedCluster(const std::vector<stats_t<float> >& Q) : 
00095   N(Q.size()-2),
00096   clusterFirst(Q.begin()+1),
00097   first(clusterFirst)
00098   {}
00099 
00100 inline
00101 void StripCPEgeometric::WrappedCluster::
00102 addSuppressedEdgeStrip() {
00103   if( eta().sigmaFrom(0) < 1 ) { first--; N+=2; } 
00104   else if( *first > last() )   { first--; N+=1; } 
00105   else                         {          N+=1; }
00106 }
00107 
00108 inline
00109 void StripCPEgeometric::WrappedCluster::
00110 dropSmallerEdgeStrip() {
00111   if( *first < last() ) { first++; N-=1; } else 
00112   if( last() < *first ) {          N-=1; } else  
00113                         { first++; N-=2; } 
00114 }
00115 
00116 inline
00117 float StripCPEgeometric::WrappedCluster::
00118 middle() const 
00119 { return (first-clusterFirst) + N/2.;}
00120 
00121 inline
00122 stats_t<float> StripCPEgeometric::WrappedCluster::
00123 centroid() const { 
00124   stats_t<float> sumXQ(0);
00125   for(std::vector<stats_t<float> >::const_iterator i = first; i<first+N; i++) sumXQ += (i-clusterFirst)*(*i);
00126   return sumXQ/sumQ() + 0.5;
00127 }
00128 
00129 inline
00130 stats_t<float> StripCPEgeometric::WrappedCluster::
00131 sumQ() const
00132 { return accumulate(first, first+N, stats_t<float>(0));}
00133 
00134 inline
00135 stats_t<float> StripCPEgeometric::WrappedCluster::
00136 eta() const 
00137 { return  ( last() - *first ) / sumQ() ;}
00138 
00139 inline
00140 bool StripCPEgeometric::WrappedCluster::
00141 deformed() const 
00142 {  return  N>2  &&  std::max((*first)(),last()()) > accumulate(first+1,first+N-1,stats_t<float>(0))() / (N-2);}
00143 
00144 inline
00145 stats_t<float> StripCPEgeometric::WrappedCluster::
00146 maxProjection() const
00147 { return N * (1 + sign()*eta() ).inverse(); }
00148 
00149 inline
00150 stats_t<float> StripCPEgeometric::WrappedCluster::
00151 smallerEdgeStrip() const
00152 { return std::min(*first, last()); }
00153 
00154 inline
00155 int StripCPEgeometric::WrappedCluster::
00156 sign() const
00157 { return ( *first < last() ) ? 1  : -1; }