Belle II Software  release-08-01-10
EclConfiguration.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 /* Own header. */
10 #include <ecl/digitization/EclConfiguration.h>
11 
12 /* ECL headers. */
13 #include <ecl/digitization/shaperdsp.h>
14 
15 /* Basf2 headers. */
16 #include <framework/database/DBObjPtr.h>
17 #include <framework/dbobjects/HardwareClockSettings.h>
18 
19 /* C++ headers. */
20 #include <cmath>
21 #include <vector>
22 
23 using namespace Belle2;
24 using namespace Belle2::ECL;
25 using namespace std;
26 
27 // define the constexpr here to make clang happy. Could be a bug or some strict
28 // adherence to the standard. I guess it's just a different interpretation of
29 // how to use these values by clang.
30 // http://stackoverflow.com/questions/28264279/undefined-reference-when-accessing-static-constexpr-float-member
31 constexpr double EclConfiguration::s_clock;
32 constexpr double EclConfiguration::m_step;
33 double EclConfiguration::m_rf = -1;
34 double EclConfiguration::m_tick = -1;
35 
37 {
40  if (m_rf < 0) {
41  DBObjPtr<Belle2::HardwareClockSettings> clock_info("HardwareClockSettings");
42  // Convert RF from GHz to MHz
43  m_rf = clock_info->getAcceleratorRF() * 1e3;
44  }
45  return m_rf;
46 }
47 
49 {
50  return 24.*12. / getRF();
51 }
52 
53 void EclConfiguration::signalsample_t::InitSample(const double* MPd, double u)
54 {
55  const int N = m_ns * m_nl;
56  vector<double> MP(MPd, MPd + 10);
57  ShaperDSP_t dsp(MP, u);
58  dsp.settimestride(m_step / m_ns);
59  dsp.fillarray(0.0, N, m_ft);
60 
61  double sum = 0;
62  for (int i = 0; i < N; i++) sum += m_ft[i];
63  m_sumscale = m_ns / sum;
64 }
65 
66 
67 void EclConfiguration::signalsample_t::InitSample(const float* MP, double u)
68 {
69  double MPd[10];
70  for (int i = 0; i < 10; i++) MPd[i] = MP[i];
71  InitSample(MPd, u);
72 }
73 
74 void EclConfiguration::adccounts_t::AddHit(const double a, const double t0, const EclConfiguration::signalsample_t& s)
75 {
76  total += s.Accumulate(a, t0, c);
77 }
78 
79 double EclConfiguration::signalsample_t::Accumulate(const double a, const double t0, double* s) const
80 {
81  // input parameters
82  // a -- signal amplitude
83  // t -- signal offset
84  // output parameter
85  // s -- output array with added signal
86  const double itick = getRF() / s_clock; // reciprocal to avoid division in usec^-1 (has to be evaluated at compile time)
87  const double tlen = m_nl - 1.0 / m_ns; // length of the sampled signal in ADC clocks units
88  const double tmax = m_tmin + m_nsmp - 1; // upper range of the fit region
89 
90  double t = t0 * itick; // rescale time in usec to ADC clocks
91  double x0 = t, x1 = t + tlen;
92 
93  if (x0 > tmax) return 0; // signal starts after the upper range of output array -- do nothing
94  if (x0 < m_tmin) {
95  if (x1 < m_tmin) return 0; // signal ends before lower range of output array -- do nothing
96  x0 = m_tmin; // adjust signal with range of output array
97  }
98 
99  int imax = m_nsmp; // length of sampled signal is long enough so
100  // the last touched element is the last element
101  // of the output array
102  if (x1 < tmax) { // if initial time is too early we need to adjust
103  // the last touched element of output array to avoid
104  // out-of-bound situation in m_ft
105  imax = x1 - m_tmin; // imax is always positive so floor can be
106  // replace by simple typecast
107  imax += 1; // like s.end()
108  }
109 
110  double imind = ceil(x0 - m_tmin); // store result in double to avoid int->double conversion below
111  // the ceil function today at modern CPUs is surprisingly fast (before it was horribly slow)
112  int imin = imind; // starting point to fill output array
113  double w = ((m_tmin - t) + imind) * double(m_ns);
114  int jmin = w; // starting point in sampled signal array
115  w -= jmin;
116 
117  // use linear interpolation between samples. Since signal samples
118  // are aligned with output samples only two weights are need to
119  // calculate to fill output array
120  const double w1 = a * w, w0 = a - w1;
121  double sum = 0;
122  for (int i = imin, j = jmin; i < imax; i++, j += m_ns) {
123  double amp = w0 * m_ft[j] + w1 * m_ft[j + 1];
124  s[i] += amp;
125  sum += amp;
126  }
127  return sum * m_sumscale;
128 }
static constexpr double m_step
time between points in internal units t_{asrto}*m_rf/2.
static constexpr double s_clock
digitization clock in RF units
static double m_rf
RF clock, www-linac.kek.jp/linac-com/report/skb-tdr/, ch.
static double getTick()
See m_tick.
static double m_tick
== 72/127 digitization clock tick (in microseconds)
static double getRF()
See m_rf.
Class include function that calculate electronic response from energy deposit
Definition: shaperdsp.h:26
void settimestride(double)
set grid step for function calculation
Definition: shaperdsp.cc:361
void fillarray(int, double *) const
fill array for amplitude and time calculation
Definition: shaperdsp.cc:381
double getAcceleratorRF() const
Get the accelerator RF value.
Abstract base class for different kinds of events.
void AddHit(const double a, const double t0, const signalsample_t &q)
add hit method
double Accumulate(const double a, const double t0, double *s) const
void InitSample(const float *MP, double unitscale=-1)