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