ATLAS Offline Software
Loading...
Searching...
No Matches
LArPhysWaveHECTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include <gsl/gsl_integration.h>
9#include <gsl/gsl_errno.h>
10
11#include <TGraphSmooth.h>
12#include <iostream>
13#include <fstream>
14#include <vector>
15#include <cmath>
16
18
19using std::cout;
20using std::endl;
21
22const int NMAX=1000;
23
24static Double_t Tp(Double_t *t, Double_t *par);
25static Double_t Tp_gsl(Double_t *t, Double_t *par);
26static Double_t DTp(Double_t *t, Double_t *par);
27static Double_t Tp4(Double_t t);
28static Double_t Tp5_gsl(Double_t t);
29static Double_t Tp4_gsl(Double_t t);
30static Double_t Tp5(Double_t t);
31static Double_t Tc(Double_t t);
32Double_t normalize(TF1 *func, Double_t *rampl=NULL,
33 Double_t from=0., Double_t to = 0., Double_t step = 1.);
34
35Double_t normalize_prof(TProfile *histo, Double_t *rampl=NULL);
36
37static Double_t tau0, taup, tauz, taus, rc, rz, rs, sp, s0, sz, ss, sc, fs,
38 tdr, tc, a, t0, al;
39static Double_t x[NMAX], y[NMAX], STEP, *pref = NULL;
40
41static Double_t f4_g(Double_t *x, Double_t *par);
42static Double_t f5_g(Double_t *x, Double_t *par);
43
44static double f4_gsl(double x, void *par);
45static double f5_gsl(double x, void *par);
46
47struct gsl_f_params { double a; };
48
49struct usertim {Double_t t;};
50
51static TSpline3 *splin = NULL;
52
53void Smooth_new(Double_t *x, Double_t *y, Double_t *yref, Int_t ymax);
54void SmootKern(Double_t *x, Double_t *y, Int_t ymax, Double_t band = 10.);
55
58
59LArPhysWaveHECTool::LArPhysWaveHECTool ( const std::string& type, const std::string& name,const IInterface* parent )
60 : AthAlgTool(type,name,parent)
61{
62
63 // Declare additional interface
64 declareInterface<LArPhysWaveHECTool>(this);
65
66 declareProperty("NormalizeCali", m_normalizeCali=false) ;//true?
67 declareProperty("TimeOriginShift", m_timeOriginShift=false) ;
68 declareProperty("SubtractBaseline", m_subtractBaseline=true) ;
69 declareProperty("isSC", m_isSC=false) ;
70 declareProperty("TcalMin", m_TcalMin=370) ;
71 declareProperty("TcalMax", m_TcalMax=490) ;
72 declareProperty("TcalAverage", m_TcalAverage=422.2) ;
73 declareProperty("FstepMin", m_FstepMin=0.02) ;
74 declareProperty("FstepMax", m_FstepMax=0.1) ;
75 declareProperty("FstepAverage", m_FstepAverage=0.068) ;
76 declareProperty("MinAmplitude", m_MinAmp=100.);
77}
78
80
82{
83 if ( m_isSC ) {
84 ATH_MSG_DEBUG("==== looking at SuperCells ====");
85 const LArOnline_SuperCellID* ll;
86 ATH_CHECK( detStore()->retrieve(ll, "LArOnline_SuperCellID") );
87 m_onlineHelper = static_cast<const LArOnlineID_Base*>(ll);
88 } else { // m_isSC
89 const LArOnlineID* ll;
90 ATH_CHECK( detStore()->retrieve(ll, "LArOnlineID") );
91 m_onlineHelper = static_cast<const LArOnlineID_Base*>(ll);
92 }
93 return StatusCode::SUCCESS;
94}
95
96
98 LArPhysWave & predLArPhysWave, const LArPhysWave & idealPhysWave,
99 float & MphysMcali, const HWIdentifier& chid, const int gain,
100 int & LArPhysWaveFlag) {
101 LArPhysWaveFlag=LArWave::predCali;
103 // set input objects
104 m_Omega0 = 0.;
105 m_Taur = 0.;
106 m_gIdealPhys = &idealPhysWave;
107
108 if(wfParam.fstep()<m_FstepMin || wfParam.fstep()>m_FstepMax){
109 ATH_MSG_INFO (" Fstep="<< wfParam.fstep() << " out of accepted region ("<<m_FstepMin<< ","<<m_FstepMax<<") average used instead : "<<m_FstepAverage);
110 wfParam.setFstep(m_FstepAverage);
111 }
112 if(wfParam.tcal()<m_TcalMin || wfParam.tcal()>m_TcalMax ){
113 ATH_MSG_INFO (" Tcal="<< wfParam.tcal() << "out of accepted region ("<<m_TcalMin<< ","<<m_TcalMax<<") average used instead : "<<m_TcalAverage);
114 wfParam.setTcal(m_TcalAverage);
115 }
116
117
118 ATH_MSG_DEBUG (" Tdrift="<< wfParam.tdrift() <<" Tcal="<<wfParam.tcal()<<" Fstep="<< wfParam.fstep()<<" m_Omega0="<< m_Omega0<<" m_Taur="<<m_Taur<<" LArWaveFlag="
119 << LArWaveFlag <<" LArPhysWaveFlag="<< LArPhysWaveFlag );
120 predict_phys_HEC(wfParam,caliWave,predLArPhysWave, MphysMcali,chid,gain);
121
122
123 return StatusCode::SUCCESS;
124}
125
127 LArPhysWave & predLArPhysWave,
128 float & MphysMcali, const HWIdentifier& chid, const int gain) {
129
130 // calib. signal at Mother Board :
131 LArWave gCaliMB=caliWave ;//deep-copy and cast to base-class
132 LArWaveHelper wHelper;
133
134
135 // shift gCaliMB to start point and remove baseline
136
137 m_Tstart = wHelper.getStart(gCaliMB) ;
138 double baseline = wHelper.getBaseline(gCaliMB,m_Tstart) ;
139 if ( m_subtractBaseline ) gCaliMB = gCaliMB+ (-baseline);
140 if ( m_timeOriginShift ) gCaliMB = wHelper.translate(gCaliMB,-m_Tstart,baseline) ;
141
142 // normalization of calibration pulse
143 double peak_tmp=gCaliMB.getSample( wHelper.getMax(gCaliMB) ) ;
144 if ( m_normalizeCali ) {
145 double peak = gCaliMB.getSample( wHelper.getMax(gCaliMB) ) ;
146 peak_tmp=peak;
147 ATH_MSG_VERBOSE ( "*** Normalisation \t|-> YES (CaliWave peak = " << peak << ")" );
148 if ( peak <=0 ) {
149 ATH_MSG_WARNING ( "Peak value <=0 , cannot normalize!" );
150 } else {
151 gCaliMB = gCaliMB * (1./peak) ;
152 }
153 } else {
154 ATH_MSG_VERBOSE ( "*** Normalisation \t|-> NO" );
155 }
156
157
158 int FT = m_onlineHelper->feedthrough(chid);
159 int Slot = m_onlineHelper->slot(chid);
160 int Channel = m_onlineHelper->channel(chid);
161 int adc = 128*(Slot-5)+ Channel+1;
162
163 ATH_MSG_VERBOSE ( "*** Physics waveform\t|-> FT=" << FT << " Slot=" << Slot << " Channel=" <<Channel<< " adc=" << adc << " gain=" << gain );
164 ATH_MSG_VERBOSE ( "*** Physics waveform\t|-> m_Tdrift = " << wfParam.tdrift() << " ns " );
165 ATH_MSG_VERBOSE ( "*** Physics waveform\t|-> m_Fstep = " << wfParam.fstep() << " ns " );
166 ATH_MSG_VERBOSE ( "*** Physics waveform\t|-> m_Tcal = " << wfParam.tcal() << " ns " );
167
168
169
171 unsigned int CaliWaveBins = gCaliMB.getSize();
172 double const BinWidth=25.0/24;
173 double const HalfBinWidth=BinWidth/2.0;
174 double par[3]={0.0,1.0,0.10};
175 bool uset0=false, norm=false;
176
177 double const QUAL_REQ=peak_tmp*0.04; //80 ADC units is max allowed deviation of Ampl between two bins
178 double const QUAL_REQ_AMPL=peak_tmp*0.3;
179
180 double DIFF=0,DIFF_AMPL=0;
181 unsigned short int repro_count=0;
182 int idx_bad_time=-1,idx_bad_time_ampl=-1;
183 TF1 *PhysWaveFunc=0;
184 const unsigned short int ITER_MAX = 10;
185 double Ampl_problem=-1, Time_problem=-1, Ampl_problem_ampl=-1, Time_problem_ampl=-1;
186 double CALIWAVE_SHIFT=0;
187 TProfile pcal("pcal","Amplitude vs Time",CaliWaveBins,0-HalfBinWidth,CaliWaveBins*BinWidth-HalfBinWidth);
188 while(( (DIFF>=QUAL_REQ || DIFF_AMPL>=QUAL_REQ_AMPL) && repro_count<ITER_MAX)
189 || repro_count==0){
190
191 // if deviation is above a limit, move the CALIWAVE by 1.0 ADC counts
192 if ( m_normalizeCali || peak_tmp < 1.1) {
193 CALIWAVE_SHIFT=0.0005*repro_count;
194 } else {
195 CALIWAVE_SHIFT=1.0*repro_count;
196 }
197
198 if(repro_count>0){
199 ATH_MSG_INFO ("FT="<<FT<<" Slot="<<Slot<<" Ch="<<Channel<<" Gain="<<gain<<" adc="<<adc);
200 ATH_MSG_INFO (repro_count<<". Iteration of INTEGRATION: CALIWAVE IS MOVED UP by "<<CALIWAVE_SHIFT<<" ADC units");
201 if(DIFF_AMPL>=QUAL_REQ_AMPL)
202 ATH_MSG_INFO ("Problematic DIFF_AMPL bin="<<idx_bad_time_ampl<<" AmplPhysGSL="<<Ampl_problem_ampl<<" Time="<< Time_problem_ampl <<" Deviation="<<DIFF_AMPL<<" ADC units"<<" Peak="<<peak_tmp);
203 if(DIFF>=QUAL_REQ)
204 ATH_MSG_INFO ("Problematic DIFF bin="<<idx_bad_time<<" AmplPhysGSL="<<Ampl_problem<<" Time="<<Time_problem<<" Deviation="<<DIFF<<" ADC units"<< " Peak="<<peak_tmp);
205 }
206
207 pcal.Reset();
208 for(unsigned tbin=1;tbin<=gCaliMB.getSize();++tbin){
209 double AmplCalib = gCaliMB.getSample(tbin-1)+CALIWAVE_SHIFT;
210 double Time = gCaliMB.getTime(tbin-1);
211 pcal.Fill(Time,AmplCalib,1);
212 }
213 bool gslflag=true;
214 Double_t *xmax=0;
215 double parCL[2]={wfParam.tcal(),wfParam.fstep()};
216 TF1 *deriv=0;
217 TF1* pwf=CaliWave2PhysWaveHEC(&pcal, par, parCL, deriv, uset0, norm, adc, xmax,gslflag);
218 if (deriv) delete deriv;
219 if (!pwf) {
220 ATH_MSG_ERROR("Failed to create PhysWaveFunc");
221 return;
222 }
223 PhysWaveFunc= (TF1*)pwf->Clone();
224 DIFF=0;DIFF_AMPL=0;Ampl_problem=-1; Time_problem=-1; Ampl_problem_ampl=-1; Time_problem_ampl=-1;
225
226
227 for(int i=1;i<pcal.GetNbinsX(); ++i){
228 double TimePhys1 = pcal.GetBinCenter(i+1);
229 double TimePhys0 = TimePhys1-BinWidth;
230 double DIFF_TMP = PhysWaveFunc->Eval(TimePhys1)-PhysWaveFunc->Eval(TimePhys0);
231 if(TimePhys1>200 && DIFF<fabs(DIFF_TMP)){
232 DIFF=fabs(DIFF_TMP);
233 idx_bad_time=i;
234 Ampl_problem=PhysWaveFunc->Eval(TimePhys1);
235 Time_problem=TimePhys1;
236 }
237 else if(TimePhys1<=200 && DIFF_AMPL<fabs(DIFF_TMP)){
238 DIFF_AMPL=fabs(DIFF_TMP);
239 idx_bad_time_ampl=i;
240 Ampl_problem_ampl=PhysWaveFunc->Eval(TimePhys1);
241 Time_problem_ampl=TimePhys1;
242 } }
243 repro_count++;
244 }
245
246 if(repro_count>=ITER_MAX && (DIFF>=QUAL_REQ || DIFF_AMPL>=QUAL_REQ_AMPL)){
247 ATH_MSG_WARNING ("FT="<<FT<<" Slot="<<Slot<<" Ch="<<Channel<<" Gain="<<gain<<" #iterations for CALIWAVE increasing reached the limit! LArWaveFlag set to -1" );
248 LArWaveFlag=-1;
249 }
250
251 predLArPhysWave=LArPhysWave(gCaliMB.getSize(),gCaliMB.getDt()); //Assignment per value, but wave is empty at this point
252
253
254 for(unsigned int i=0;i<gCaliMB.getSize(); ++i){
255 const double Time = gCaliMB.getTime(i);
256 if(Time<=t0){
257 predLArPhysWave.setSample(i,PhysWaveFunc->Eval(Time));
258 }
259 else{
260 predLArPhysWave.setSample(i,PhysWaveFunc->Eval(Time)-CALIWAVE_SHIFT);
261 }
262 }
263
265
266 // compute Mphys/Mcal
267 if ( m_normalizeCali ) {
268 // caliwave is normalized to 1 => Mcali = 1
269 MphysMcali = predLArPhysWave.getSample( wHelper.getMax(predLArPhysWave) ) ;
270 std::cout<<"Normalized: MphysMcali="<<MphysMcali<<std::endl;
271 } else {
272 MphysMcali = predLArPhysWave.getSample( wHelper.getMax(predLArPhysWave) ) /
273 gCaliMB.getSample( wHelper.getMax(gCaliMB) ) ;
274 }
275 ATH_MSG_VERBOSE ( "*** Physics waveform\t|-> m_MphysMcali = " << MphysMcali << " adc=" <<adc);
276
277 return ;
278}
279
280static Double_t P(Double_t *tt, Double_t *par)
281{
282 return par[1]*splin->Eval(*tt+par[0]);
283}
284
285static Double_t Rd(Double_t t)
286{
287 static Double_t res;
288
289 if(t<0 || t>tdr) return 0;
290
291 res = rc*((1+sc*al*tdr)*exp(-t*sc*al)-1) + rz*((1+sz*tdr)*exp(-t*sz)-1);
292 res += rs*((1+ss*tdr)*exp(-t*ss)-1) - 1;
293 res *= fs/tdr;
294
295 return res;
296}
297
298static Double_t Ro(Double_t t)
299{
300 static Double_t res;
301
302 if(t<tdr) return 0;
303
304 res = rc*((1+sc*al*tdr)*exp(-t*sc*al) - exp((tdr-t)*sc*al));
305 res += rz*((1+sz*tdr)*exp(-t*sz) - exp((tdr-t)*sz));
306 res += rs*((1+ss*tdr)*exp(-t*ss) - exp((tdr-t)*ss));
307 res *= fs/tdr;
308
309 return res;
310}
311
312Double_t Tc(Double_t t)
313{
314 static Double_t res;
315
316 if(t<t0) return 0;
317
318 res = splin->Eval(t);
319
320
321 return res;
322}
323
324
325Double_t DTp(Double_t *tt, Double_t *par)
326{
327 static Double_t res,t;
328
329 static TF1 *ff=NULL;
330 static TGraph *gg=NULL;
331 static Double_t xx[21],yy[21];
332 static Int_t j;
333
334 if(*tt < t0) return 0.;
335 t = *tt;
336
337 if(ff==NULL) ff=new TF1("ff","pol2",0.,800.);
338 if(gg==NULL) gg=new TGraph(11,xx,yy);
339
340
341 ff->SetRange(*tt-5.,*tt+5.);
342 for(j=-10; j<=10; ++j) {
343 res = t + j/2.;
344 gg->SetPoint(j+10,t+j/2.,Tp(&res,par));
345 }
346 if(gg->GetFunction("ff")) gg->GetFunction("ff")->Delete();
347 gg->Fit("ff","QRI0");
348 res = 2*t*ff->GetParameter(2) + ff->GetParameter(1);
349
350
351 return res;
352}
353
354Double_t Tp(Double_t *tt, Double_t *par)
355{
356 static Double_t res;
357 static Double_t t,t1,t4,t5;
358
359 if(*tt < t0 + par[0]) return 0;
360// if(par[0] < 0) return 0;
361
362 t = *tt - par[0];
363 taus = par[2];
364
365// Redefinition of poles
366
367 sp = 1/taup; s0 = 1/tau0; sz = 1/tauz; ss = 1/taus; sc = 1/tc;
368 //
369// Coefficients
370
371 rc = pow(al,3)*sc*sc + al*al*(-sc*sc-sc*s0-sc*sp);
372 rc += al*(sc*s0+sc*sp+sp*s0) - sp*s0;
373 rc /= -al*(al*al*sc*sc + al*(-sc*ss-sc*sz) + sz*ss);
374
375 rz = sz*sz*(sc+s0+sp) - pow(sz,3) - sz*sc*(s0+sp) + sp*s0*(sc-sz);
376 rz /= sz*(al*(-sc*sz+sc*ss) + sz*sz - sz*ss);
377
378 rs = -ss*ss*(sc+s0+sp-ss) + sc*ss*(s0+sp) + ss*sp*s0 - sc*sp*s0;
379 rs /= ss*(al*(-sc*sz+sc*ss) + sz*ss - ss*ss);
380
381 fs = sz*ss / (s0*sp);
382
383 t1 = fs*Tc(t);
384
385 t4 = Tp4(t); t5 = Tp5(t);
386 res = t1 + t4 + t5;
387
388 return par[1]*res;
389}
390
391Double_t Tp_gsl(Double_t *tt, Double_t *par)
392{
393 static Double_t res;
394 static Double_t t,t1,t4,t5;
395
396 if(*tt < t0 + par[0]) return 0;
397
398 t = *tt - par[0];
399 taus = par[2];
400
401// Redefinition of poles
402
403 sp = 1/taup; s0 = 1/tau0; sz = 1/tauz; ss = 1/taus; sc = 1/tc;
404 //
405// Coefficients
406
407 rc = pow(al,3)*sc*sc + al*al*(-sc*sc-sc*s0-sc*sp);
408 rc += al*(sc*s0+sc*sp+sp*s0) - sp*s0;
409 rc /= -al*(al*al*sc*sc + al*(-sc*ss-sc*sz) + sz*ss);
410
411 rz = sz*sz*(sc+s0+sp) - pow(sz,3) - sz*sc*(s0+sp) + sp*s0*(sc-sz);
412 rz /= sz*(al*(-sc*sz+sc*ss) + sz*sz - sz*ss);
413
414 rs = -ss*ss*(sc+s0+sp-ss) + sc*ss*(s0+sp) + ss*sp*s0 - sc*sp*s0;
415 rs /= ss*(al*(-sc*sz+sc*ss) + sz*ss - ss*ss);
416
417 fs = sz*ss / (s0*sp);
418
419 t1 = fs*Tc(t);
420
421 t4 = Tp4_gsl(t); t5 = Tp5_gsl(t);
422 res = t1 + t4 + t5;
423
424 return par[1]*res;
425}
426
427// version for GSL
428
429Double_t Tp4_gsl(Double_t t)
430{
431 static Double_t a,b;
432
433
434
435 //BEG: variables for QAWO
436 static double L;
437 static const double omega=0.0;
438 static const size_t n=100;
439 static const size_t limit=1001; // "n" must be < limit
440 static const double epsabs=0.0;
441 static double epsrel=1e-10;
442 double abserr;
443 static gsl_integration_workspace *w=0;
444 static gsl_integration_qawo_table *wf=0;
445 //END: variables for QAWO
446
447 struct gsl_f_params params = {t};
448 gsl_function gsl_func;
449
450 a = t - tdr;
451 if(a < t0) a = t0;
452 b = t;
453
454 //for gsl_integration_qawo:
455 L=b-a;
456 if(!w) w = gsl_integration_workspace_alloc(limit);
457 if(!wf) wf=gsl_integration_qawo_table_alloc(omega,L,GSL_INTEG_COSINE,n);
458
459 gsl_integration_qawo_table_set_length(wf, L);
460 //end of gsl_integration_qawo
461
462 gsl_func.function = &f4_gsl;
463 gsl_func.params = &params;
464 double result;
465
466 // set off automatic GSL error handling
467 gsl_set_error_handler_off();
468 // set integration precision
469 if(b>t0+130) epsrel=1e-8;
470 else epsrel=1e-10;
471
472 unsigned short int INTEGRAL_ITER=0;
473 const unsigned short int INTEGRAL_ITER_MAX=10;
474 int status=-1;
475
476 // compute integral with the starting high precision
477 while((status!=0 || INTEGRAL_ITER==0) && INTEGRAL_ITER<INTEGRAL_ITER_MAX){
478 status = gsl_integration_qawo (&gsl_func,a, epsabs, epsrel,limit,w,wf,&result,&abserr);
479
480 // if failes, descrease the precision
481 if(status == GSL_EROUND) epsrel*=10;
482 // if different error from GSL_EROUND, annonce integration ERROR
483 else if(status!=0){
485 std::cout<< "WARNING Tp4_gsl:QAWO ERROR (not roundoff): status="<<gsl_strerror(status)<<" ERRcode="<<status << " LArWaveFlag set to -1 !!"<< std::endl ;
486 status=0;
487 LArWaveFlag=-1;
489 }
490 INTEGRAL_ITER++;
491 }
492 //if iteration of integration reaches the limit (=> bad precision) set LArWaveFlag to -1
493 if(INTEGRAL_ITER==INTEGRAL_ITER_MAX && status!=0){
494 std::cout<<"WARNING Integration of Tp4_gsl FAILED !!!! #iterations reached the MAXIMUM!!! status="<<gsl_strerror(status)<<" ERRcode="<<status << " LArWaveFlag set to -1 !!"<<std::endl ;
495 LArWaveFlag=-1;
496 }
497
498
499 return result;
500
501}
502// Integrand for the Tp4 function
503// version for GSL
504static double f4_gsl(Double_t x, void *par)
505{
506 struct gsl_f_params * params = (struct gsl_f_params *)par;
507 static Double_t t;
508
509 t = params -> a;
510
511
512 return Tc(x) * Rd(t - x);
513}
514
515// version for GSL
516
517Double_t Tp5_gsl(Double_t t)
518{
519 if(t<t0 + tdr) return 0.;
520 Double_t b;
521
522
523
524 //BEG: variables for QAWO
525 static double L;
526 static const double omega=0.0;
527 static const size_t n=100;
528 static const size_t limit=1001; // "n" must be < limit
529 static const double epsabs=0.0;
530 static double epsrel = 1e-10;
531 double abserr;
532 static gsl_integration_workspace *w=0;
533 static gsl_integration_qawo_table *wf=0;
534 //END: variables for QAWO
535
536 struct gsl_f_params params = {t};
537 gsl_function gsl_func;
538 double a = 0.;
539 b = t - tdr;
540
541 //for gsl_integration_qawo:
542 L=b-a;
543 if(!w) w = gsl_integration_workspace_alloc(limit);
544 if(!wf) wf=gsl_integration_qawo_table_alloc(omega,L,GSL_INTEG_COSINE,n);
545
546 gsl_integration_qawo_table_set_length(wf, L);
547 //end of gsl_integration_qawo
548
549 gsl_func.function = &f5_gsl;
550 gsl_func.params = &params;
551
552
553
554 // set off automatic GSL error handling
555 gsl_set_error_handler_off();
556 // set integration precision
557 if(b>t0+60) epsrel=1e-8; // behinde the peak = tale region
558 else epsrel=1e-10; // peak/amplitude region
559
560 double result;
561 unsigned short int INTEGRAL_ITER=0;
562 const unsigned short int INTEGRAL_ITER_MAX=10;
563 int status=-1;
564
565 while((status!=0 || INTEGRAL_ITER==0) && INTEGRAL_ITER<INTEGRAL_ITER_MAX){
566 status = gsl_integration_qawo (&gsl_func,a, epsabs, epsrel,limit,w,wf,&result,&abserr);
567 // if failes, descrease the precision
568 if(status == GSL_EROUND) epsrel*=10;
569 // if different error from GSL_EROUND, annonce integration ERROR
570 else if(status!=0){
572 std::cout <<"WARNING: Tp5_gsl:QAWO ERROR (not roundoff): status="<<gsl_strerror(status)<<" ERRcode="<<status << " LArWaveFlag set to -1 !!"<< std::endl ;
573 status=0;
574 LArWaveFlag=-1;
576 }
577 INTEGRAL_ITER++;
578 }
579 //if iteration of integration reaches the limit (=> bad precision) set LArWaveFlag to -1
580 if(INTEGRAL_ITER==INTEGRAL_ITER_MAX && status!=0){
581 std::cout<<"WARNING: Integration of Tp5_gsl FAILED: #iterations reached the MAXIMUM!!!! status="<<gsl_strerror(status)<<" ERRcode="<<status << " LArWaveFlag set to -1 !!"<<std::endl ;
582 LArWaveFlag=-1;
583 }
584
585
586
587 return result;
588
589}
590
591// Integrand for the Tp5 function
592// version for the GSL
593
594static double f5_gsl(Double_t x, void *par)
595{
596 struct gsl_f_params * params = (struct gsl_f_params *)par;
597 static Double_t t;
598
599 t = params -> a;
600
601 return Tc(x) * Ro(t - x);
602}
603
604
606//version for the Gauss
607Double_t Tp4(Double_t t)
608{
609 static Double_t a,b;//, par[1];
610 static const Double_t epsrel = 0.001;
611 static TF1 *fun4 = NULL;
612
613 if(fun4 == NULL) fun4 = new TF1("fun4",&f4_g,0.,NMAX,1);
614
615 a = t - tdr;
616 b = t;
617
618
619 fun4->SetParameter(0,t);
620 return fun4->Integral(a,b,epsrel);
621
622}
623// Integrand for the Tp4 function
624// version for the Gauss
625static Double_t f4_g(Double_t *x, Double_t *par)
626{
627 static Double_t t;
628
629 t = par[0];
630
631 return Tc(*x) * Rd(t - *x);
632}
633
634// version for the Gauss
635Double_t Tp5(Double_t t)
636{
637 static Double_t b;//, par[1];
638 static const Double_t a = 0., epsrel = 0.001;
639 static TF1 *fun5 = NULL;
640
641 if(fun5 == NULL) fun5 = new TF1("fun5",&f5_g,0.,NMAX,1);
642
643 b = t - tdr;
644 fun5->SetParameter(0,t);
645 return fun5->Integral(a,b,epsrel);
646}
647
648// Integrand for the Tp5 function
649// version for the Gauss
650
651static Double_t f5_g(Double_t *x, Double_t *par)
652{
653 static Double_t t;
654
655 t = par[0];
656
657 return Tc(*x) * Ro(t - *x);
658}
659
661
662TF1 * LArPhysWaveHECTool::CaliWave2PhysWaveHEC(TProfile *pcal, Double_t *par, double *parCL, TF1 *& deriv,
663 Bool_t uset0, Bool_t norm, Int_t /*adc*/, Double_t */*xmax*/, bool gsl_flag){
664
665 TF1 *fitfun{}, *fu{};
666 Int_t i{},nbin{},nbino{},i5bin{},count{} ;
667 Double_t pampl{}, t5{}, mcut{}, rshift{}, rmult{};
668
669// Cables amplitude
670 a = 0.974;
671// Cables poles
672 tau0 = 1.5;
673// New value according to findings on Sept. 2001 run
674 taup = 19.5;
675 tauz = 18.;
676// Should be smaller
677 taus = 0.1;
678// Step amplitude
679
680 al=parCL[1]; // FT: can be exchanged with m_Fstep
681
682 tc=parCL[0]; // FT: can be exchanged with m_Tcal
683
684// Drift time
685// tdr = 440.;
686// New value:
687 tdr = 449.7;
688
689 nbino = nbin = pcal->GetNbinsX();
690 if(nbin>NMAX) nbin = NMAX;
691 if(nbino>NMAX) nbino = NMAX;
692
693 if(norm) {
694 normalize_prof(pcal,&pampl);
695 mcut = 0.05;
696 } else {
697 mcut = 0.05*pcal->GetMaximum();
698 }
699
700 cout<<"mcut: "<<mcut<<endl;
701 i5bin = 0;
702 for(i=1; i<=nbin; ++i) {
703 x[i-1] = pcal->GetBinCenter(i);
704 y[i-1] = pcal->GetBinContent(i);
705 if(i5bin == 0 && y[i-1] > mcut) i5bin = i;
706 };
707 //check access range
708 if (i5bin<2) {
709 printf("\n number of bins too small !\n");
710 return nullptr;
711 }
712 t5 = (mcut-y[i5bin-2])*(x[i5bin-1]-x[i5bin-2])/(y[i5bin-1]-y[i5bin-2]);
713 t5 += x[i5bin-2];
714//
715// t0 is app. 16.8 ns less than t5 (from reference shapes 2002)
716//
717 t0 = t5 - 16.8;
718
719
720 if(fabs((x[1] - x[0]) - (x[3] - x[2])) > 0.000001 ) {
721 cout<< x[0] << " " << x[1] << " " << x[2] << " " << x[3] << endl;
722 printf("\n Nonuniform step !\n");
723 return nullptr;
724 }
725
726 STEP = x[1] - x[0];
727
728
729 if(pref) delete [] pref;
730 pref = new Double_t[nbin];
731
732 count = 0;
733 for(i=0; i<nbin; ++i) {
734 if(x[i] < t0) {pref[i] = 0.; continue;}
735 double AmplPhys = m_gIdealPhys->getSample(count);
736 pref[i] = AmplPhys;
737 ++count;
738 if(count==(int)m_gIdealPhys->getSize()) break;
739 }
740 if(i<nbin) nbin = i+1;
741
742// Try to find the shift and mult. for reference signal
743 if(splin) delete splin;
744 splin = new TSpline3("sp",x,pref,nbin,"b1",0.);
745 fu = new TF1("fu",P,x[15],x[nbin-15],2);
746 fu->SetParName(0,"t0 shift");
747 fu->SetParLimits(0,-15.,15.);
748 fu->SetParName(1,"mult");
749 fu->SetParLimits(1,0.,10000.);
750 fu->SetParameters(5.,5.);
751
752 if( pcal->Fit("fu","RQ0") == 0) {
753 rshift = pcal->GetFunction("fu")->GetParameter(0);
754 rmult = pcal->GetFunction("fu")->GetParameter(1);
755 } else {
756 rshift = 0; rmult= pcal->GetMaximum()/ (* std::max_element(m_gIdealPhys->getWave().begin(), m_gIdealPhys->getWave().end()));
757 }
758
759 delete fu;
760// Read the reference again, shifting and multiplying:
761 count = 0;
762 for(i=0; i<nbin; ++i) {
763 if(x[i] < t0-rshift) {pref[i] = 0.; continue;}
764 double AmplPhys = rmult*m_gIdealPhys->getSample(count);
765 pref[i] = AmplPhys;
766 ++count;
767 if(count==(int)m_gIdealPhys->getSize()) break;
768 }
769 if(i<nbin) nbin = i+1;
770
771 if(uset0){
772 for(i=1; i<=nbin; ++i) x[i-1] -= t0;
773 t0 = 0.;
774 }
775 else {
776 for(i=1; i<=nbin; ++i) x[i-1] += par[0];
777 t0 += par[0];
778 }
779 par[0] = 0;
780 Smooth_new(x, y, pref, nbin);
781 if(splin) delete splin;
782 splin = new TSpline3("sp",x,pref,nbin,"b1",0.);
783
784 // gaus or GSL ?
785
786 if(!gsl_flag)
787 fitfun = new TF1("fitfun",&Tp,x[0],x[nbin-1],3);
788 else
789 fitfun = new TF1("fitfun",&Tp_gsl,x[0],x[nbin-1],3);
790
791 fitfun->SetParName(0,"t0 shift");
792 fitfun->SetParLimits(0,0.,100.);
793 fitfun->SetParName(1,"mult");
794 fitfun->SetParLimits(1,0.,100.);
795 fitfun->SetParName(2,"Taus");
796 fitfun->SetParLimits(2,0.1,10.);
797 fitfun->SetNpx(nbin+1);
798 fitfun->SetParameters(par[0],par[1],par[2]);
799 //std::cout<<"What happens before normalize?"<<std::endl;
800 if(norm) {
801 if(uset0)
802 normalize(fitfun, &pampl, 0., 100., STEP);
803 else
804 normalize(fitfun, &pampl, t0, t0+100., STEP);
805 }
806// Return also the derivative
807 deriv = new TF1("derivfun",&DTp,x[0],x[nbin-1],3);
808 deriv->SetParName(0,"t0 shift");
809 deriv->SetParLimits(0,0.,100.);
810 deriv->SetParName(1,"mult");
811 deriv->SetParLimits(1,0.,100.);
812 deriv->SetParName(2,"Taus");
813 deriv->SetParLimits(2,0.1,10.);
814 deriv->SetNpx(nbin+1);
815 deriv->SetParameters(par[0],par[1],par[2]);
816
817 if(norm) {
818 normalize(deriv, &pampl, t0+par[0], t0+par[0]+100., STEP);
819 }
820
821 return fitfun;
822}
823
824
825Double_t normalize(TF1 *func, Double_t *rampl,
826 Double_t from, Double_t to, Double_t step)
827{
828 static Double_t amax, tmax,t, ampl;
829 static Double_t t1,t2,tt1,tt2;
830 static Int_t i;
831
832 if((from == to) || (from > to))
833 func->GetRange(t1,t2);
834 else {
835 func->GetRange(tt1,tt2);
836 if(from>tt1) t1 = from; else t1 = tt1;
837 if(to<tt2) t2 = to; else t2 = tt2;
838 }
839
840 amax = 0; tmax = t1;
841 for(t=t1; t<=t2; t+=step)
842 {
843 if(func->Eval(t) > amax) {
844 amax = func->Eval(t); tmax = t;
845 }
846 }
847 Double_t x[20], y[20];
848 i=0;
849 for(t=tmax-5; t<tmax+5; ++t) {
850 x[i] = t;
851 y[i] = func->Eval(t);
852 ++i;
853 }
854 TGraph *g = new TGraph(10,x,y);
855 g->Fit("pol2","QIE0");
856 tmax = - g->GetFunction("pol2")->GetParameter(1) / (2 *g->GetFunction("pol2")->GetParameter(2));
857 amax = g->GetFunction("pol2")->Eval(tmax);
858
859 ampl = func->GetParameter(1);
860 if(amax != 0) func->SetParameter(1,ampl/amax);
861 else tmax = 0;
862 cout << "Normalize: tmax="<<tmax << " ampl=" << ampl<<" amax="<<amax << endl;
863 if(rampl != NULL) *rampl = amax;
864 g->Delete();
865 return tmax;
866}
867
868Double_t normalize_prof(TProfile *histo, Double_t *rampl)
869{
870 Double_t amax, tmax, x, y, err;
871 Int_t nbins,i, j, nent;
872 amax = histo->GetBinContent(0);
873 tmax = histo->GetBinCenter(0);
874 nbins = histo->GetNbinsX();
875 for(i=1; i<nbins; i++)
876 {
877 if(amax < histo->GetBinContent(i))
878 {
879 amax = histo->GetBinContent(i);
880 tmax = histo->GetBinCenter(i);
881 }
882 }
883
884 histo->Fit("pol2","0QI","",tmax-10., tmax+10.);
885 tmax = - histo->GetFunction("pol2")->GetParameter(1) / (2 * histo->GetFunction("pol2")->GetParameter(2));
886 amax = histo->GetFunction("pol2")->Eval(tmax);
887 TProfile *htmp = new TProfile(*histo);
888 histo->Reset();
889 for(i=0; i<=nbins; i++)
890 {
891 if(htmp->GetBinEntries(i) == 0) continue;
892 x = htmp->GetBinCenter(i);
893 y = htmp->GetBinContent(i);
894 nent=int(htmp->GetBinEntries(i));
895 err = htmp->GetBinError(i);
896// Hack for stupid root v.3, which do not like the one entries in profile histo
897 for(j=0; j<7; ++j) {
898 if(nent != 0) {
899 histo->Fill(x,y/amax+sqrt(2)*err/nent);
900 histo->Fill(x,y/amax-sqrt(2)*err/nent);
901 } else {
902 histo->Fill(x,y/amax+sqrt(2)*err);
903 histo->Fill(x,y/amax-sqrt(2)*err);
904 }
905 }
906 }
907
908 if(rampl != NULL) *rampl = amax;
909
910 return tmax;
911}
912void SmootKern(Double_t *x, Double_t *y, Int_t ymax, Double_t band)
913{
914 Double_t *xx, *yy;
915 TGraph *g=new TGraph(ymax,x,y);
916 TGraphSmooth *gs = new TGraphSmooth();
917 TGraph *g1 = gs->SmoothKern(g,"normal",band);
918 xx = g1->GetX(); yy = g1->GetY();
919 for(Int_t i=0; i<g->GetN(); ++i) {
920 x[i] = xx[i]; y[i] = yy[i];
921 }
922 delete g; delete gs;
923}
924
925void Smooth_new(Double_t *x, Double_t *y, Double_t *yref, Int_t ymax)
926{
927// Smoothing the difference between the yref and y,
928// then y = y + smoothed differnce
929// repeating few times
930 static Double_t *dif = NULL;
931 static Int_t i,j;
932
933 if(dif) delete[] dif;
934 dif = new Double_t[ymax];
935 for(j=0; j<4; ++j) {
936 for(i=0; i<ymax; ++i) dif[i] = y[i] - yref[i];
937 SmootKern(x,dif,ymax, 10.);
938 for(i=0; i<ymax; ++i) yref[i] += dif[i];
939 }
940}
941
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static boost::dynamic_bitset rshift(boost::dynamic_bitset<> const &b, int n)
std::pair< std::vector< unsigned int >, bool > res
void Smooth_new(Double_t *x, Double_t *y, Double_t *yref, Int_t ymax)
static Double_t Tp4_gsl(Double_t t)
static Double_t f4_g(Double_t *x, Double_t *par)
int Tp4_gsl_err_counter
static Double_t sp
int LArWaveFlag
static double f4_gsl(double x, void *par)
static Double_t tauz
static TSpline3 * splin
static Double_t taus
const int NMAX
static Double_t DTp(Double_t *t, Double_t *par)
static Double_t rs
static Double_t Tp_gsl(Double_t *t, Double_t *par)
static Double_t sz
static Double_t Tp5(Double_t t)
static Double_t Tc(Double_t t)
static Double_t Tp5_gsl(Double_t t)
Double_t normalize(TF1 *func, Double_t *rampl=NULL, Double_t from=0., Double_t to=0., Double_t step=1.)
static Double_t taup
static Double_t s0
Double_t normalize_prof(TProfile *histo, Double_t *rampl=NULL)
static Double_t Tp4(Double_t t)
static Double_t a
static Double_t fs
static double f5_gsl(double x, void *par)
static Double_t Rd(Double_t t)
static Double_t ss
static Double_t tc
static Double_t f5_g(Double_t *x, Double_t *par)
static Double_t tdr
static Double_t * pref
static Double_t al
static Double_t Tp(Double_t *t, Double_t *par)
static Double_t Ro(Double_t t)
void SmootKern(Double_t *x, Double_t *y, Int_t ymax, Double_t band=10.)
static Double_t P(Double_t *tt, Double_t *par)
static Double_t sc
int Tp5_gsl_err_counter
static Double_t rc
static Double_t rz
static Double_t t0
static Double_t tau0
#define STEP(f, a, b, c, d, x, t, s)
Definition MD5.cxx:121
@ baseline
#define DIFF(_name, _a, _b)
#define y
#define x
constexpr int pow(int base, int exp) noexcept
#define ATLAS_NO_CHECK_FILE_THREAD_SAFETY
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)
const ServiceHandle< StoreGateSvc > & detStore() const
Helper for the Liquid Argon Calorimeter cell identifiers.
TF1 * CaliWave2PhysWaveHEC(TProfile *pcal, Double_t *par, double *parCL, TF1 *&deriv, Bool_t uset0, Bool_t norm, int adc, Double_t *xmax, bool gsl_flag)
LArPhysWaveHECTool(const std::string &type, const std::string &name, const IInterface *parent)
const LArOnlineID_Base * m_onlineHelper
const LArPhysWave * m_gIdealPhys
void predict_phys_HEC(LArWFParams &wfParams, LArCaliWave &caliWave, LArPhysWave &predLArPhysWave, float &MphysMcali, const HWIdentifier &chid, const int gain)
StatusCode makeLArPhysWaveHEC(LArWFParams &wfParams, LArCaliWave &caliWave, LArPhysWave &predLArPhysWave, const LArPhysWave &LArIdealPhysWave, float &MphysMcali, const HWIdentifier &chid, const int gain, int &LArPhysWaveFlag)
virtual StatusCode initialize()
static const int DEFAULT
void setFstep(double fstep)
double tdrift() const
void setTcal(double tcal)
double fstep() const
double tcal() const
LArWave translate(const LArWave &theWave, int nShift, double baseline=0.) const
double getBaseline(const LArWave &theWave, unsigned nBase) const
unsigned int getMax(const LArWave &theWave) const
return index of maximum sample
unsigned getStart(const LArWave &theWave) const
double getTime(const unsigned i) const
time
Definition LArWave.h:172
void setSample(const unsigned i, const double aVal)
set the amplitude for time bin i
Definition LArWave.h:87
size_t getSize() const
number of time samples
Definition LArWave.h:62
@ predCali
Definition LArWave.h:129
const double & getSample(const unsigned int i) const
Amplitude per time bin.
Definition LArWave.h:53
const double & getDt() const
delta time
Definition LArWave.h:50
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
double xmax
Definition listroot.cxx:61
double ymax
Definition listroot.cxx:64