ATLAS Offline Software
Public Member Functions | Private Member Functions | Private Attributes | List of all members
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 }

◆ ~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 }

◆ 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
125  double startTime = m_lowerTimeWindow;
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 }

◆ 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
190  double startTime = m_lowerTimeWindow;
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 }

◆ 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
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 }

◆ 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 }

◆ 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 }

◆ 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.

◆ m_argK1

double VMM_Shaper::m_argK1 {0.}
private

Definition at line 41 of file VMM_Shaper.h.

◆ m_im_pole1

double VMM_Shaper::m_im_pole1 {0.}
private

Definition at line 38 of file VMM_Shaper.h.

◆ m_im_pole1_ns

double VMM_Shaper::m_im_pole1_ns {0.}
private

Definition at line 51 of file VMM_Shaper.h.

◆ m_inverseTimeStep

double VMM_Shaper::m_inverseTimeStep {0.}
private

Definition at line 31 of file VMM_Shaper.h.

◆ m_k1_abs

double VMM_Shaper::m_k1_abs {0.}
private

Definition at line 40 of file VMM_Shaper.h.

◆ m_lowerTimeWindow

double VMM_Shaper::m_lowerTimeWindow {0.}
private

Definition at line 27 of file VMM_Shaper.h.

◆ m_peakTime

double VMM_Shaper::m_peakTime {0.}
private

Definition at line 26 of file VMM_Shaper.h.

◆ m_peakTimeChargeScaling

double VMM_Shaper::m_peakTimeChargeScaling {0.}
private

Definition at line 42 of file VMM_Shaper.h.

◆ m_pole0

double VMM_Shaper::m_pole0 {0.}
private

Definition at line 36 of file VMM_Shaper.h.

◆ m_pole0_ns

double VMM_Shaper::m_pole0_ns {0.}
private

Definition at line 49 of file VMM_Shaper.h.

◆ m_pole1_square

double VMM_Shaper::m_pole1_square {0.}
private

Definition at line 39 of file VMM_Shaper.h.

◆ m_preCalculationVMMShaper

double VMM_Shaper::m_preCalculationVMMShaper {0.}
private

Definition at line 33 of file VMM_Shaper.h.

◆ m_re_pole1

double VMM_Shaper::m_re_pole1 {0.}
private

Definition at line 37 of file VMM_Shaper.h.

◆ m_re_pole1_ns

double VMM_Shaper::m_re_pole1_ns {0.}
private

Definition at line 50 of file VMM_Shaper.h.

◆ m_timeStep

double VMM_Shaper::m_timeStep {0.}
private

Definition at line 30 of file VMM_Shaper.h.

◆ m_upperTimeWindow

double VMM_Shaper::m_upperTimeWindow {0.}
private

Definition at line 28 of file VMM_Shaper.h.


The documentation for this class was generated from the following files:
VMM_Shaper::m_peakTimeChargeScaling
double m_peakTimeChargeScaling
Definition: VMM_Shaper.h:42
max
#define max(a, b)
Definition: cfImp.cxx:41
response
MDT_Response response
Definition: MDT_ResponseTest.cxx:28
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
VMM_Shaper::aboveThresholdSimple
bool aboveThresholdSimple(const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold) const
Definition: VMM_Shaper.cxx:204
VMM_Shaper::vmmResponse
double vmmResponse(const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, double time) const
Definition: VMM_Shaper.cxx:49
lumiFormat.startTime
startTime
Definition: lumiFormat.py:102
VMM_Shaper::m_inverseTimeStep
double m_inverseTimeStep
Definition: VMM_Shaper.h:31
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
VMM_Shaper::m_pole1_square
double m_pole1_square
Definition: VMM_Shaper.h:39
VMM_Shaper::m_peakTime
double m_peakTime
Definition: VMM_Shaper.h:26
VMM_Shaper::m_upperTimeWindow
double m_upperTimeWindow
Definition: VMM_Shaper.h:28
VMM_Shaper::m_im_pole1
double m_im_pole1
Definition: VMM_Shaper.h:38
VMM_Shaper::m_re_pole1
double m_re_pole1
Definition: VMM_Shaper.h:37
VMM_Shaper::m_preCalculationVMMShaper
double m_preCalculationVMMShaper
Definition: VMM_Shaper.h:33
VMM_Shaper::m_a
double m_a
Definition: VMM_Shaper.h:35
VMM_Shaper::m_re_pole1_ns
double m_re_pole1_ns
Definition: VMM_Shaper.h:50
VMM_Shaper::m_timeStep
double m_timeStep
Definition: VMM_Shaper.h:30
dumpTgcDigiJitter.nBins
list nBins
Definition: dumpTgcDigiJitter.py:29
VMM_Shaper::m_im_pole1_ns
double m_im_pole1_ns
Definition: VMM_Shaper.h:51
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
VMM_Shaper::m_pole0
double m_pole0
Definition: VMM_Shaper.h:36
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
VMM_Shaper::m_k1_abs
double m_k1_abs
Definition: VMM_Shaper.h:40
VMM_Shaper::m_argK1
double m_argK1
Definition: VMM_Shaper.h:41
VMM_Shaper::m_pole0_ns
double m_pole0_ns
Definition: VMM_Shaper.h:49
VMM_Shaper::findPeak
double findPeak(const std::vector< float > &effectiveCharge, const std::vector< float > &electronsTime, const double electronicsThreshold) const
Definition: VMM_Shaper.cxx:122
VMM_Shaper::initialize
void initialize()
Definition: VMM_Shaper.cxx:27
VMM_Shaper::m_lowerTimeWindow
double m_lowerTimeWindow
Definition: VMM_Shaper.h:27