ATLAS Offline Software
Loading...
Searching...
No Matches
TileSampleGenerator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8
9#include "TArrayD.h"
10#include "TMath.h"
11#include "TF1.h"
12#include "TRandom3.h"
13
14#include <iostream>
15#include <cstdio>
16
17using namespace std;
18
19//
20//_______________________________________________________________
22 m_ps(0), m_buf(0), m_DEBUG(false), m_rndm(nullptr) {
23
24}
25
26//
27//_______________________________________________________________
29 m_ps(ps), m_buf(buf), m_DEBUG(dd_DEBUG) {
30 m_rndm = new TRandom3();
31}
32
33//
34//_______________________________________________________________
38
39//
40//_______________________________________________________________
41void TileSampleGenerator::fillSamples(double t0, double pedestal, double amplitude1, double amplitude2, TF1* pdf, bool addNoise, double itOffset, double otOffset) {
42 for (unsigned int i = 0; i < m_buf->size(); ++i) {
43 double x1 = m_buf->getTime(i) - t0 + itOffset;
44 double y1 = m_ps->eval(x1) * amplitude1;
45 double x2 = m_buf->getTime(i) - t0 + otOffset;
46 double y2 = m_ps->eval(x2) * amplitude2;
47 double y = y1 + y2 + pedestal;
48
49 double noise(0), val(y);
50 if (addNoise) {
51 noise = pdf->GetRandom();
52 val += noise;
53 }
54
55 m_buf->setValueNoise(i, (noise));
56 m_buf->setValue(i, val);
57 }
58
59 return;
60}
61
62//
63//________________________________________________________
64void TileSampleGenerator::fillNSamples(double t0, double pedestal, double amp_it, const std::vector<float>& amp_pu, TF1* pdf, bool addNoise, double itOffset, int nSamples, int nPul) {
65
66 std::unique_ptr<TileSampleBuffer> bufall = std::make_unique<TileSampleBuffer>(nPul, -25*((nPul-1)/2), 25.);
67
68 if(m_DEBUG){
69 cout << "Pileup pulses:" << std::endl;
70 for (std::vector<float>::const_iterator i = amp_pu.begin(); i != amp_pu.end(); ++i)
71 std::cout << *i << ' ';
72 std::cout << std::endl;
73 }
74
75
76 double tin, amp_it_out;
77 int nAmp = amp_pu.size();
78 vector<int> t(nAmp);
79 vector<float> amp_pu_out(nAmp);
80 int x = (nAmp-1)/2 + nSamples;
81 double amp_total = pedestal;
82
83 for (int i = 0; i < nSamples; i++) { //Loop over output samples
84
85 if (m_DEBUG)
86 cout << "sample to compute: " << i << " " << amp_total << std::endl;
87
88 for (int j = 0; j < nAmp ; j++) { //Loop over PU pulses
89
90 t[j] = bufall->getTime(x + i - j) - t0;
91
92 if (m_DEBUG)
93 cout << "pileupsample to compute " << j << std::endl;
94 if (m_DEBUG)
95 cout << " time in " << i << " " << j << " " << (x + i - j) << " " << " buf " << bufall->getTime(x + i - j) << " time_out " << t[j] << std::endl;
96
97 if (t[j] < -((nSamples-1)/2)*25. || t[j] > ((nSamples+1)/2)*25.)
98 continue; //Limits of the PulseShape
99 amp_pu_out[j] = m_ps->eval(t[j]) * amp_pu.at(j); // PU Contribution
100 amp_total += amp_pu_out[j];
101
102 if (m_DEBUG)
103 cout << " amp_pu " << amp_pu.at(j) << " ps " << m_ps->eval(t[j]) << " amp_out " << amp_pu_out[j] << std::endl;
104 if (m_DEBUG)
105 cout << " amp_total " << amp_total << std::endl;
106 }
107
108 tin = m_buf->getTime(i) - t0 + itOffset;
109 amp_it_out = m_ps->eval(tin) * amp_it; //Contribution from In-time Pulse
110 amp_total += amp_it_out;
111
112 if (m_DEBUG)
113 cout << " INTIME amp_it " << amp_it << " ps " << m_ps->eval(tin) << " amp_it_out " << amp_it_out << std::endl;
114 if (m_DEBUG)
115 std::cout << " amp_total " << amp_total << std::endl;
116
117 double noise(0), val(amp_total);
118 if (addNoise) {
119 noise = pdf->GetRandom();
120 val += noise;
121 }
122 if (m_DEBUG)
123 cout << " FINAL " << amp_total << std::endl;
124 m_buf->setValueNoise(i, (noise));
125 m_buf->setValue(i, val);
126 }
127
128 return;
129}
130
131float TileSampleGenerator::fillSample(double t0, double pedestal, const vector<float>& amp_pu, TF1* pdf, bool addNoise, int nPul, int gain) {
132
133 std::unique_ptr<TileSampleBuffer> bufall = std::make_unique<TileSampleBuffer>(nPul, -25*((nPul-1)/2), 25.);
134
135 if(m_DEBUG){
136 std::cout << "Pileup pulses:" << std::endl;
137 for (std::vector<float>::const_iterator i = amp_pu.begin(); i != amp_pu.end(); ++i)
138 std::cout << *i << ' ';
139 std::cout << std::endl;
140 }
141
142 double amp_it_out = pedestal;
143 vector<int> t(nPul);
144
145 for (int pul=0; pul < nPul; pul++){
146
147 t[pul] = bufall->getTime(pul) - t0;
148
149 if(gain == 1){
150 amp_it_out += m_ps->eval(t[pul], false, true) * amp_pu.at(pul);
151 }
152 else{
153 amp_it_out += (m_ps->eval(t[pul], false, true) * amp_pu.at(pul)) / 40;
154 }
155
156 if(m_DEBUG){
157 std::cout << "nPul-1-pul: " << pul << " getTime(nPul-1-pul) " << bufall->getTime(pul) << " ps " << m_ps->eval(bufall->getTime(pul), false, true) << std::endl;
158 std::cout << "PU sample " << pul << ", pulse shape evaluated for t'=" << t[pul] << std::endl;
159 std::cout << "Contribution for in time amp " << m_ps->eval(t[pul], false, true) << " * " << amp_pu.at(pul) << std::endl;
160 std::cout << std::endl;
161 }
162 }
163
164 if (addNoise) {
165 amp_it_out += pdf->GetRandom();
166 }
167
168 return amp_it_out;
169
170}
171
172//
173//________________________________________________________
174// Simulation of the PMT pulse shapes for QIE FEB
175// Please e-mail your questions to alexander.paramonov@cern.ch
176//________________________________________________________
177void TileSampleGenerator::fill7SamplesQIE(float amp_it, float *amp_pu) { //float t0, addNoise
178
179 //amp_it = energy/charge of the in-time pulse in fC
180
181 //amp_pu charge deposited by out-of-time interactions assuming the interactions are every 25 ns
182 //the amplitudes are in fC
183
184 //The in-time signal produces charges in amp_total[3] and amp_total[4]; ~80% of charge is added to amp_total[3]
185
186 float amp_total[7] = { 0, 0, 0, 0, 0, 0, 0 };
187 float tail_Q = 0;
188 const float Q_1pe = 17.; //Average charge per a photo-electron
189 const float tail_prob = 0.18; //Probability for a photo-electron to have 25<t<75 ns
190
191 for (int i = 0; i < 7; i++) { //Loop over output samples
192
193 //if (m_DEBUG)
194 // std::cout << "sample to compute: " << i << " " << amp_total << std::endl;
195
196 if (i != 3) { //out-of-time pileup
197 tail_Q = Q_1pe * m_rndm->Binomial((int) (amp_pu[i] / Q_1pe), tail_prob);
198
199 amp_total[i] += amp_pu[i] - tail_Q;
200 if (i < 6)
201 amp_total[i + 1] += tail_Q;
202
203 } else { //in-time pulse
204
205 tail_Q = Q_1pe * m_rndm->Binomial((int) amp_it / Q_1pe, tail_prob);
206
207 amp_total[3] += amp_it - tail_Q;
208 amp_total[4] += tail_Q;
209 }
210
211 /*
212 double noise(0), val(amp_total);
213 if (addNoise) {
214 noise = pdf->GetRandom();
215 amp_total[i] += noise;
216 }
217
218 if (m_DEBUG)
219 std::cout << " FINAL " << amp_total << std::endl;
220 */
221 }
222
223 for (unsigned int i = 0; i < 7; i++) { //Loop over output samples
224 m_buf->setValueNoise(i, 0);
225 m_buf->setValue(i, amp_total[i]);
226 }
227
228 return;
229}
static Double_t t0
#define y
#define x
void fillSamples(double t0, double pedestal, double amplitude1, double amplitude2, TF1 *pdf, bool addNoise, double itOffset=0, double otOffset=50)
void fillNSamples(double t0, double pedestal, double amp_it, const std::vector< float > &amp_pu, TF1 *pdf, bool addNoise, double itOffset=0, int nSamples=7, int nPul=21)
TileSampleBuffer * m_buf
void fill7SamplesQIE(float amp_it, float *amp_pu)
float fillSample(double t0, double pedestal, const std::vector< float > &amp_pu, TF1 *pdf, bool addNoise, int nPul=21, int gain=1)
STL namespace.