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