ATLAS Offline Software
Loading...
Searching...
No Matches
ZdcRecChannelTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5/*
6 * ZdcRecChannelTool.cxx
7 *
8 * Created on: Nov 24, 2009
9 * Author: leite
10 */
11
12
13#include <iostream>
14#include <fstream>
15
16#include <valarray>
17#include <numeric>
18#include <algorithm>
19#include <functional>
20#include <vector>
21#include <map>
22
23#include <cmath>
24
25#include "TMath.h"
26
27#include "GaudiKernel/IInterface.h"
28#include "GaudiKernel/MsgStream.h"
29
30#include "ZdcEvent/ZdcDigits.h"
34#include "ZdcIdentifier/ZdcID.h"
36
38
39//Interface Id for retrieving the tool
40//Consider creating a factory class and define the interface
41static const InterfaceID IID_IZdcRecChannelTool("ZdcRecChannelTool", 1, 1);
42
43//==================================================================================================
45{
47
48}
49//==================================================================================================
50
51//==================================================================================================
53 const std::string& name,
54 const IInterface* parent) :
55 AthAlgTool(type, name, parent),
57 m_nsamples(7),
58 m_sample_time (25.),
59 m_cfd_fraction (0.35),
60 m_cfd_delay (20.)
61
62{
63 //Declare properties here...
64
65 declareInterface<ZdcRecChannelTool>(this);
66
67 declareProperty("ZeroSuppress", m_zeroSupress = 0,
68 "Supress channels with only 0");
69
70 declareProperty("DeltaPeak", m_delta = 5,
71 "Minimum difference between min and max to be considered a signal");
72
73
74}
75//==================================================================================================
76
77//==================================================================================================
81//==================================================================================================
82
83
84//==================================================================================================
86{
87 msg(MSG::INFO) << "Initializing " << name() << endmsg;
88
89 //Get the pedestal information for the channels.
90 //For now, this is a file; later on it will be moved to a database
91
92
93 // Bandwidth interpolation method initializations
94 // making sure we use only 50 ps steps for the resolution
95
98
100
101 m_wfm_bwl.resize(s);
102
103 msg(MSG::INFO) << "Using a time step of "
105 << "ps for the Bandwidth Limited Sin(x)/x Interpolation: "
106 << " Vector Size = "
107 << s
108 << endmsg;
109
110
111
112
113 // GSL Interpolation functions initializations
114 m_interp_acc = gsl_interp_accel_alloc ();
115 // Thread-safe according to https://www.gnu.org/software/gsl/doc/html/roots.html
116 const gsl_interp_type *interp_type ATLAS_THREAD_SAFE = gsl_interp_akima;
117 m_spline = gsl_spline_alloc (interp_type, 14); //FIXME: TWICE THE SAMPLES
118
119 //Load Mapping
120 msg(MSG::DEBUG) << "--> ZDC : START OF MODIFICATION 0" << endmsg ;
121
122 const ZdcID* zdcId = nullptr;
123 if (detStore()->retrieve( zdcId ).isFailure() ) {
124 msg(MSG::ERROR) << "execute: Could not retrieve ZdcID object from the detector store" << endmsg;
125 return StatusCode::FAILURE;
126 }
127 else {
128 msg(MSG::DEBUG) << "execute: retrieved ZdcID" << endmsg;
129 }
130 m_zdcId = zdcId;
131
132 msg(MSG::DEBUG) << "--> ZDC : END OF MODIFICATION 0" << endmsg ;
133 return StatusCode::SUCCESS;
134}
135//==================================================================================================
136
137//==================================================================================================
139{
140 msg(MSG::INFO) << "Finalizing " << name() << endmsg;
141
142 gsl_spline_free (m_spline);
143 gsl_interp_accel_free (m_interp_acc);
144
145 return StatusCode::SUCCESS;
146}
147//==================================================================================================
148
149//Returns a pointer to a RawChannel Collection with energy and time
150//==================================================================================================
152 const ZdcDigitsCollection& mydata,
153 ZdcRawChannelCollection & ChannelCollection)
154
155{
156 //ZdcRawChannel *z;
157 Identifier id;
158 float soma = 0.;
159 float pico = 0.;
160 float tzc = 0.;
161 float tsr = 0.;
162 float t0 = 0.;
163 float t1 = 0.;
164 float m = 0.;
165
166 //bool pp = false;
167 int i = 0;
168 //int j = 0;
169 int k = 0;
170 //int s = 0;
171 int ped = 0;
172 int imax = 0;
173
174 int mSide = 0;
175 int mModule = 0;
176 int mType = 0;
177 int mChannel = 0;
178
179 int ncha = 0;
180
181
182 //TODO use BOOST containers here, more flexible and inteligent, and it will
183 // nevertless stay inside this method, so no fussing with complex collections
184
185 std::vector<std::vector<int> > wfm;
186 std::vector<std::vector<int> >::iterator vit;
187 std::vector<int>::iterator it;
188
189 std::vector<float> energy_sum;
190 std::vector<float> energy_peak;
191 std::vector<float> time_cfd;
192 std::vector<float> time_sratio;
193 std::vector<float> chi;
194
195 std::vector<int> v;
196 std::vector<int> vd;
197 std::vector<int> vi;
198
199 std::vector<float> vcfd1;
200 std::vector<float> vcfd2;
201 std::vector<float> vcfd3;
202
203 //Identifier::value_type zId;
204
205
206 // Main procedure: Reduce the data to energy and time, and store it into
207 // ZdcRawDataCollection
208
209 //digits_p = *mydata.begin();
210 //nsamples = digits_p->m_nSamples;
211 //vi.resize(2*nsamples);
212 vi.resize(14);
213
214 for (const ZdcDigits* digits_p : mydata) {
215
216 msg(MSG::DEBUG) << "--> ZDC : START OF MODIFICATION " << endmsg ;
217 id = digits_p->identify();
218 mSide = m_zdcId->side(id);
219 mModule = m_zdcId->module(id);
220 mType = m_zdcId->type(id);
221 mChannel = m_zdcId->channel(id);
222
223 msg(MSG::DEBUG) << "--> ZDC : ZdcRecChannelTool::makeRawFromDigits: "
224 << " id;Side;Module;Type;Channel: "
225 << id.getString() << ";"
226 << mSide << ";"
227 << mModule << ";"
228 << mType << ";"
229 << mChannel << endmsg;
230
231
232 //1) Check the high gain. If it has saturation (max = FADC_SATURATION)
233 // drop and use the low gain
234 //
235 wfm.clear();
236 wfm.resize(2);
237 energy_sum.clear();
238 energy_peak.clear();
239 time_cfd.clear();
240 time_sratio.clear();
241 chi.clear();
242
243 wfm[0] = digits_p->get_digits_gain0_delay0();
244 if (wfm[0].empty()) {
245 msg(MSG::DEBUG) << "ZERO SIZE g0d0 at ID " << id.getString() << endmsg;
246 wfm[0].resize(7);
247 }
248
249 wfm[1] = digits_p->get_digits_gain1_delay0();
250 if (wfm[1].empty()) {
251 msg(MSG::DEBUG) << "ZERO SIZE g1d0 at ID " << id.getString() << endmsg;
252 wfm[1].resize(7);
253 }
254
255
256 msg(MSG::DEBUG) << " ------- 1 " << endmsg;
257
258 //2) Check to see if there are delayed information
259 // module type 0 -> (full Energy) delayed info
260 // module type 1 -> (segmented) do not have delayed info
261 // - use the identifiers here -
262 //
263 //if (((id.get_identifier32().get_compact() >> 21) & 1) == 0) {
264
265 //zId = id.get_identifier32().get_compact();
266
267 //Only type 0 (Total Module Energy) has delay information
268 //if ( ( (zId == 0xec000000) || (zId == 0xed000000) ||
269 // (zId == 0xec200000) || (zId == 0xed200000) ||
270 // (zId == 0xec400000) || (zId == 0xed400000) ||
271 // (zId == 0xec600000) || (zId == 0xed600000) ) ) {
272 if (mType == 0) {
273 //std::cout << "*** Resize 4 at Id " << zId << std::endl ;
274 wfm.resize(4);
275 wfm[2] = digits_p->get_digits_gain0_delay1();
276 wfm[3] = digits_p->get_digits_gain1_delay1();
277 }
278
279
280
281
282 msg(MSG::DEBUG) << " ------- 2 " << endmsg;
283 //3) Subtratct baseline pedestal
284 //We need to be carefull. Sometimes the vector size here is zero (PPM flaw) and
285 //the code crashs if we do not treat this.
286 i = 0;
287 for (vit = wfm.begin(); vit<wfm.end(); ++vit) {
288 if (vit->empty()) vit->resize(7);
289 ped = *vit->begin();
290 for (it=vit->begin(); it<vit->end();++it) {
291 (*it) -= ped;
292 //if ((i==1) || (i==3) ) (*it) = (*it) * s_GAIN_RATIO;
293 }
294 i++;
295 }
296 /*
297 if (((id.get_identifier32().get_compact() >> 21) & 1) == 0) {
298 if ( ( *(std::max_element(wfm[0].begin(),wfm[0].end()) ) > 300 ) ||
299 ( *(std::max_element(wfm[1].begin(),wfm[1].end()) ) > 300 ) ||
300 ( *(std::max_element(wfm[2].begin(),wfm[2].end()) ) > 300 ) ||
301 ( *(std::max_element(wfm[3].begin(),wfm[3].end()) ) > 300 ) ) {
302 //std::cout << "&&&&& OVFLW &&&&&" << std::endl;
303 msg(MSG::DEBUG) << "%%%%%%%% ID " << id.getString() << endmsg;
304 msg(MSG::DEBUG) << "%%%%%%%% g0d0 " << wfm[0] << endmsg;
305 msg(MSG::DEBUG) << "%%%%%%%% g1d0 " << wfm[1] << endmsg;
306 msg(MSG::DEBUG) << "%%%%%%%% g0d1 " << wfm[2] << endmsg;
307 msg(MSG::DEBUG) << "%%%%%%%% g1d1 " << wfm[3] << endmsg;
308
309 }
310 }
311 else {
312 if ( ( *(std::max_element(wfm[0].begin(),wfm[0].end()) ) > 20 ) ||
313 (*(std::max_element(wfm[1].begin(),wfm[1].end()) ) > 20 ) ) {
314 //std::cout << "**** g1d0 OVFLW ****" << std::endl;
315 msg(MSG::DEBUG) << "******** ID " << id.getString() << endmsg;
316 msg(MSG::DEBUG) << "******** g0d0 " << wfm[0] << endmsg;
317 msg(MSG::DEBUG) << "******** g1d0 " << wfm[1] << endmsg;
318
319 }
320 }
321 */
322 msg(MSG::DEBUG) << " ------- 3 " << endmsg;
323 //4) Calculate the quantities of interest. For now it will be Energy (by SUM and Peak)
324 // and timing (using undelayed, delayed and combined)
325 // Include a quality factor chi which will follow design definitions for
326 // chi < 0 -> something very bad (for example saturation)
327 // 0 >= chi >= 1 -> depends on the algorithm to be used; 1 is very good
328
329 k = 0;
330
332 // GSL for CFD Timing
334
335 getTimingCFD(id, wfm);
336
338 // Sinx/x Timing (GSL)
340 // Not yet needed
341 //getTimingSinc(id, wfm);
342
343
345 // Sinx/x Timing (Andrei's coding)
347
348 getTimingSinc2(id, wfm);
349
354 for (vit = wfm.begin(); vit<wfm.end(); ++vit) {
355 v = *vit;
356 soma = std::accumulate(v.begin(), v.end(), 0) ;
357 pico = *(std::max_element(v.begin(),v.end()) );
358 energy_sum.push_back ((float) soma);
359 energy_peak.push_back((float) pico);
360 if (pico >= (s_FADC_SATURATION -42)) {
361 chi.push_back(-1);
362 }
363 else {
364 chi.push_back(0); //nothing to say here
365 }
366
367
368 // Now, lets also calculate the timing by the ratio of the
369 // second to the third sample. Because the correction is module
370 // dependent, we postpone the calibration to the next stage
371 // Time will be
372 // t = (r-R0)/(R1-R0) ns
373 // where r = v[imax -1]/v[imax], (imax = peak)
374 // R0, R1 are constants that depends on the module
375
376 // Get the position of the maximum
377 // Take care of div by 0
378 imax = std::max_element(v.begin(),v.end()) - v.begin();
379 if ((v[imax] != 0) && (imax>0)) {
380 tsr = ((float) v[imax-1])/v[imax];
381 }
382 else {
383 tsr = v[imax];
384 }
385
386 time_sratio.push_back(tsr);
387
388
389 msg(MSG::DEBUG) << "--> ZDC : ZdcRecChannelTool " << id.getString() <<
390 " Type=" << k <<
391 " Energy Sum=" << soma <<
392 " Energy Peak=" << pico <<
393 " Chi=" << *(chi.end() -1) <<
394 " t0=" << t0 << " t1=" << t1 <<
395 " m=" << m <<
396 " Time by CFD=" << tzc <<
397 " Peak at imax = " << imax <<
398 " v[imax-1] = " << (imax > 0 ? v[imax-1] : 0) <<
399 " V[imax] = " << v[imax] <<
400 " Sample Ratio A1/A2=" << tsr << endmsg;
401 k++;
402 }
403
404 msg(MSG::DEBUG) << " ------- 5 " << endmsg;
405 ZdcRawChannel *z = new ZdcRawChannel(id);
406
407 msg(MSG::DEBUG) << "CFD EXACT***** ID "<< id.getString() << m_cfd_result << endmsg;
408 msg(MSG::DEBUG) << "CFD APPRO***** ID "<< id.getString() << m_bwl_tpeak << endmsg;
409
410 z->setSize(3*k); //FIXME very important, but not smart move ...
411 /*
412 * What can go here:
413 *
414 * energy_peak -> max sample peak
415 * energy_sum -> sum of samples
416 * time_sratio -> from ratio of samples
417 *
418 * m_bwl_vpeak -> Energy peak from sinc interpolation
419 * m_bwl_tpeak -> Time at peak from sinc interpolation
420 *
421 * m_bwl_vpeak2 -> Energy peak from sinc interpolation (AP code)
422 * m_bwl_tpeak2 -> Time at peak from sinc interpolation (AP code)
423 *
424 * m_cfd_result -> timing by software CFD
425 */
426 for (i=0;i<k;i++) {
427 z->setEnergy (i, energy_peak[i]);
428 z->setTime (i, time_sratio[i]);
429 z->setChi (i, chi[i]);
430
431 z->setEnergy (i+k, m_bwl_vpeak2[i]);
432 z->setTime (i+k, m_bwl_tpeak2[i]);
433 z->setChi (i+k, chi[i]);
434
435 z->setEnergy (i+2*k, energy_sum[i]);
436 z->setTime (i+2*k, m_cfd_result[i]);
437 z->setChi (i+2*k, chi[i]);
438
439 //z->setEnergy(i+k, energy_peak[i]);
440 //z->setTime(i,time_cfd[i]);
441
442
443 }
444 ncha++;
445 ChannelCollection.push_back(z);
446 msg(MSG::DEBUG) << " ------- 6 " << endmsg;
447 }
448 msg(MSG::DEBUG) << "--> ZDC : ZdcRecChannelTool ChannelCollection size " << ChannelCollection.size() << endmsg ;
449 return ncha;
450}
451
452
453
454//==================================================================================================
455
456//==================================================================================================
458 const ZdcDigitsCollection& mydata,
459 ZdcRawChannelCollection & ChannelCollection)
460{
461 int ncha = 0;
462 for (const ZdcDigits* digits_p : mydata) {
463 digits_p->identify();
464 ncha++;
465 }
466 int ncal = ChannelCollection.size();
467 msg(MSG::DEBUG) << " Zdc ---> Calibration for " << ncal << " channels " << endmsg;
468 return ncha;
469}
470//==================================================================================================
471
472//==================================================================================================
473int ZdcRecChannelTool::getTimingCFD(const Identifier& id, const std::vector<std::vector <int> >& wfm )
474{
475
476 unsigned int i = 0;
477 //unsigned int j = 0;
478 unsigned int nsamples_local = 14;
479 double v[14];
480 double t[14];
481 double td[14];
482 double vd[14];
483 double vf[14];
484
485 std::vector<float> vaux;
486 unsigned int tmin = 0;
487 unsigned int tmax = 0;
488
489 double x_lo = 0.0;
490 double x_hi = 200.0;
491 float r = 0;
492 int status = 0;
493
494 int iterations = 0;
495 int max_iterations = 100;
496
497 // Thread-safe according to https://www.gnu.org/software/gsl/doc/html/roots.html
498 const gsl_root_fsolver_type *T ATLAS_THREAD_SAFE = gsl_root_fsolver_brent;
499 gsl_root_fsolver *s = gsl_root_fsolver_alloc (T);
500 gsl_function F;
501
502 CCallbackHolder cc{};
503
504
505 std::vector<int> y;
506
507 std::vector<std::vector<int> >::const_iterator vit;
508 std::vector<int>::iterator it;
509
510 std:: vector<float> result;
511
512 m_cfd_result.clear();
513
514 msg(MSG::DEBUG) << "--> ZDC : ZdcRecChannelTool::getTimingCFD: Id " << id.getString() ;
515
516 for (i=0;i<14;i++) {
517 t[i] = 0.;
518 td[i] = 0.;
519 v[i] = 0.;
520 vd[i] = 0.;
521 vf[i] = 0.;
522 }
523
524 for (vit = wfm.begin(); vit<wfm.end(); ++vit) {
525 y = *vit;
526 i = 4;
527 for (it=y.begin();it != y.end();++it) {
528 v[i] = *it;
529 i++;
530 }
531 for (i=0;i<nsamples_local;i++) {
532 t[i] = m_sample_time*i ; //TODO: Do it only once somewhere else
533 td[i] = t[i]-m_cfd_delay;
534 }
535
536 gsl_spline_init (m_spline, t, v, nsamples_local);
537
538
539
540 for (i=0;i<nsamples_local;i++) {
541 vd[i] = gsl_spline_eval (m_spline, td[i], m_interp_acc);
542 vf[i] = vd[i] - v[i]* m_cfd_fraction;
543 }
544
545 //gsl_spline_free (m_spline); // Not sure if this is necessary
546
547 gsl_spline_init (m_spline, t, vf, nsamples_local);
548
549 cc.cls = this;
551 F.params = &cc;
552
553
554
555
556 //Get the range for root finding
557 vaux.assign(vf,vf+14);
558 tmin = std::min_element(vaux.begin(), vaux.end()) - vaux.begin();
559 tmax = std::max_element(vaux.begin(), vaux.end()) - vaux.begin();
560 if (tmin < tmax)
561 {
562 x_lo = t[tmin];
563 x_hi = t[tmax];
564 }
565 else
566 {
567 x_lo = t[tmax];
568 x_hi = t[tmin];
569 }
570 //std::cout << "::::::::::tmin,tmax " << x_lo << " " << x_hi << std::endl;
571
572 /*
573 std::cout << "::::::::::V " << id.getString() << " "<< j << " " ;
574 for (i=0;i<nsamples_local;i++) {
575 std::cout << v[i] << " " ;
576 }
577 std::cout << std::endl;
578
579 std::cout << "::::::::::VD " << id.getString() << " "<< j << " " ;
580 for (i=0;i<nsamples_local;i++) {
581 std::cout << vd[i] << " " ;
582 }
583 std::cout << std::endl;
584
585 std::cout << "::::::::::VF " << id.getString() << " "<< j << " " ;
586 for (i=0;i<nsamples_local;i++) {
587 std::cout << vf[i] << " " ;
588 }
589 std::cout << std::endl;
590 */
591 //j++;
592
593 gsl_root_fsolver_set (s, &F, x_lo, x_hi);
594
595 iterations = 0;
596 do
597 {
598 iterations++;
599 status = gsl_root_fsolver_iterate(s);
600 r = gsl_root_fsolver_root(s);
601 x_lo = gsl_root_fsolver_x_lower(s);
602 x_hi = gsl_root_fsolver_x_upper(s);
603 status = gsl_root_test_interval (x_lo, x_hi, 0, 0.001);
604 //if (status == GSL_SUCCESS) printf ("Converged:\n");
605 }
606
607 while (status == GSL_CONTINUE && iterations < max_iterations);
608 //std::cout << " COnvergence ----> " << iterations << " " << r << " " << x_lo << " " << x_hi << std::endl;
609 m_cfd_result.push_back(r-100); //subtraction accounts for zero padding
610 }
611 gsl_root_fsolver_free (s);
612 return 0;
613}
614//==================================================================================================
615
616//==================================================================================================
617double ZdcRecChannelTool::fx(double x0, void *params)
618 {
619 ZdcRecChannelTool* p = static_cast<ZdcRecChannelTool*>(params);
620 //std::cout << " MMMMMMMMMMMMAAAAAAAAA " << p->m_cfd_delay << std::endl;
621 return gsl_spline_eval (p->m_spline, x0, p->m_interp_acc);
622 }
623//==================================================================================================
624
625/*BW limited signal interpolation by sin(t)/t
626 * This method returns the peak value and the peak time by interpolating a vector
627 * in 50 ps step (which will be the resolution). For this resolution, the vector size is
628 * calculated as vsize = m_nsamples * s_SAMPLING_TIME/m_bwl_time_resolution. To avoid
629 * too small steps, only steps of 50 ps are allowed in this (for now).
630 */
631
632//==================================================================================================
633int ZdcRecChannelTool::getTimingSinc(const Identifier& id, const std::vector<std::vector <int> >& wfm )
634{
635 unsigned int i = 0;
636 unsigned int k = 0;
637 int t = 0;
638 int tpeak = 0;
639 float tfpeak = 0.;
640 float vpeak = 0.;
641 float x = 0.;
642 float z = 0.;
643 float t_cor = 0. ;
644 int mSide = 0;
645 int mModule = 0;
646 int mType = 0;
647 int mChannel = 0;
648 int do_tcor = false;
649
650
651 std::vector<float> vt(7);
652 std::vector<int> y;
653
654 std::vector<float>::iterator vf_it;
655 std::vector<std::vector<int> >::const_iterator vvi_it;
656
657 //initialize the vectors
658 m_bwl_vpeak.resize(4,0);
659 m_bwl_tpeak.resize(4,0);
660
661 //zId = id.get_identifier32().get_compact();
662 msg(MSG::DEBUG) << "--> ZDC : START OF MODIFICATION 2 " << endmsg ;
663 mSide = m_zdcId->side(id);
664 mModule = m_zdcId->module(id);
665 mType = m_zdcId->type(id);
666 mChannel = m_zdcId->channel(id);
667 msg(MSG::DEBUG) << "--> ZDC : ZdcRecChannelTool::getTimingSinc: "
668 << " id;Side;Module;Type;Channel: "
669 << id.getString() << ";"
670 << mSide << ";"
671 << mModule << ";"
672 << mType << ";"
673 << mChannel << endmsg;
674
675 for (vvi_it = wfm.begin(); vvi_it<wfm.end(); ++vvi_it) {
676 //FIXME: Change to the method of ID identification
677 //if ((zId == 0xec000000) || (zId == 0xed000000) ||
678 // (zId == 0xec200000) || (zId == 0xed200000) ||
679 // (zId == 0xec400000) || (zId == 0xed400000) ||
680 // (zId == 0xec600000) || (zId == 0xed600000) )
681 // {
682 if (mType == 0) {
683
684 y = *vvi_it;
685
686 t = 0;
687 //Fill the interpolated vector
688 for (vf_it = m_wfm_bwl.begin(); vf_it != m_wfm_bwl.end(); ++vf_it ) {
689 z = 0.;
690 for (i=0;i<m_nsamples;i++) {
691 x = (TMath::Pi() *(t*0.1 - i*25.))/25. ;
692 if (fabs(x) < 1e-8) {
693 z = z + y[i]*1.0;
694 }
695 else {
696 z = z + y[i]*(sin(x)/(x));
697 }
698 }
699 *vf_it = z;
700 //if (id.get_identifier32().get_compact() == 0xec400000) {
701 //std::cout << "========== " << t << " " << *vf_it << std::endl;
702 //}
703 t++;
704 }
705
706 //Get The maximum and the position of the peak
707 tpeak = std::max_element(m_wfm_bwl.begin(),m_wfm_bwl.end()) - m_wfm_bwl.begin();
708 vpeak = m_wfm_bwl[tpeak];
709
710 //Account for 100 ps step
711 tfpeak = tpeak/10.;
712
713
714 //The correction for non-linear behavior
715 //Right now only two channels implemented:
716 //First hadronic modules for A and C sides
717 //zId = id.get_identifier32().get_compact();
718
719 //Side C, Mod 0, Low Gain
720 //if (id.get_compact() == 0xec400000) {
721 if ( (mSide == -1) && (mType == 0) && (mModule == 0) && (mChannel == 0) ) {
722 t_cor = -777.277 +
723 33.685 * tfpeak +
724 -0.483265 * pow(tfpeak,2) +
725 0.00234842 * pow(tfpeak,3);
726 }
727
728 //Side A, Mod 0, Low Gain
729 //if (id.get_compact() == 0xed400000) {
730 if ( (mSide == 1) && (mType == 0) && (mModule == 0) && (mChannel == 0) ) {
731 //piecewise fit
732 if (tfpeak <= 68) {
733 t_cor = -1749.27 +
734 80.5426 * tfpeak +
735 -1.229 * pow(tfpeak,2) +
736 0.006276 * pow(tfpeak,3);
737 }
738 else {
739 t_cor = -1965.52 +
740 84.0379 * tfpeak +
741 -1.19169 * pow(tfpeak,2) +
742 0.005659 * pow(tfpeak,3);
743 }
744 }
745
746 if (do_tcor) m_bwl_tpeak[k] = t_cor;
747 else m_bwl_tpeak[k] = tpeak;
748 m_bwl_vpeak[k] = vpeak;
749 }
750 else {
751 m_bwl_tpeak[k] = -999;
752 m_bwl_vpeak[k] = -999;
753 }
754 k++;
755 }
756 return k;
757}
758//==================================================================================================
759
760/*BW limited signal interpolation by sin(t)/t
761 * Andrei Poblaguev implementation
762 */
763//==================================================================================================
764int ZdcRecChannelTool::getTimingSinc2(const Identifier& id, const std::vector<std::vector <int> >& wfm )
765{
766 int i = 0;
767 int wfmIndex = 0;
768 //float energy = 0.;
769 //float w = 0.;
770 //float timing = 0.;
771 int error = 0;
772 int warning = 0;
773
774 double Slices[10];
775 int NSlice = 5;
776 double gain=1.;
777 double pedestal=0;
778 double CFD_frac = 1.0;
779 bool corr=0;
780
781 std::vector<std::vector<int> >::const_iterator vit;
782 std::vector<int> y;
783
784 int mType = 0;
785
786
787
788 //Identifier::value_type zId;
789
790 /*
791 Id: Side Module Number Module Type
792 0xec000000 0 (C) 0 0
793 0xec400000 0 (C) 1 0
794 0xec800000 0 (C) 2 0
795 0xecc00000 0 (C) 3 0
796 0xed000000 1 (A) 0 0
797 0xed400000 1 (A) 1 0
798 0xed800000 1 (A) 2 0
799 0xedc00000 1 (A) 3 0
800 */
801 //Initialize the vectors
802 m_bwl_vpeak2.resize(4,0);
803 m_bwl_tpeak2.resize(4,0);
804
805 mType = m_zdcId->type(id);
806
807
808
809 //This controls if we get timing from all channels or
810 //from only a subset
811 wfmIndex = 2;
812 i = 0;
813 for (vit = wfm.begin(); vit<wfm.end(); ++vit) {
814 if ( (i < wfmIndex) && (mType == 0) )
815 {
816 y = *vit;
817
818 // This is for the sinx/x interpolation
819
820 for(int I=0;I<NSlice;I++) {Slices[I]=y[I];}
821 ZdcSignalSinc zdcSignalSinc(NSlice);
822
823 zdcSignalSinc.process(Slices,gain,pedestal,CFD_frac,corr);
824
825
826 m_bwl_vpeak2[i] = zdcSignalSinc.getAmp() ;
827 m_bwl_tpeak2[i] = zdcSignalSinc.getTime() ;
828
829 error = zdcSignalSinc.getError();
830 warning = zdcSignalSinc.getWarning();
831
832 msg(MSG::DEBUG) << "--> ZDC : ZdcRecChannelTool::getTimingSinc2: "
833 << error << ";" << warning << endmsg;
834
835 }
836 else {
837 m_bwl_vpeak2[i] = -999 ;
838 m_bwl_tpeak2[i] = -999 ;
839 }
840 i++;
841 }
842 return 0;
843
844}
#define endmsg
static Double_t t0
#define F(x, y, z)
Definition MD5.cxx:112
#define I(x, y, z)
Definition MD5.cxx:116
int imax(int i, int j)
#define y
#define x
#define z
static const Attributes_t empty
static const InterfaceID IID_IZdcRecChannelTool("ZdcRecChannelTool", 1, 1)
constexpr int pow(int base, int exp) noexcept
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
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
MsgStream & msg() const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
Definition ZdcID.h:25
static double fxCallback(double d, void *v)
static const int s_FADC_SATURATION
std::vector< float > m_bwl_tpeak
int makeRawFromDigits(const ZdcDigitsCollection &data_collection, ZdcRawChannelCollection &raw_collection)
static const int s_SAMPLING_TIME
virtual StatusCode finalize()
int getCalibration(const ZdcDigitsCollection &data_collection, ZdcRawChannelCollection &raw_collection)
int getTimingSinc(const Identifier &id, const std::vector< std::vector< int > > &wfm)
std::vector< float > m_wfm_bwl
static const InterfaceID & interfaceID()
AlgTool InterfaceID.
static double fx(double x0, void *params)
int getTimingSinc2(const Identifier &id, const std::vector< std::vector< int > > &wfm)
virtual StatusCode initialize()
std::vector< float > m_bwl_tpeak2
ZdcRecChannelTool(const std::string &type, const std::string &name, const IInterface *parent)
std::vector< float > m_cfd_result
std::vector< float > m_bwl_vpeak
gsl_interp_accel * m_interp_acc
int getTimingCFD(const Identifier &id, const std::vector< std::vector< int > > &wfm)
std::vector< float > m_bwl_vpeak2
int process(double *, double gain=1., double ped=0., double frac=1., bool corr=true)
double getTime() const
int getWarning() const
int getError() const
double getAmp() const
int r
Definition globals.cxx:22