ATLAS Offline Software
Loading...
Searching...
No Matches
LArParabolaPeakRecoTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8
9#include "CLHEP/Matrix/Matrix.h"
10#include "CLHEP/Matrix/Vector.h"
11#include <algorithm>
12#include <cmath>
13#include <stdio.h>
14
15using CLHEP::HepMatrix;
16using CLHEP::HepVector;
17
18
19LArParabolaPeakRecoTool::LArParabolaPeakRecoTool(const std::string& type, const std::string& name,
20 const IInterface* parent)
21 : AthAlgTool(type, name, parent),
22 m_correctBias(true),
23 m_fileShapeName("parabola_Shape.dat"),
24 m_fileADCcorName("parabola_adccor.dat")
25
26{
27 declareProperty("correctBias",m_correctBias);
30 declareInterface<LArParabolaPeakRecoTool>(this);
31}
32
34{
35
36 if(m_correctBias){
37
38 std::cout << "LArParabolaPeakRecoTool: correctBias flag is ON " << std::endl;
39 // if want to correct bias, open files
40
43
44 m_fileShape = fopen(m_fileShapeName.c_str(),"r");
45 m_fileADCcor = fopen(m_fileADCcorName.c_str(),"r");
46 int idelay, ilayer;
47 float timeValue, adccorValue;
48
49 // fill correction table
50 while( fscanf(m_fileShape,"%80d %80d %80f",&idelay,&ilayer,&timeValue) != EOF )
51 {
52 if ( ilayer >= 0 && ilayer < 4 && idelay >= 0 && idelay < 25 )
53 {
54 m_QT_Shape[ilayer][idelay] = timeValue;
55
56 if ( idelay == 0 && m_QT_Shape[ilayer][0] != 0. )
57 {
58 m_QT_Shape[ilayer][25] = m_QT_Shape[ilayer][0] + 25;
59 }
60 }
61 }
62
63 while( fscanf(m_fileADCcor,"%80d %80d %80f",&idelay,&ilayer,&adccorValue) != EOF )
64 {
65 if ( ilayer >= 0 && ilayer < 4 && idelay >= 0 && idelay < 25 )
66 {
67 m_QT_ADCcor[ilayer][idelay] = adccorValue;
68 }
69 }
70 fclose(m_fileADCcor);
71 fclose(m_fileShape);
72 }
73
74 return StatusCode::SUCCESS;
75}
76
78{return StatusCode::SUCCESS;}
79
80std::vector<float> LArParabolaPeakRecoTool::peak (const std::vector<float>& samples) const
81{
82 return peak(samples, -1, -1.);
83}
84
85std::vector<float> LArParabolaPeakRecoTool::peak (const std::vector<short>& samples) const
86{
87 std::vector<float> newsamples;
88 for(unsigned int i=0;i<samples.size();i++)
89 {
90 newsamples.push_back((float)samples[i]);
91 }
92 return peak(newsamples, -1, -1.);
93}
94
95
96std::vector<float> LArParabolaPeakRecoTool::peak (const std::vector<short>& samples, int layer, float pedestal) const
97{
98
99 std::vector<float> newsamples;
100 for(unsigned int i=0;i<samples.size();i++)
101 {
102 newsamples.push_back((float)samples[i]);
103 }
104 return peak(newsamples, layer, pedestal);
105
106}
107
108std::vector<float> LArParabolaPeakRecoTool::peak (const std::vector<float>& samples, int layer, float pedestal) const
109{//const float dt=25.0;//ns
110 std::vector<float> solution;
111
112 const std::vector<float>::const_iterator it_max=max_element(samples.begin(),samples.end());
113 if (it_max==samples.end()) {
114 ATH_MSG_ERROR( "Maximum ADC sample not found!" );
115 return solution;
116 }
117 if (it_max==samples.begin() || it_max==samples.end()-1)
118 {
119 solution.push_back(*it_max);
120 return solution;
121 }
122
123 // Fit a+bx+cx^2
124 HepMatrix alpha(3,3);
125 HepVector beta(3);
126 for (int i=0;i<3;i++)
127 {beta[i]=*(it_max-1+i);
128 for (int j=0;j<3;j++)
129 alpha[i][j]=pow(-1+i,j);
130 }
131
132 float retval=0, tmax=0, traw=0, trec=0;
133 if(!m_correctBias){
134
135 HepVector comp=solve(alpha,beta);
136 //solve b+2cx=0 to get maximum
137 tmax=-comp[1]/(2*comp[2]);
138 //substitute-back
139 retval=comp[0]-comp[1]*comp[1]/(4*comp[2]);
140
141 }else{
142
143 // obtain time as in EMTB
144 traw = 25./2.*(beta[0]-beta[2])/(beta[0] - beta[1] + beta[2] - beta[1]);
145
146 // normalize back to the reference scheme
147 traw += ( it_max-samples.begin() - 3 )*25.;
148
149 if(layer < 0 || layer > 3) {
150 ATH_MSG_ERROR( "Layer index is wrong ! Layer = " << layer );
151 return solution;
152 }else{
153 // get true time
154 trec = ParabolaRawToTrueTime(traw, layer);
155 // get true ADC
156 if(pedestal<0) ATH_MSG_ERROR( "Pedestal is wrong ! Ped = " << pedestal );
157 retval = ParabolaRawToTrueADC(trec, beta[1], pedestal, layer);
158 }
159 }
160
161 solution.push_back(retval);
162 if(!m_correctBias){
163 solution.push_back(tmax);
164 }else{
165 // if corrected bias, return both uncorrected and corrected times
166 solution.push_back(traw);
167 solution.push_back(trec);
168 }
169 return solution;
170}
171
172// function taken from EMTB to obtaine the true time from the biased time
173float LArParabolaPeakRecoTool::ParabolaRawToTrueTime(float& QT_fittime, int& layer) const
174{
175 int iOffset;
176 float QT_true_lower;
177 float QT_raw_lower;
178 float QT_raw_upper;
179 float QT_true_time;
180 int idelay;
181 int ilayer;
182
183 /*
184 * initialize
185 */
186
187 ilayer = layer;
188
189 QT_true_lower = -999.;
190 QT_raw_lower = -999.;
191 QT_raw_upper = -999.;
192 iOffset = 0;
193
194 /*
195 * the transfer function is defined from 0 to 25 ns
196 * the function has a periodicity of 25 ns, adapted
197 * the input value to the nominal regime and correct
198 * afterwards
199 */
200 while ( QT_fittime < m_QT_Shape[ilayer][0] )
201 {
202 QT_fittime +=25;
203 iOffset++;
204 }
205
206 while ( QT_fittime > m_QT_Shape[ilayer][25] )
207 {
208 QT_fittime -= 25;
209 iOffset--;
210 }
211
212 /*
213 * now find the correct bin to do the correction
214 */
215
216 for ( idelay=0; idelay < 25; idelay++ )
217 {
218 if ( QT_fittime >= m_QT_Shape[ilayer][idelay]
219 && QT_fittime < m_QT_Shape[ilayer][idelay+1])
220 {
221 QT_true_lower = (float) (idelay - iOffset * 25.);
222 QT_raw_lower = m_QT_Shape[ilayer][idelay];
223 QT_raw_upper = m_QT_Shape[ilayer][idelay+1];
224 }
225 }
226
227 /*
228 * from lower and upper bounds calculate the true time (linear extrapolation)
229 */
230
231 if ( QT_true_lower == -999. )
232 {
233 QT_true_time = -999.;
234 }
235 else
236 {
237 QT_true_time = QT_true_lower +
238 (QT_fittime-QT_raw_lower)/(QT_raw_upper - QT_raw_lower);
239 }
240 /*
241 * return the true time
242 */
243
244 return QT_true_time;
245
246}
247
248// function taken from EMTB to obtaine the true ADC from the biased ADC
249float LArParabolaPeakRecoTool::ParabolaRawToTrueADC(float& QT_true_time, double& ADCref, float& PEDref, int& layer) const
250{
251 int ichoosedelay;
252 float QT_true_ADC;
253 float QT_correct_ADC;
254 int ilayer;
255
256 /*
257 * save in local variable because of extensive use
258 */
259
260 ilayer = layer;
261
262 /*
263 * now transform the time into a positive value to
264 * make the calculation easier
265 */
266
267 if ( QT_true_time < 0. )
268 {
269 QT_true_time += ( ( (int) std::abs(QT_true_time / 25)) + 1)*25;
270 }
271
272 /*
273 * determine the bin (==delay) of the reference signal
274 */
275
276 ichoosedelay = (int) QT_true_time % 25;
277
278 /*
279 * make sure that we are in-bounds for the correction matrix
280 */
281
282 if ( ilayer >=0 && ilayer< 4 )
283 {
284 if ( ichoosedelay < 25 - 1 ){
285 QT_correct_ADC= m_QT_ADCcor[ilayer][ichoosedelay]
286 + (m_QT_ADCcor[ilayer][ichoosedelay+1]-m_QT_ADCcor[ilayer][ichoosedelay])
287 * (QT_true_time - (int) QT_true_time);
288 }
289 else {
290 QT_correct_ADC= m_QT_ADCcor[ilayer][ichoosedelay]
291 + (m_QT_ADCcor[ilayer][0]-m_QT_ADCcor[ilayer][ichoosedelay])
292 * (QT_true_time - (int) QT_true_time);
293 }
294 }
295 else
296 {
297 QT_correct_ADC = 100.;
298 }
299
300 /*
301 * for consistency reasons:
302 * - subtract pedestal
303 * - correct to ADCmax
304 * - add pedestal (subtraction in EMTB later on)
305 */
306
307 QT_true_ADC = ADCref - PEDref;
308 QT_true_ADC = QT_true_ADC / QT_correct_ADC * 100.;
309 QT_true_ADC += PEDref;
310
311 /*
312 * the corrected time is returned
313 */
314
315 return QT_true_ADC;
316}
#define ATH_MSG_ERROR(x)
constexpr int pow(int base, int exp) noexcept
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
float ParabolaRawToTrueTime(float &QT_fittime, int &layer) const
LArParabolaPeakRecoTool(const std::string &type, const std::string &name, const IInterface *parent)
std::vector< float > peak(const std::vector< float > &samples) const
float ParabolaRawToTrueADC(float &QT_true_time, double &ADCref, float &PEDref, int &layer) const
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)