ATLAS Offline Software
Loading...
Searching...
No Matches
LArShapePeakRecoTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <algorithm>
8#include <cmath>
9#include <stdio.h>
10
11// *****************************************************************************
12// Tool to reconstruct ADCreco from the calibration profile (Inspired by EMTB )
13// Author: S. Laplace - Nov. 2004
14//
15//******************************************************************************
16
17
18LArShapePeakRecoTool::LArShapePeakRecoTool(const std::string& type, const std::string& name,
19 const IInterface* parent)
20 : AthAlgTool(type, name, parent)
21{}
22
24{
25 return StatusCode::SUCCESS;
26}
27
29{return StatusCode::SUCCESS;}
30
31// input vector of samples must be pedestal substracted
32std::vector<float> LArShapePeakRecoTool::peak (const std::vector<float>& samples, const std::vector<double>& wave ) const
33{
34 std::vector<float> solution;
35
36 float shape_max,delay_max;
37 float sample_max,adc_max;
38 int i,s,s1,s2,d,d1,d2;
39 double chi2,chi2_best,yi2,yigi,gi2,lambda=0;
40 int nbin;
41
42 nbin = wave.size();
43
44 // find maximum of delay profile
45 const std::vector<double>::const_iterator wave_max=max_element(wave.begin(),wave.end());
46 if (wave_max==wave.end())
47 {ATH_MSG_ERROR( "Maximum of Delay Profile not found!" );
48 return solution;
49 }
50 shape_max = *wave_max;
51
52 delay_max = distance(wave.begin(),wave_max);
53
54 // parabola approximation of shape maximum
55 d = (int) delay_max;
56 GetShapeParMax(delay_max,shape_max,delay_max-1,wave[d-1],
57 delay_max,wave[d], delay_max+1,wave[d+1]);
58
59 // find maximum of ADC samples
60
61 const std::vector<float>::const_iterator it_max=max_element(samples.begin(),samples.end());
62 if (it_max==samples.end())
63 {ATH_MSG_ERROR( "Maximum ADC sample not found!" );
64 return solution;
65 }
66 adc_max = *it_max;
67 sample_max = distance(samples.begin(),it_max);
68
69 // Get sample limits
70 // GetShapeSampleLimits(s1,s2,sample_max,delay_max,nbin,samples.size());
71
72 // find 2nd maximum of ADC samples
73 std::vector<float>::const_iterator it_sample = samples.begin();
74 std::vector<float>::const_iterator it_sample_end = samples.end();
75
76 float adc_2ndmax = 0;
77 int sample_2ndmax = static_cast<int> (sample_max);
78 for (;it_sample!=it_sample_end;++it_sample) { //Loop over sample vector
79 if((*it_sample>adc_2ndmax) && (*it_sample<=adc_max)) {
80 adc_2ndmax = *it_sample;
81 sample_2ndmax = distance(samples.begin(),it_sample);
82 }
83 }
84
85 // determine s1 and s2
86 if(std::abs(sample_max-sample_2ndmax)>1) std::cout << "maxima are far away ? index(max) = " << sample_max << ", index(2nd max) = " << sample_2ndmax << ", samples = " << samples[0] << ", " << samples[1] << ", " << samples[2] << ", " << samples[3] << ", " << samples[4] << ", " << samples[5] << ", " << std::endl;
87
88 if(sample_max-sample_2ndmax > 0) {
89 s1 = sample_2ndmax - 1;
90 s2 = static_cast<int> (sample_max + 1);
91 }else{
92 s1 = static_cast<int> (sample_max - 1);
93 s2 = sample_2ndmax + 1;
94 }
95
96 // Get delay Limits
97 d1 = 0;
98 d2 = nbin-1-(s2-s1)*24;
99
100 // Loop on all delays to find the best chi2
101 // i.e. minimise
102 // chi2 = yi2-yigi*lambda = yi2-yigi*yigi/gi2
103 // where yi : samples in ADC counts
104 // gi : normalised pulse shape
105 // maximum is then given by the lagrange factor
106 // lambda = yigi/gi2 in ADC counts
107
108 chi2_best=1e30;
109 int delay_best=-999;
110
111 for(d=d1;d<=d2;d++)
112 {
113 yi2=0; gi2=0; yigi=0;
114
115 for(s=s1;s<=s2;s++) {
116 i = (s-s1)*24+d;
117 yi2+=samples[s]*samples[s];
118 gi2+=wave[i]*wave[i];
119 yigi+=wave[i]*samples[s];
120 }
121
122 if(gi2<=0) chi2=chi2_best;
123 else chi2=yi2-yigi*yigi/gi2;
124
125 if(chi2<chi2_best)
126 {
127 chi2_best=chi2;
128 delay_best=d;
129 lambda=yigi/gi2;
130 }
131 }
132
133 if(delay_best<=-999) { return solution; }
134
135 float adc_reco = lambda*shape_max;
136
137 float time_reco = delay_best;
138 if(delay_best<adc_max) time_reco = delay_best;
139
140 solution.push_back(adc_reco);
141 solution.push_back(time_reco);
142
143 return solution;
144}
145
146// Find maximum of three points shape with a Parabola approximation
147void LArShapePeakRecoTool::GetShapeParMax(float &xmax, float &ymax, float x1, float y1,
148 float x2, float y2, float x3, float y3) const
149{
150 float a,b,c;
151 float x12, x13, xx12, xx13, y12, y13;
152 float n,d;
153
154 y13 = y1 - y3;
155 y12 = y1 - y2;
156 x13 = x1 - x3;
157 x12 = x1 - x2;
158 xx12 = x1*x1 - x2*x2;
159 xx13 = x1*x1 - x3*x3;
160
161 n = y13 - x13/x12*y12;
162 d = xx13 - x13/x12*xx12;
163 a = n/d;
164 b = (y12 - a*xx12)/x12;
165 c = y1 - a*x1*x1 - b*x1;
166
167 xmax = -b/2/a;
168 ymax = a*xmax*xmax+b*xmax+c;
169}
170
171// Find sample Limits
172void LArShapePeakRecoTool::GetShapeSampleLimits(int &s1, int &s2, float sample_max,
173 float delay_max, int nbin, int nsample) const
174{
175 s1=0; s2=nsample-1;
176
177 s1 = (int) (sample_max - (delay_max - 5.)/25.) +1;
178 if(s1<0) s1=0;
179 s2 = (int) (sample_max + (nbin - delay_max - 5.)/25.);
180 if(s2>=nsample) s2=nsample-1;
181
182 while(s2-s1>=3) {
183 if(s2-sample_max>sample_max-s1) s2--;
184 else s1++;
185 }
186
187}
188
#define ATH_MSG_ERROR(x)
static Double_t a
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
LArShapePeakRecoTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode finalize()
void GetShapeSampleLimits(int &s1, int &s2, float sample_max, float delay_max, int nbin, int nsample) const
virtual StatusCode initialize()
void GetShapeParMax(float &xmax, float &ymax, float x1, float y1, float x2, float y2, float x3, float y3) const
std::vector< float > peak(const std::vector< float > &samples, const std::vector< double > &wave) const
double chi2(TH1 *h0, TH1 *h1)
double xmax
Definition listroot.cxx:61
double ymax
Definition listroot.cxx:64