CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/RecoLocalTracker/SiStripRecHitConverter/src/CrosstalkInversion.cc

Go to the documentation of this file.
00001 #include "RecoLocalTracker/SiStripRecHitConverter/interface/CrosstalkInversion.h"
00002 #include "FWCore/Utilities/interface/isFinite.h"
00003 
00004 namespace reco {
00005 
00006 std::vector<stats_t<float> > InverseCrosstalkMatrix::
00007 unfold(const std::vector<uint8_t>& q, const float x) {
00008   const stats_t<float> suppressed(-5,100);
00009   const stats_t<float> saturated(254,400);
00010   #define STATS(value) ( (value<254) ? stats_t<float>(value) : saturated )
00011 
00012   const unsigned N=q.size();
00013   std::vector<stats_t<float> > Q(N+2,stats_t<float>(0));
00014   Q[0] = Q[N+1] = suppressed;
00015 
00016   if(N==1)                                 //optimize N==1
00017     Q[1] = STATS(q[0])/(1-2*x);  
00018   else if(N==2) {                          //optimize N==2
00019     const double A=1-2*x; 
00020     const stats_t<float> q0 = STATS(q[0]);
00021     const stats_t<float> q1 = STATS(q[1]);
00022     Q[1] = ( A*q0 -x*q1 ) / (A*A-x*x);
00023     Q[2] = ( A*q1 -x*q0 ) / (A*A-x*x);
00024   } 
00025   else {                                   //general case
00026     const InverseCrosstalkMatrix inverse(N,x);  
00027     for(unsigned i=0; i<(N+1)/2; i++) {
00028       for(unsigned j=i; j<N-i; j++) {
00029         const float Cij = inverse(i+1,j+1);
00030         Q[i+1] += Cij * STATS(q[  j  ]) ;  if( i!=j)   
00031         Q[j+1] += Cij * STATS(q[  i  ]) ;  if( N!=i+j+1) {
00032         Q[N-i] += Cij * STATS(q[N-j-1]) ;  if( i!=j)
00033         Q[N-j] += Cij * STATS(q[N-i-1]) ;
00034         }
00035       }
00036     }
00037   }
00038   #undef STATS
00039   return Q;
00040 }
00041 
00042 InverseCrosstalkMatrix::
00043 InverseCrosstalkMatrix(const unsigned N, const float x)
00044   : N( x>0 ? N : 0 ),
00045     sq( sqrt(-x*4+1)),
00046     lambdaP( 1+(1+sq)/(-x*2) ),
00047     lambdaM( 1+(1-sq)/(-x*2) ),
00048     denominator( sq * ( pow(lambdaP,N+1) - pow(lambdaM,N+1) ) )
00049 {}
00050 
00051 float InverseCrosstalkMatrix::
00052 operator()(const unsigned i, const unsigned j) const
00053 { return N==0 || edm::isNotFinite(denominator) ? i==j : i>=j ? element(i,j) : element(j,i) ; }
00054 
00055 inline
00056 float InverseCrosstalkMatrix::
00057 element(const unsigned i, const unsigned j) const 
00058 { return ( pow(lambdaM,N+1-i) - pow(lambdaP,N+1-i) ) * ( pow(lambdaM,j) - pow(lambdaP,j) ) / denominator; }
00059 
00060 }