Jpp test-rotations-old
the software that should make you happy
Loading...
Searching...
No Matches
JPMTSignalProcessorInterface.hh
Go to the documentation of this file.
1#ifndef __JDETECTOR__JPMTSIGNALPROCESSORINTERFACE__
2#define __JDETECTOR__JPMTSIGNALPROCESSORINTERFACE__
3
4#include <algorithm>
5#include <cmath>
6#include <limits>
7
10
11
12/**
13 * \author mdejong
14 */
15
16namespace JDETECTOR {}
17namespace JPP { using namespace JDETECTOR; }
18
19namespace JDETECTOR {
20
21 /**
22 * PMT signal processor interface.
23 *
24 * This class supports the implementation of the PMT simulator interface using
25 * an alternative set of virtual methods.
26 * These methods constitute a user interface to the expected performance of a PMT.
27 *
28 * Each photon is converted to a photo-electron using member method getRandomTime().
29 * For this, the data structure JPhotoElectron is used.
30 * Note that the quantum efficiency (QE) of the PMT actually is included in the simulation of the detector response.
31 * A relative QE is applied via method applyQE().
32 * All photo-electrons are then time sorted.
33 * The photo-electrons which simultaneously arrive are merged.
34 * The corresponding condition is defined by member method compare().
35 * The time of the combined signal is determined by the time of the first photo-electron and
36 * the rise time of the analogue pulse to the threshold of the discriminator via method getRiseTime().
37 * In this, the actual amplitude of the combined analogue signal and the calibration of the PMT are taken into account.
38 * The amplitude of the combined analogue signal is simulated using member method getRandomCharge().
39 * For this, the data structure JPMTSignal is used.
40 *
41 * The analogue signals of the PMT are processed by a discriminator.
42 * This discriminator produces a time-over-threshold signal for each analogue signal that passes a preset threshold.
43 * The output signal is described by the time of the leading edge and the length of the time-over-threshold signal.
44 * For this, the data structure JPMTPulse is used.
45 * The determination of the time of the leading edge and the length of the time-over-threshold signal
46 * require a designated model.
47 * The class JPMTAnalogueSignalProcessor provides for an implementation of such a model.
48 *
49 * Overlapping time-over-threshold pulses are merged.
50 * The time of the leading edge is then set to the earliest leading edge and
51 * the time-over-threshold to the difference between
52 * the latest trailing edge and the earliest leading edge.
53 * The merging of hits is implemented in member method merge().
54 *
55 * The default implementation of these virtual methods corresponds to no smearing
56 * and a time-over-threshold value equal to a fixed two photo-electron resolution times the number of photo-electrons.
57 * The width of the charge distribution and the two photo-electron resolution are implemented in methods
58 * getQmin() and getTmin(), respectively.
59 *
60 * For a realistic PMT simulation, the derived class should provide for
61 * an implementation of each of these virtual methods.
62 */
64 public:
65 /**
66 * Default constructor.
67 */
70
71
72 /**
73 * Virtual destructor.
74 */
77
78
79 /**
80 * Process hits.
81 *
82 * Two (or more) photo-electrons are combined if they are comparable according method compare.\n
83 * Two (or more) consecutive hits hits maybe merged (according method merge).
84 *
85 * \param calibration PMT calibration
86 * \param input PMT signals
87 * \param output PMT hits
88 */
89 void operator()(const JCalibration& calibration,
90 const JPMTData<JPMTSignal>& input,
91 JPMTData<JPMTPulse>& output) const
92 {
93 // apply transition time distribution to each photo-electron.
94
96
97 for (JPMTData<JPMTSignal>::const_iterator hit = input.begin(); hit != input.end(); ++hit) {
98
99 for (int i = 0; i != hit->npe; ++i) {
100
101 if (applyQE()) {
102 buffer.push_back(JPhotoElectron(getRandomTime(hit->t_ns)));
103 }
104 }
105 }
106
107 if (!buffer.empty()) {
108
109 buffer.push_back(JPhotoElectron::getEndMarker());
110
111 buffer.sort();
112
113
114 // generate PMT hits from time sequence of photo-electrons.
115
116 for (JPMTData<JPhotoElectron>::const_iterator q = buffer.begin(), p = q++; q != buffer.end(); ++q) {
117
118 while (compare(*p,*q)) {
119 ++q;
120 }
121
122 const double npe = getRandomCharge(distance(p,q));
123
124 if (applyThreshold(npe)) {
125 output.push_back(JPMTPulse(putTime(p->t_ns + getRiseTime(npe), calibration), getTimeOverThreshold(npe)));
126 }
127
128 p = q;
129 }
130
131 // merge overlapping PMT hits.
132
133 merge(output);
134 }
135 }
136
137
138 /**
139 * Apply relative QE.
140 * The default implementation returns <tt>true</tt>.
141 *
142 * \return true if accepted; false if rejected
143 */
144 virtual bool applyQE() const
145 {
146 return true;
147 }
148
149
150 /**
151 * Get randomised time according transition time distribution.
152 * The default implementation returns the given value.
153 *
154 * \param t_ns time [ns]
155 * \return time [ns]
156 */
157 virtual double getRandomTime(const double t_ns) const
158 {
159 return t_ns;
160 }
161
162
163 /**
164 * Compare arrival times of photo-electrons.
165 * The default implementation uses method getTmin as two photo-electron resolution.
166 *
167 * \param first first photo-electron
168 * \param second second photo-electron
169 * \return true if arrival times of photo-electrons are within two photo-electron resolution; else false
170 */
171 virtual bool compare(const JPhotoElectron& first, const JPhotoElectron& second) const
172 {
173 return second.t_ns - first.t_ns <= getTmin();
174 }
175
176
177 /**
178 * Get randomised charge according to gain and gain spread.
179 * The default implementation returns the given value.
180 *
181 * \param NPE number of photo-electrons
182 * \return number of photo-electrons
183 */
184 virtual double getRandomCharge(const int NPE) const
185 {
186 return (double) NPE;
187 }
188
189
190 /**
191 * Get probability density for given charge.
192 *
193 * \param npe observed number of photo-electrons
194 * \param NPE true number of photo-electrons
195 * \return probability [npe^-1]
196 */
197 virtual double getChargeProbability(const double npe, const int NPE) const
198 {
199 return (fabs(npe - NPE) <= 0.5 * getQmin() ? 1.0 / getQmin() : 0.0);
200 }
201
202
203 /**
204 * Apply threshold.
205 * The default implementation returns <tt>true</tt>.
206 *
207 * \param npe number of photo-electrons
208 * \return true if pass; else false
209 */
210 virtual bool applyThreshold(const double npe) const
211 {
212 return (npe > 0.0);
213 }
214
215
216 /**
217 * Get time to reach threshold.
218 * The default implementation returns <tt>0</tt>.
219 *
220 * \param npe number of photo-electrons
221 * \return time [ns]
222 */
223 virtual double getRiseTime(const double npe) const
224 {
225 return 0.0;
226 }
227
228
229 /**
230 * Get time-over-threshold (ToT).
231 * The default implementation corresponds to a linear relation between the number of photo-electrons and the time-over-threshold.
232 *
233 * \param npe number of photo-electrons
234 * \return ToT [ns]
235 */
236 virtual double getTimeOverThreshold(const double npe) const
237 {
238 return TIME_OVER_THRESHOLD_NS + getTmin() * (round(npe) - 1.0);
239 }
240
241
242 /**
243 * Get derivative of number of photo-electrons to time-over-threshold.
244 *
245 * \param npe number of photo-electrons
246 * \return dnpe/dToT [ns^-1]
247 */
248 virtual double getDerivative(const double npe) const
249 {
250 return 1.0 / getTmin();
251 }
252
253
254 /**
255 * Probability that a hit survives the simulation of the PMT.
256 * The default implementation returns <tt>1</tt> if given value larger than <tt>0</tt>.
257 *
258 * \param NPE number of photo-electrons
259 * \return probability
260 */
261 virtual double getSurvivalProbability(const int NPE) const
262 {
263 if (NPE > 0)
264 return 1.0;
265 else
266 return 0.0;
267 }
268
269
270 /**
271 * Get number of photo-electrons.
272 * The default implementation corresponds to a linear relation between the number of photo-electrons and the time-over-threshold.
273 *
274 * \param tot_ns time over threshold [ns]
275 * \return number of photo-electrons
276 */
277 virtual double getNPE(const double tot_ns) const
278 {
279 return 1.0 + (tot_ns - TIME_OVER_THRESHOLD_NS) / getTmin();
280 }
281
282
283 /**
284 * Merging of PMT hits.
285 *
286 * Hits with overlapping time-over-threshold signals should -de facto- be combined.
287 * In this, the leading edge is maintained and the time-over-threshold is
288 * set to the difference between the overall trailing and leading edges.
289 * As a result, the number of PMT hits may be reduced.
290 *
291 * \param data PMT hits (I/O)
292 */
293 virtual void merge(JPMTData<JPMTPulse>& data) const
294 {
295 using namespace std;
296
297 JPMTData<JPMTPulse>::iterator out = data.begin();
298
299 for (JPMTData<JPMTPulse>::iterator i = data.begin(); i != data.end(); ) {
300
301 double t1 = i->t_ns;
302 double t2 = i->t_ns + i->tot_ns;
303
304 while (++i != data.end() && i->t_ns < t2 + getTmin()) {
305 t2 = max(t2, i->t_ns + i->tot_ns);
306 }
307
308 out->t_ns = t1;
309 out->tot_ns = t2 - t1;
310
311 ++out;
312 }
313
314 data.resize(distance(data.begin(), out));
315 }
316
317
318 /**
319 * Get two photo-electron resolution for time-over-threshold
320 *
321 * \return minimal time [ns]
322 */
323 static double getTmin()
324 {
325 return 1.0;
326 }
327
328
329 /**
330 * Get width of charge distribution.
331 *
332 * \return width charge distribution [npe]
333 */
334 static double getQmin()
335 {
336 return 1.0e-3;
337 }
338 };
339
340
341 /**
342 * Get charge probability.
343 *
344 * \param pmt PMT signal processor
345 * \param npe measured number of photo-electrons
346 * \param NPE expected number of photo-electrons
347 * \param precision precision
348 * \return probability
349 */
351 const double npe,
352 const double NPE,
353 const double precision = 1.0e-4)
354 {
355 int i = (int) (NPE - 5.0 * sqrt(NPE));
356
357 if (i < 1) {
358 i = 1;
359 }
360
361 double p = NPE * exp(-NPE) / (double) 1;
362
363 for (int __i = 1; __i != i; ++__i) {
364 p *= NPE / __i;
365 }
366
367 double P = 0.0;
368
369 for (double p0 = 0.0; (p >= p0 || p > precision); ++i, p0 = p, p *= NPE / (double) i) {
370 P += pmt.getChargeProbability(npe, i) * p;
371 }
372
373 return P;
374 }
375}
376
377#endif
Time calibration (including definition of sign of time offset).
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Data structure for time calibration.
Template data structure for PMT I/O.
std::vector< JElement_t >::iterator iterator
std::vector< JElement_t >::const_iterator const_iterator
virtual bool applyQE() const
Apply relative QE.
virtual double getChargeProbability(const double npe, const int NPE) const
Get probability density for given charge.
virtual double getDerivative(const double npe) const
Get derivative of number of photo-electrons to time-over-threshold.
virtual double getTimeOverThreshold(const double npe) const
Get time-over-threshold (ToT).
virtual double getRandomCharge(const int NPE) const
Get randomised charge according to gain and gain spread.
static double getQmin()
Get width of charge distribution.
virtual bool applyThreshold(const double npe) const
Apply threshold.
virtual bool compare(const JPhotoElectron &first, const JPhotoElectron &second) const
Compare arrival times of photo-electrons.
virtual double getRiseTime(const double npe) const
Get time to reach threshold.
virtual double getSurvivalProbability(const int NPE) const
Probability that a hit survives the simulation of the PMT.
static double getTmin()
Get two photo-electron resolution for time-over-threshold.
virtual double getNPE(const double tot_ns) const
Get number of photo-electrons.
void operator()(const JCalibration &calibration, const JPMTData< JPMTSignal > &input, JPMTData< JPMTPulse > &output) const
Process hits.
virtual double getRandomTime(const double t_ns) const
Get randomised time according transition time distribution.
virtual void merge(JPMTData< JPMTPulse > &data) const
Merging of PMT hits.
file Auxiliary data structures and methods for detector calibration.
Definition JAnchor.hh:12
const double TIME_OVER_THRESHOLD_NS
Specification for time-over-threshold corresponding to a one photo-electron pulse.
double getChargeProbability(const JPMTSignalProcessorInterface &pmt, const double npe, const double NPE, const double precision=1.0e-4)
Get charge probability.
double putTime(const T &t1, const JCalibration &cal)
Get de-calibrated time.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Data structure for PMT digital pulse.
Data structure for single photo-electron.
static JPhotoElectron getEndMarker()
Get end marker.