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-p.backplanecorrection) * 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; }