ATLAS Offline Software
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 
15 using CLHEP::HepMatrix;
16 using CLHEP::HepVector;
17 
18 
19 LArParabolaPeakRecoTool::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);
28  declareProperty("fileShape",m_fileShapeName);
29  declareProperty("fileADCcor",m_fileADCcorName);
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 
80 std::vector<float> LArParabolaPeakRecoTool::peak (const std::vector<float>& samples) const
81 {
82  return peak(samples, -1, -1.);
83 }
84 
85 std::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 
96 std::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 
108 std::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
173 float 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
249 float 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 }
plotting.yearwise_luminosity_vs_mu.comp
comp
Definition: yearwise_luminosity_vs_mu.py:24
LArParabolaPeakRecoTool::initialize
virtual StatusCode initialize()
Definition: LArParabolaPeakRecoTool.cxx:33
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cxx:251
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
LArParabolaPeakRecoTool::peak
std::vector< float > peak(const std::vector< float > &samples) const
Definition: LArParabolaPeakRecoTool.cxx:80
LArCellBinning_test.retval
def retval
Definition: LArCellBinning_test.py:112
LArParabolaPeakRecoTool::LArParabolaPeakRecoTool
LArParabolaPeakRecoTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: LArParabolaPeakRecoTool.cxx:19
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:92
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
01SubmitToGrid.samples
samples
Definition: 01SubmitToGrid.py:58
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
LArParabolaPeakRecoTool::finalize
virtual StatusCode finalize()
Definition: LArParabolaPeakRecoTool.cxx:77
test_pyathena.parent
parent
Definition: test_pyathena.py:15
LArParabolaPeakRecoTool::m_fileShape
FILE * m_fileShape
Definition: LArParabolaPeakRecoTool.h:59
LArParabolaPeakRecoTool::m_fileShapeName
std::string m_fileShapeName
Definition: LArParabolaPeakRecoTool.h:56
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
LArParabolaPeakRecoTool::ParabolaRawToTrueTime
float ParabolaRawToTrueTime(float &QT_fittime, int &layer) const
Definition: LArParabolaPeakRecoTool.cxx:173
LArParabolaPeakRecoTool::m_QT_Shape
float m_QT_Shape[4][26]
Definition: LArParabolaPeakRecoTool.h:60
LArParabolaPeakRecoTool::m_QT_ADCcor
float m_QT_ADCcor[4][25]
Definition: LArParabolaPeakRecoTool.h:61
LArParabolaPeakRecoTool::m_fileADCcorName
std::string m_fileADCcorName
Definition: LArParabolaPeakRecoTool.h:56
LArParabolaPeakRecoTool::m_correctBias
bool m_correctBias
Definition: LArParabolaPeakRecoTool.h:55
LArParabolaPeakRecoTool::ParabolaRawToTrueADC
float ParabolaRawToTrueADC(float &QT_true_time, double &ADCref, float &PEDref, int &layer) const
Definition: LArParabolaPeakRecoTool.cxx:249
LArParabolaPeakRecoTool::m_fileADCcor
FILE * m_fileADCcor
Definition: LArParabolaPeakRecoTool.h:59
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
LArParabolaPeakRecoTool.h
AthAlgTool
Definition: AthAlgTool.h:26
MuonParameters::beta
@ beta
Definition: MuonParamDefs.h:144
readCCLHist.float
float
Definition: readCCLHist.py:83