ATLAS Offline Software
Loading...
Searching...
No Matches
VMM_Shaper Class Reference

#include <VMM_Shaper.h>

Collaboration diagram for VMM_Shaper:

Public Member Functions

 VMM_Shaper (const float peakTime, const float lowerTimeWindow, const float upperTimeWindow)
virtual ~VMM_Shaper ()=default
void initialize ()
bool vmmPeakResponse (const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold, double &amplitudeFirstPeak, double &timeFirstPeak) const
bool vmmThresholdResponse (const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold, double &amplitudeAtFirstPeak, double &timeAtThreshold) const
bool hasChargeAboveThreshold (const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold) const

Private Member Functions

double vmmResponse (const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, double time) const
double findPeak (const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold) const
bool aboveThresholdSimple (const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold) const

Private Attributes

double m_peakTime {0.}
double m_lowerTimeWindow {0.}
double m_upperTimeWindow {0.}
double m_timeStep {0.}
double m_inverseTimeStep {0.}
double m_preCalculationVMMShaper {0.}
double m_a {0.}
double m_pole0 {0.}
double m_re_pole1 {0.}
double m_im_pole1 {0.}
double m_pole1_square {0.}
double m_k1_abs {0.}
double m_argK1 {0.}
double m_peakTimeChargeScaling {0.}
double m_pole0_ns {0.}
double m_re_pole1_ns {0.}
double m_im_pole1_ns {0.}

Detailed Description

Definition at line 10 of file VMM_Shaper.h.

Constructor & Destructor Documentation

◆ VMM_Shaper()

VMM_Shaper::VMM_Shaper ( const float peakTime,
const float lowerTimeWindow,
const float upperTimeWindow )

Definition at line 21 of file VMM_Shaper.cxx.

21 :
22 m_peakTime(peakTime), m_lowerTimeWindow(lowerTimeWindow), m_upperTimeWindow(upperTimeWindow), m_timeStep(0.1) {
24 initialize();
25}
double m_inverseTimeStep
Definition VMM_Shaper.h:31
void initialize()
double m_lowerTimeWindow
Definition VMM_Shaper.h:27
double m_upperTimeWindow
Definition VMM_Shaper.h:28
double m_peakTime
Definition VMM_Shaper.h:26
double m_timeStep
Definition VMM_Shaper.h:30

◆ ~VMM_Shaper()

virtual VMM_Shaper::~VMM_Shaper ( )
virtualdefault

Member Function Documentation

◆ aboveThresholdSimple()

bool VMM_Shaper::aboveThresholdSimple ( const std::vector< float > & effectiveCharge,
const std::vector< float > & electronsTime,
const double electronicsThreshold ) const
private

Definition at line 204 of file VMM_Shaper.cxx.

205 {
206 // check if total strip charge is above threshold, otherwise skip VMM
207 float chargeSum = 0;
208 for (unsigned int i_elec = 0; i_elec < effectiveCharge.size(); i_elec++) {
209 if (electronsTime.at(i_elec) >= m_lowerTimeWindow - m_peakTime && electronsTime.at(i_elec) <= m_upperTimeWindow) {
210 chargeSum += effectiveCharge.at(i_elec) * m_peakTimeChargeScaling;
211 }
212 }
213 return chargeSum >= electronicsThreshold;
214}
double m_peakTimeChargeScaling
Definition VMM_Shaper.h:42

◆ findPeak()

double VMM_Shaper::findPeak ( const std::vector< float > & effectiveCharge,
const std::vector< float > & electronsTime,
const double electronicsThreshold ) const
private

Definition at line 122 of file VMM_Shaper.cxx.

123 {
124 if (effectiveCharge.empty()) return -9999; // protect min_element
126 double minElectronTime = *std::min_element(electronsTime.begin(), electronsTime.end());
127
128 minElectronTime += 0.8 * m_peakTime; // only start looking for the peak close to the first possible peak
129 if (startTime < minElectronTime)
130 startTime = minElectronTime; // if smallest strip times are higher then the lower time window, just start the loop from the
131 // smallest electron time
132
133 double oldResponse = 0;
134 // double currentDerivative = 0;
135
136 double timeStepScaleFactor = 5.0;
137
138 for (double time = startTime; time < m_upperTimeWindow; time += m_timeStep * timeStepScaleFactor) {
139 double response = vmmResponse(effectiveCharge, electronsTime, time);
140 if (oldResponse < response) {
141 oldResponse = response;
142 continue;
143 }
144 oldResponse = response;
145
146 int searchWindow = 5;
147
148 std::vector<double> tmpTime, tmpResponse;
149
150 tmpTime.reserve(2 * timeStepScaleFactor);
151 tmpResponse.reserve(2 * timeStepScaleFactor);
152
153 for (double fineTime = (time - 1.5 * m_timeStep * timeStepScaleFactor); fineTime < time + 0.5 * m_timeStep * timeStepScaleFactor;
154 fineTime += m_timeStep) {
155 tmpTime.push_back(fineTime);
156 tmpResponse.push_back(vmmResponse(effectiveCharge, electronsTime, fineTime));
157 }
158
159 int nBins = tmpTime.size();
160
161 for (int i_time = 1; i_time < nBins - 1; i_time++) {
162 if (tmpResponse.at(i_time) < tmpResponse.at(i_time + 1)) continue;
163
164 if (tmpResponse.at(i_time) < electronicsThreshold) break;
165
166 bool checkTimeWindow = false;
167 for (int i_timeOfPeak = i_time - searchWindow + 1; i_timeOfPeak <= i_time + searchWindow; i_timeOfPeak++) {
168 if (i_timeOfPeak < 1 || i_timeOfPeak == nBins - 1) continue;
169
170 double oldDerivative = (tmpResponse.at(i_time) - tmpResponse.at(i_time - 1));
171 double newDerivative = (tmpResponse.at(i_time + 1) - tmpResponse.at(i_time));
172 if (newDerivative > oldDerivative) {
173 checkTimeWindow = false;
174 break;
175 } else {
176 checkTimeWindow = true;
177 }
178 }
179 if (checkTimeWindow) return tmpTime.at(i_time);
180 }
181 }
182 return -9999; // no peak found
183}
MDT_Response response
double vmmResponse(const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, double time) const
time(flags, cells_name, *args, **kw)

◆ hasChargeAboveThreshold()

bool VMM_Shaper::hasChargeAboveThreshold ( const std::vector< float > & effectiveCharge,
const std::vector< float > & electronsTime,
const double electronicsThreshold ) const

Definition at line 185 of file VMM_Shaper.cxx.

186 {
187 if (!aboveThresholdSimple(effectiveCharge, electronsTime, electronicsThreshold)) return false;
188
189 if (effectiveCharge.empty()) return false; // protect min_element
191 double minElectronTime = *std::min_element(electronsTime.begin(), electronsTime.end());
192 // since we are only checking if signal is above threshold, we can start searching close to the peak
193 minElectronTime += m_peakTime * 0.8;
194 if (startTime < minElectronTime)
195 startTime = minElectronTime; // if smallest strip times are higher then the lower time window, just start the loop from the
196 // smallest electron time
197
198 for (double time = startTime; time < m_upperTimeWindow; time += m_timeStep) {
199 if (vmmResponse(effectiveCharge, electronsTime, time) >= electronicsThreshold) { return true; }
200 }
201 return false;
202}
bool aboveThresholdSimple(const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold) const

◆ initialize()

void VMM_Shaper::initialize ( )

Definition at line 27 of file VMM_Shaper.cxx.

27 {
28 // hardcoded vmm shaper values are provided by G. Iakovidis
29 m_a = (m_peakTime * (1e-9)) / 1.5;
30 m_pole0 = 1.263 / m_a;
31 m_re_pole1 = 1.149 / m_a;
32 m_im_pole1 = -0.786 / m_a;
34 m_k1_abs = std::sqrt(Re_K1 * Re_K1 + Im_K1 * Im_K1);
35 m_argK1 = std::atan2(Im_K1, Re_K1);
36
37 // scale factor for charge taking into account the mm ion flow time of ~150ns
38 // if the peaking time is lower then that, only a fration of the total charge is integrated
39 m_peakTimeChargeScaling = (m_peakTime < mmIonFlowTime ? 1.0 * m_peakTime / mmIonFlowTime : 1.0);
40
41 // preCalculate factor to avoid recalculating for each electron
42 m_preCalculationVMMShaper = chargeScaleFactor * m_peakTimeChargeScaling * std::pow(m_a, 3) * m_pole0 * m_pole1_square;
43
44 m_pole0_ns = m_pole0 * (1e-9);
45 m_re_pole1_ns = m_re_pole1 * (1e-9);
46 m_im_pole1_ns = m_im_pole1 * (1e-9);
47}
double m_pole1_square
Definition VMM_Shaper.h:39
double m_im_pole1
Definition VMM_Shaper.h:38
double m_k1_abs
Definition VMM_Shaper.h:40
double m_pole0
Definition VMM_Shaper.h:36
double m_preCalculationVMMShaper
Definition VMM_Shaper.h:33
double m_argK1
Definition VMM_Shaper.h:41
double m_a
Definition VMM_Shaper.h:35
double m_re_pole1
Definition VMM_Shaper.h:37
double m_re_pole1_ns
Definition VMM_Shaper.h:50
double m_pole0_ns
Definition VMM_Shaper.h:49
double m_im_pole1_ns
Definition VMM_Shaper.h:51

◆ vmmPeakResponse()

bool VMM_Shaper::vmmPeakResponse ( const std::vector< float > & effectiveCharge,
const std::vector< float > & electronsTime,
const double electronicsThreshold,
double & amplitudeFirstPeak,
double & timeFirstPeak ) const

Definition at line 64 of file VMM_Shaper.cxx.

65 {
66 double t_peak = findPeak(effectiveCharge, electronsTime, electronicsThreshold);
67
68 if (t_peak == -9999) return false; // no peak found
69
70 amplitudeFirstPeak = vmmResponse(effectiveCharge, electronsTime, t_peak);
71 timeFirstPeak = t_peak;
72 return true;
73}
double findPeak(const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold) const

◆ vmmResponse()

double VMM_Shaper::vmmResponse ( const std::vector< float > & effectiveCharge,
const std::vector< float > & electronsTime,
double time ) const
private

Definition at line 49 of file VMM_Shaper.cxx.

49 {
50 double response = 0;
51 for (unsigned int i_electron = 0; i_electron < effectiveCharge.size(); i_electron++) {
52 if (time < electronsTime.at(i_electron)) continue;
53 double t = (time - electronsTime.at(i_electron));
54 // now follows the vmm shaper response function provided by G. Iakovidis
55 // It is described in section 7.1.3 of https://cds.cern.ch/record/1955475
56 double st =
57 effectiveCharge.at(i_electron) * m_preCalculationVMMShaper *
58 ((K0 * std::exp(-t * m_pole0_ns)) + (2. * m_k1_abs * std::exp(-t * m_re_pole1_ns) * std::cos(-t * m_im_pole1_ns + m_argK1)));
59 response += st;
60 }
61 return response;
62}
static const int K0
Definition AtlasPID.h:115

◆ vmmThresholdResponse()

bool VMM_Shaper::vmmThresholdResponse ( const std::vector< float > & effectiveCharge,
const std::vector< float > & electronsTime,
const double electronicsThreshold,
double & amplitudeAtFirstPeak,
double & timeAtThreshold ) const

Definition at line 75 of file VMM_Shaper.cxx.

76 {
77 if (!aboveThresholdSimple(effectiveCharge, electronsTime, electronicsThreshold)) return false;
78
79 if (effectiveCharge.empty()) return false; // protect min_element
81 double minElectronTime = *std::min_element(electronsTime.begin(), electronsTime.end());
82 if (startTime < minElectronTime)
83 startTime = minElectronTime; // if smallest strip times are higher then the lower time window, just start the loop from the
84 // smallest electron time
85
86 double tmpTimeAtThreshold = -9999;
87
88 for (double time = startTime; time < minElectronTime + 0.9 * m_peakTime;
89 time += 10 * m_timeStep) { // quick search till the first possible peak
90 if (vmmResponse(effectiveCharge, electronsTime, time) <= electronicsThreshold) continue;
91 for (double fineTime = time; fineTime >= time - 10 * m_timeStep;
92 fineTime -=
93 m_timeStep) { // since value above threshold was found, loop back in time to find the crossing with the timeStep precission
94 if (vmmResponse(effectiveCharge, electronsTime, fineTime) >= electronicsThreshold) continue;
95 tmpTimeAtThreshold = fineTime + 0.5 * m_timeStep; // get time between time above and time below threshold
96 break;
97 }
98 break;
99 }
100
101 if (tmpTimeAtThreshold == -9999) { // threshold crossing not yet found
102 // check if first possible peak was before start time
103 double tmpStartTime = std::max(minElectronTime + 0.9 * m_peakTime, startTime);
104 for (double time = tmpStartTime; time < m_upperTimeWindow; time += m_timeStep) {
105 if (vmmResponse(effectiveCharge, electronsTime, time) >= electronicsThreshold) {
106 tmpTimeAtThreshold = time;
107 break;
108 }
109 }
110 }
111
112 if (tmpTimeAtThreshold == -9999) return false;
113
114 double t_peak = findPeak(effectiveCharge, electronsTime, electronicsThreshold);
115 if (t_peak == -9999) return false;
116
117 timeAtThreshold = tmpTimeAtThreshold;
118 amplitudeAtFirstPeak = vmmResponse(effectiveCharge, electronsTime, t_peak);
119 return true;
120}

Member Data Documentation

◆ m_a

double VMM_Shaper::m_a {0.}
private

Definition at line 35 of file VMM_Shaper.h.

35{0.};

◆ m_argK1

double VMM_Shaper::m_argK1 {0.}
private

Definition at line 41 of file VMM_Shaper.h.

41{0.};

◆ m_im_pole1

double VMM_Shaper::m_im_pole1 {0.}
private

Definition at line 38 of file VMM_Shaper.h.

38{0.};

◆ m_im_pole1_ns

double VMM_Shaper::m_im_pole1_ns {0.}
private

Definition at line 51 of file VMM_Shaper.h.

51{0.};

◆ m_inverseTimeStep

double VMM_Shaper::m_inverseTimeStep {0.}
private

Definition at line 31 of file VMM_Shaper.h.

31{0.};

◆ m_k1_abs

double VMM_Shaper::m_k1_abs {0.}
private

Definition at line 40 of file VMM_Shaper.h.

40{0.};

◆ m_lowerTimeWindow

double VMM_Shaper::m_lowerTimeWindow {0.}
private

Definition at line 27 of file VMM_Shaper.h.

27{0.};

◆ m_peakTime

double VMM_Shaper::m_peakTime {0.}
private

Definition at line 26 of file VMM_Shaper.h.

26{0.};

◆ m_peakTimeChargeScaling

double VMM_Shaper::m_peakTimeChargeScaling {0.}
private

Definition at line 42 of file VMM_Shaper.h.

42{0.};

◆ m_pole0

double VMM_Shaper::m_pole0 {0.}
private

Definition at line 36 of file VMM_Shaper.h.

36{0.};

◆ m_pole0_ns

double VMM_Shaper::m_pole0_ns {0.}
private

Definition at line 49 of file VMM_Shaper.h.

49{0.};

◆ m_pole1_square

double VMM_Shaper::m_pole1_square {0.}
private

Definition at line 39 of file VMM_Shaper.h.

39{0.};

◆ m_preCalculationVMMShaper

double VMM_Shaper::m_preCalculationVMMShaper {0.}
private

Definition at line 33 of file VMM_Shaper.h.

33{0.};

◆ m_re_pole1

double VMM_Shaper::m_re_pole1 {0.}
private

Definition at line 37 of file VMM_Shaper.h.

37{0.};

◆ m_re_pole1_ns

double VMM_Shaper::m_re_pole1_ns {0.}
private

Definition at line 50 of file VMM_Shaper.h.

50{0.};

◆ m_timeStep

double VMM_Shaper::m_timeStep {0.}
private

Definition at line 30 of file VMM_Shaper.h.

30{0.};

◆ m_upperTimeWindow

double VMM_Shaper::m_upperTimeWindow {0.}
private

Definition at line 28 of file VMM_Shaper.h.

28{0.};

The documentation for this class was generated from the following files: