CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/LaserAlignment/src/LASPeakFinder.cc

Go to the documentation of this file.
00001 
00002 #include "Alignment/LaserAlignment/interface/LASPeakFinder.h"
00003 
00004 
00008 LASPeakFinder::LASPeakFinder() {
00009 
00010   amplitudeThreshold = 0.; // default
00011 
00012 }
00013 
00014 
00015 
00016 
00017 
00023 bool LASPeakFinder::FindPeakIn( const LASModuleProfile& aProfile, std::pair<double,double>& result, TH1D* histogram, const double offset ) {
00024 
00025   // this function will be propagated to the histo output file,
00026   // therefore we do some cosmetics already here
00027   TF1 fitFunction( "fitFunction", "gaus" );
00028   fitFunction.SetLineColor( 2 );
00029   fitFunction.SetLineWidth( 2 );
00030 
00031   std::pair<int,double> largestAmplitude( 0, 0. ); // strip, amplitude
00032   double anAmplitude = 0.;
00033 
00034   // need approximate position -> cast to int
00035   const int approxOffset = static_cast<int>( offset );
00036 
00037   // expected beam position (in strips)
00038   const unsigned int meanPosition = 256 + approxOffset;
00039 
00040   // backplane "alignment hole" approx. half size (in strips)
00041   const unsigned int halfWindowSize = 33;
00042 
00043   // loop over the strips in the "alignment hole"
00044   // to fill the histogram
00045   // and determine fit parameter estimates
00046   double sum0 = 0.; // this is the sum of all amplitudes
00047   for( unsigned int strip = meanPosition - halfWindowSize; strip < meanPosition + halfWindowSize; ++strip ) {
00048     anAmplitude = aProfile.GetValue( strip );
00049     sum0 += anAmplitude;
00050     histogram->SetBinContent( 1 + strip, anAmplitude );
00051     if( anAmplitude > largestAmplitude.second ) {
00052       largestAmplitude.first = strip; largestAmplitude.second = anAmplitude;
00053     }
00054   }
00055 
00056   // loop outside the "alignment hole"
00057   // to determine the noise level = sqrt(variance)
00058   double sum1 = 0., sum2 = 0.;
00059   int nStrips = 0;
00060   for( unsigned int strip = 0; strip < 512; ++strip ) {
00061     if( strip < meanPosition - halfWindowSize || strip > meanPosition + halfWindowSize ) {
00062       anAmplitude = aProfile.GetValue( strip );
00063       sum0 += anAmplitude;
00064       sum1 += anAmplitude;
00065       sum2 += pow( anAmplitude, 2 );
00066       nStrips++;
00067     }
00068   }
00069 
00070   // noise as sqrt of the amplitude variance
00071   const double noise = sqrt( 1. / ( nStrips - 1 ) * ( sum2 - pow( sum1, 2 ) / nStrips ) );
00072 
00073   // empty profile?
00074   if( fabs( sum0 ) < 1.e-3 ) {
00075     std::cerr << " [LASPeakFinder::FindPeakIn] ** WARNING: Empty profile (sum=" << sum0 << ")." << std::endl;
00076     return false;
00077   }
00078 
00079   // no reasonable peak?
00080   if( largestAmplitude.second < amplitudeThreshold * noise ) {
00081     std::cerr << " [LASPeakFinder::FindPeakIn] ** WARNING: No reasonably large peak." << std::endl;
00082     return false;
00083   }
00084 
00085   // prepare fit function: starting values..
00086   fitFunction.SetParameter( 0, largestAmplitude.second ); // amp
00087   fitFunction.SetParameter( 1, largestAmplitude.first ); // mean
00088   fitFunction.SetParameter( 2, 3. ); // width
00089 
00090   // ..and parameter limits
00091   fitFunction.SetParLimits( 0, largestAmplitude.second * 0.3, largestAmplitude.second * 1.8 ); // amp of the order of the peak height
00092   fitFunction.SetParLimits( 1, largestAmplitude.first - 12, largestAmplitude.first + 12 ); // mean around the peak maximum
00093   fitFunction.SetParLimits( 2, 0.5, 8. ); // reasonable width
00094   
00095 
00096   // fit options: Quiet / all Weights=1 / better Errors / enable fix&Bounds on parameters
00097   histogram->Fit( &fitFunction, "QWEB", "", largestAmplitude.first - 12, largestAmplitude.first + 12 );
00098 
00099   // prepare output
00100   result.first = fitFunction.GetParameter( 1 );
00101   result.second = fitFunction.GetParError( 1 );
00102 
00103   return true;
00104 
00105 }
00106 
00107 
00108 
00109 
00110 
00114 void LASPeakFinder::SetAmplitudeThreshold( double aThreshold ) {
00115 
00116   amplitudeThreshold = aThreshold;
00117 
00118 }