CMS 3D CMS Logo

LASPeakFinder.cc
Go to the documentation of this file.
1 
3 
4 
9 
10  amplitudeThreshold = 0.; // default
11 
12 }
13 
14 
15 
16 
17 
23 bool LASPeakFinder::FindPeakIn( const LASModuleProfile& aProfile, std::pair<double,double>& result, TH1D* histogram, const double offset ) {
24 
25  // this function will be propagated to the histo output file,
26  // therefore we do some cosmetics already here
27  TF1 fitFunction( "fitFunction", "gaus" );
28  fitFunction.SetLineColor( 2 );
29  fitFunction.SetLineWidth( 2 );
30 
31  std::pair<int,double> largestAmplitude( 0, 0. ); // strip, amplitude
32  double anAmplitude = 0.;
33 
34  // need approximate position -> cast to int
35  const int approxOffset = static_cast<int>( offset );
36 
37  // expected beam position (in strips)
38  const unsigned int meanPosition = 256 + approxOffset;
39 
40  // backplane "alignment hole" approx. half size (in strips)
41  const unsigned int halfWindowSize = 33;
42 
43  // loop over the strips in the "alignment hole"
44  // to fill the histogram
45  // and determine fit parameter estimates
46  double sum0 = 0.; // this is the sum of all amplitudes
47  for( unsigned int strip = meanPosition - halfWindowSize; strip < meanPosition + halfWindowSize; ++strip ) {
48  anAmplitude = aProfile.GetValue( strip );
49  sum0 += anAmplitude;
50  histogram->SetBinContent( 1 + strip, anAmplitude );
51  if( anAmplitude > largestAmplitude.second ) {
52  largestAmplitude.first = strip; largestAmplitude.second = anAmplitude;
53  }
54  }
55 
56  // loop outside the "alignment hole"
57  // to determine the noise level = sqrt(variance)
58  double sum1 = 0., sum2 = 0.;
59  int nStrips = 0;
60  for( unsigned int strip = 0; strip < 512; ++strip ) {
61  if( strip < meanPosition - halfWindowSize || strip > meanPosition + halfWindowSize ) {
62  anAmplitude = aProfile.GetValue( strip );
63  sum0 += anAmplitude;
64  sum1 += anAmplitude;
65  sum2 += pow( anAmplitude, 2 );
66  nStrips++;
67  }
68  }
69 
70  // noise as sqrt of the amplitude variance
71  const double noise = sqrt( 1. / ( nStrips - 1 ) * ( sum2 - pow( sum1, 2 ) / nStrips ) );
72 
73  // empty profile?
74  if( fabs( sum0 ) < 1.e-3 ) {
75  std::cerr << " [LASPeakFinder::FindPeakIn] ** WARNING: Empty profile (sum=" << sum0 << ")." << std::endl;
76  return false;
77  }
78 
79  // no reasonable peak?
80  if( largestAmplitude.second < amplitudeThreshold * noise ) {
81  std::cerr << " [LASPeakFinder::FindPeakIn] ** WARNING: No reasonably large peak." << std::endl;
82  return false;
83  }
84 
85  // prepare fit function: starting values..
86  fitFunction.SetParameter( 0, largestAmplitude.second ); // amp
87  fitFunction.SetParameter( 1, largestAmplitude.first ); // mean
88  fitFunction.SetParameter( 2, 3. ); // width
89 
90  // ..and parameter limits
91  fitFunction.SetParLimits( 0, largestAmplitude.second * 0.3, largestAmplitude.second * 1.8 ); // amp of the order of the peak height
92  fitFunction.SetParLimits( 1, largestAmplitude.first - 12, largestAmplitude.first + 12 ); // mean around the peak maximum
93  fitFunction.SetParLimits( 2, 0.5, 8. ); // reasonable width
94 
95 
96  // fit options: Quiet / all Weights=1 / better Errors / enable fix&Bounds on parameters
97  histogram->Fit( &fitFunction, "QWEB", "", largestAmplitude.first - 12, largestAmplitude.first + 12 );
98 
99  // prepare output
100  result.first = fitFunction.GetParameter( 1 );
101  result.second = fitFunction.GetParError( 1 );
102 
103  return true;
104 
105 }
106 
107 
108 
109 
110 
114 void LASPeakFinder::SetAmplitudeThreshold( double aThreshold ) {
115 
116  amplitudeThreshold = aThreshold;
117 
118 }
double GetValue(unsigned int theStripNumber) const
bool FindPeakIn(const LASModuleProfile &, std::pair< double, double > &, TH1D *, const double)
T sqrt(T t)
Definition: SSEVec.h:18
double amplitudeThreshold
Definition: LASPeakFinder.h:29
void SetAmplitudeThreshold(double)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40