DetectorClocksData.h
Go to the documentation of this file.
1 #ifndef LARDATAALG_DETECTORINFO_DETECTORCLOCKSDATA_H
2 #define LARDATAALG_DETECTORINFO_DETECTORCLOCKSDATA_H
3 
4 
6 
7 namespace detinfo {
8 
9  /** **************************************************************************
10  * @brief Contains all timing reference information for the detector.
11  *
12  * The timing information object can be obtained in _art_ from any
13  * implementation of `detinfo::DetectorClocksService`, and in non-_art_
14  * contexts from any `detinfo::DetectorClocks` provider implementation:
15  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
16  * detinfo::DetectorClocksData const detClocks
17  * = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
18  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19  * in _art_ context without a current event, and better:
20  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
21  * detinfo::DetectorClocksData const detClocks
22  * = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
23  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24  * in _art_ context when a current event is defined and available.
25  *
26  *
27  * Validity of the information
28  * ----------------------------
29  *
30  * The content of this object is static and disconnected from the context it
31  * was extracted from.
32  * The actual timing information can be updated event by event.
33  * In general, a new object might be needed for each event or run change.
34  *
35  *
36  * Time definitions
37  * =================
38  *
39  * @anchor DetectorClocksTimeDefinitions
40  * Many different components contribute to the operation of a LArTPC, and more
41  * are needed for the simulation.
42  * Some of the relevant events and time points associated with time are:
43  * * *hardware trigger*:
44  * @anchor DetectorClocksHardwareTrigger
45  * the instant the trigger happens or is expected; data acquisition reacts
46  * at this time (_multi-event_)
47  * * *beam gate opening*:
48  * @anchor DetectorClocksBeamGateOpening
49  * the instant the beam particles are expected to enter the detector
50  * (_multi-event_)
51  * * *software trigger*:
52  * @anchor DetectorClocksSoftwareTrigger
53  * additional logic can provide a more detailed estimation of the physics
54  * event time; this usually comes too late for the electronics time to be
55  * defined by it (_multi-event_)
56  * * *electronics start time*:
57  * @anchor DetectorClocksElectronicsStartTime
58  * a reference time instant; this is usually matching the
59  * @ref DetectorClocksTPCelectronicsStartTime "instant the TPC readout starts recording raw digits"
60  * (_multi-event_)
61  * * *TPC electronics start time*:
62  * @anchor DetectorClocksTPCelectronicsStartTime
63  * the instant corresponding to the first sample of the raw digits from
64  * TPC; for untampered `raw::RawDigit` objects, this time matches the
65  * general @ref DetectorClocksElectronicsStartTime "electronics start time"
66  * definition, and for the model of data acquisition described here, this
67  * time is by definition function of the
68  * @ref DetectorClocksHardwareTrigger "hardware trigger". Trimmed
69  * `raw::RawDigit` with a start portion clipped away will break the
70  * assumption of electronics time matching the TPC one (which is defined
71  * as seen by `raw::RawDigit`) (_multi-event_)
72  * * other electronics start times (*optical detector*, *cosmic ray tagger*,
73  * etc.)
74  * @anchor DetectorClocksOpticalElectronicsStartTime
75  * @anchor DetectorClocksExternalElectronicsStartTime
76  * represent the instant the respective data acquisition subsystems start
77  * digitizing the data from their detectors (_multi-event_)
78  * * *event trigger*:
79  * @anchor DetectorClocksExternalEventTrigger
80  * the instant the physics event is detected (in reconstruction jargon
81  * this is a @f$ t_{0} @f$); ideally, for most events involving beam
82  * particles this is the a little after
83  * @ref DetectorClocksBeamGateOpening "beam gate opening", and on top of
84  * the @ref DetectorClocksHardwareTrigger "hardware trigger" (_per event_)
85  * * *charge collection*:
86  * @anchor DetectorClocksChargeCollection
87  * the instant the ionisation from a particle reaches the charge readout
88  * (_per particle_)
89  * * *photon collection*:
90  * @anchor DetectorClocksPhotonCollection
91  * the instant scintillation photons from a particle reaches the optical
92  * readout (_per particle_)
93  * * *physics event time*:
94  * @anchor DetectorClocksPhysicsEvent
95  * the instant the main interaction happens; this is assigned by the event
96  * generator (_per event_)
97  * * *Geant4 time start*:
98  * @anchor DetectorClocksGeant4TimeStart
99  * assigned to each particle by the simulation of propagation
100  * through matter (Geant4); note that this is not necessarily the same as
101  * the @ref DetectorClocksPhysicsEvent "event time". (_per event_)
102  *
103  * In parentheses, it is indicated if such instant is defined for each
104  * considered particle, or for the complete physics process ("event") or for
105  * all physics processes recorded in the same time window ("multi-event").
106  *
107  * @anchor DetectorClocksTimeFrameDefinitions
108  * We can also define many ways to measure these times with respect to the
109  * others. We use the following time scales and frames:
110  * * *electronics time*:
111  * @anchor DetectorClocksElectronicsTime
112  * from the
113  * @ref DetectorClocksElectronicsStartTime "electronics start time"; this
114  * is the "glue" time frame connecting most of the others _[&micro;s]_
115  * * *TPC time*:
116  * @anchor DetectorClocksTPCelectronicsTime
117  * from the
118  * @ref DetectorClocksTPCelectronicsStartTime "TPC electronics start time"
119  * _[&micro;s]_
120  * * other electronics times (
121  * @anchor DetectorClocksOpticalElectronicsTime
122  * *optical electronics time*,
123  * @anchor DetectorClocksExternalElectronicsTime
124  * *external electronics time*, etc.):
125  * from the respective start times; note that in LArSoft the definition of
126  * these times is not fully defined (see
127  * @ref DetectorClocksElectronicsTimesNote "below").
128  * _[&micro;s]_
129  * * *beam gate time*:
130  * @anchor DetectorClocksBeamGateTime
131  * from the @ref DetectorClocksBeamGateOpening "beam gate opening time"
132  * _[&micro;s]_
133  * * *trigger time*:
134  * @anchor DetectorClocksTriggerTime
135  * from the @ref DetectorClocksHardwareTrigger "hardware trigger"
136  * _[&micro;s]_
137  * * *event time*:
138  * @anchor DetectorClocksEventTime
139  * from an @ref DetectorClocksPhysicsEvent "event trigger" _[&micro;s]_
140  * * *generation time*:
141  * @anchor DetectorClocksGenerationTime
142  * from the time the generators assigns to the
143  * @ref DetectorClocksPhysicsEvent "main physics event"; this is
144  * stored in the trajectory points of `simb::MCParticle` (usually the
145  * generators store a single trajectory point for each particle) _[ns]_
146  * * *GEANT4 time*:
147  * @anchor DetectorClocksGeant4Time
148  * from the @ref DetectorClocksGeant4TimeStart "GEANT4 time start"; this
149  * is stored into each trajectory point of `simb::MCParticle` produced by
150  * `LArG4` module or equivalent _[ns]_
151  * * *simulation time*:
152  * @anchor DetectorClocksSimulationTime
153  * the same as @ref DetectorClocksGeant4Time "GEANT4 time" (and also
154  * generation time, which in LArSoft happens to match the former) _[ns]_
155  *
156  * The list above reports in square brackets the "standard" unit, used for
157  * that times in that scale by all LArSoft code unless explicitly specified
158  * otherwise.
159  * For the times bound to readout, there is also an equivalent tick count time
160  * (from the TDC), which is an integral value representing the number of
161  * elapsed sampling periods of the detector they refer too (and that period
162  * may be different for each piece of hardware). Be sure to read the
163  * documentation about the methods you want to use to convert ticks, because
164  * their implications and assumptions may be quite subtle.
165  *
166  *
167  * Time conversions
168  * =================
169  *
170  * While this system is carefully designed to give physicists an headache,
171  * `detinfo::DetectorClocksData` attempts to tame this complexity
172  * by providing methods to convert from one time to the other.
173  * Also see `detinfo::DetectorTimings` for a higher level interface.
174  *
175  * The following table represents the available conversion functions, with the
176  * time in the first column as the time to be converted and in the columns the
177  * times to convert to:
178  *
179  * | to &rarr; | electronics time | (_ticks_) | TPC time ticks | trigger time | trigger clock ticks | beam gate time | Optical clock ticks | External clock ticks |
180  * | ------------------------------------------------------------: | --------------------- | -------------------- | ------------------ | ------------------------- | ------------------- | ------------------------- | --------------------- | ---------------------- |
181  * | (unit) | &micro;s | | | &micro;s | | &micro;s | | |
182  * | @ref DetectorClocksHardwareTrigger "hardware trigger" | `TriggerTime()` | `TPCClock()` | | | `TriggerClock()` | | `OpticalClock()` | `ExternalClock()` |
183  * | @ref DetectorClocksBeamGateOpening "beam gate point" | `BeamGateTime()` | | | | | | | |
184  * | @ref DetectorClocksElectronicsTime "electronics time" | | | `Time2Tick()` | | | | | |
185  * | &nbsp; (_ticks_) | | | `TPCTDC2Tick()` | | | | | |
186  * | @ref DetectorClocksTPCelectronicsTime "TPC time" | | | | | | | | |
187  * | &nbsp; (_ticks_) | `TPCTick2Time()` | `TPCTick2TDC()` | | `TPCTick2TrigTime()` | | `TPCTick2BeamTime()` | | |
188  * | @ref DetectorClocksTriggerTime "trigger time" | | | | | | | | |
189  * | &nbsp; (_ticks_) | | | | | | | | |
190  * | @ref DetectorClocksOpticalElectronicsTime "Optical" | | | | | | | | |
191  * | &nbsp; (_ticks_) | `OpticalTick2Time()` | `OpticalTick2TDC()` | | `OpticalTick2TrigTime()` | | `OpticalTick2BeamTime()` | | |
192  * | @ref DetectorClocksExternalElectronicsTime "External" | | | | | | | | |
193  * | &nbsp; (_ticks_) | `ExternalTick2Time()` | `ExternalTick2TDC()` | | `ExternalTick2TrigTime()` | | `ExternalTick2BeamTime()` | | |
194  * | @ref DetectorClocksSimulationTime "simulation time" | `G4ToElecTime()` | `TPCG4Time2TDC()` | `TPCG4Time2Tick()` | | | | `OpticalG4Time2TDC()` | `ExternalG4Time2TDC()` |
195  *
196  * Note that the complete definition of optical and external time requires
197  * additional information: see the
198  * @ref DetectorClocksElectronicsTimesNote "note on electronics time frames"
199  * below.
200  *
201  * The names are not thoroughly consistent, but they roughly follow the
202  * following rules:
203  * * the "trigger time" is named as `TrigTime` (but see below)
204  * * the "beam time" is named as `BeamTime` (but see below)
205  * * the @ref DetectorClocksElectronicsTime "electronics time" is named simply
206  * as `Time`; note that e.g. `TriggerTime()` and `BeamGateTime()` must be
207  * read as `Trigger` and `BeamGate` plus `Time()`, that is they return a
208  * `Time` value (i.e., electronics time) of the
209  * @ref DetectorClocksHardwareTrigger "hardware trigger instant" and
210  * @ref DetectorClocksBeamGateOpening "beam gate opening" instant, in the
211  * electronics time frame
212  * * the @ref DetectorClocksElectronicsTime "electronics time ticks" are
213  * labelled `TDC`
214  * * the @ref DetectorClocksSimulationTime "simulation time" is labelled `G4`
215  * or `G4Time`
216  * * `TPCTick` is @ref DetectorClocksTPCelectronicsTime "TPC electronics clock"
217  * ticks, measured from the
218  * @ref DetectorClocksTPCelectronicsStartTime "TPC electronics start time"
219  * * `Tick` (without further qualification) is equivalent to "TPCTick" above
220  * * `TPC` is usually used in conjunction with `Tick`, where it means
221  * `TPCTick`; but in `TPCG4Time2TDC()` it is a misnomer (the `TDC` wins in
222  * that the result is in ticks in
223  * @ref DetectorClocksElectronicsTime "electronics time" reference, not in
224  * @ref DetectorClocksTPCelectronicsTime "TPC electronics time")
225  *
226  *
227  * @anchor DetectorClocksElectronicsTimesNote
228  * Note on electronics time frames
229  * --------------------------------
230  *
231  * The conversion of some electronic time ticks, especially the
232  * @ref DetectorClocksOpticalElectronicsTime "optical" and
233  * @ref DetectorClocksExternalElectronicsTime "external" ones, assumes that
234  * the tick values to be converted are relative to an arbitrary reference,
235  * meaning that the absolute (or, e.g., electronics) time for tick `0` is not
236  * centrally defined. Instead, it is expected that additional information is
237  * provided to locate when this tick `0` actually happens. This is usually
238  * done via another pair of arguments, the frame number and the sample number
239  * within that frame. In the end, this just moves the questions to when frame
240  * `0` sample `0` happens: as those are input arguments, that absolute
241  * reference is left to the caller to define; but usually it is referring to
242  * the @ref DetectorClocksElectronicsStartTime "electronics start time".
243  *
244  *
245  * @anchor DetectorClocksIntroClocks
246  * Clocks
247  * -------
248  *
249  * A clock object (`ElecClock`) contains settings for a specific
250  * hardware clock. `DetectorClocksData` provides four clock objects:
251  *
252  * clock name | purpose | default time
253  * ----------------- | ------------------------------------- | ---------------
254  * `TPCClock()` | TPC readout and "general" electronics | `TriggerTime()`
255  * `OpticalClock()` | optical detector electronics | `TriggerTime()`
256  * `TriggerClock()` | hardware trigger electronics | `TriggerTime()`
257  * `ExternalClock()` | _not specified_ | `TriggerTime()`
258  *
259  * A clock object _does not change the time frame_: in the conversions between
260  * times and ticks, and the other way around, it always assumes that at tick 0
261  * (and frame 0, sample 0, if needed), the time is also 0 (see the
262  * @ref DetectorClocksElectronicsTimesNote "note on electronics time frames"
263  * above). Therefore, once again, **a clock object does not help in converting
264  * between different time scales**, and the output times are in the same time
265  * frame as the input.
266  *
267  * The "default time" is the time the clock is set when returned by the
268  * methods with no argument (e.g. `TriggerClock()`).
269  *
270  * All times (including frame lengths) are measured in microseconds, and all
271  * the frequencies are measured in megahertz.
272  *
273  * `TPCClock()` deals with TPC readout, and the "electronics time" clock is
274  * defined to have the same parameters as the TPC readout one.
275  *
276  * @note The `TriggerClock()` clock has little in common with `TriggerTime()`:
277  * the former is an electronics setting for a piece of hardware
278  * generating the trigger, while the latter is the instant the
279  * @ref DetectorClocksHardwareTrigger "hardware trigger" actually
280  * happened.
281  *
282  */
284  public:
285  /**
286  * @brief Returns a complete `detinfo::DetectorClocksData` object.
287  * @param g4_ref_time start of simulation time in electronics time scale [ns]
288  * @param trigger_offset_tpc hardware trigger time in electronics time
289  * (see the full description below)
290  * @param trigger_time the default hardware trigger time in electronics time
291  * @param beam_time the default beam gate opening time in electronics time
292  * @param tpc_clock use a copy of this as TPC clock object
293  * @param optical_clock use a copy of this as optical detector clock object
294  * @param trigger_clock use a copy of this as trigger clock object
295  * @param external_clock use a copy of this as external clock object
296  *
297  * Details of the definition of the different parameters:
298  *
299  * * `g4_ref_time` is the @ref DetectorClocksSimulationTime "simulation (Geant4) start time"
300  * in @ref DetectorClocksElectronicsTime "electronics time scale", i.e. when
301  * time `0.0` of simulation happens in the electronics time scale
302  * *`trigger_offset_tpc`: time elapsed between the
303  * @ref DetectorClocksTPCelectronicsStartTime "start of the TPC readout clock"
304  * and the @ref DetectorClocksHardwareTrigger "hardware trigger";
305  * it can be expressed in one of two ways:
306  * * negative number [&micro;s]: the offset of the start of the TPC
307  * readout clock start respect to the trigger time (where negative
308  * means that the clock starts _before_ the trigger arrives)
309  * * positive number [ticks]: the number of TPC readout clock tick at
310  * which the trigger arrives; despite this being a tick number, it can
311  * be fractional for added precision
312  *
313  * For example, `trigger_offset_tpc` of `-1600.0` means that the TDC clock
314  * starts 1.6 milliseconds before the hardware trigger. `trigger_offset_tpc`
315  * of `3200.0` means that the trigger arrives at the exact start of tick
316  * 3200 of the TPC readout. In this example, if the sampling frequency of
317  * that readout is 2 MHz, these two settings are equivalent.
318  * * *trigger_time* (_microseconds_): the default
319  * @ref DetectorClocksHardwareTrigger "hardware trigger time", measured
320  * in the @ref DetectorClocksElectronicsTime "electronics time frame"
321  * * *beam_time* (_microseconds_): the default
322  * @ref DetectorClocksBeamGateOpening "beam gate opening time", measured
323  * in the @ref DetectorClocksElectronicsTime "electronics time frame"
324  *
325  */
326  DetectorClocksData(double const g4_ref_time,
327  double const trigger_offset_tpc,
328  double const trig_time,
329  double const beam_time,
330  ElecClock const& tpc_clock,
331  ElecClock const& optical_clock,
332  ElecClock const& trigger_clock,
333  ElecClock const& external_clock)
334  : fTriggerTime{trig_time}
335  , fTriggerOffsetTPC{trigger_offset_tpc}
336  , fBeamGateTime{beam_time}
337  , fG4RefTime{g4_ref_time}
338  , fTPCClock{tpc_clock}
339  , fOpticalClock{optical_clock}
340  , fTriggerClock{trigger_clock}
341  , fExternalClock{external_clock}
342  {}
343 
344  /**
345  * @see `detinfo::DetectorClocks::TriggerOffsetTPC()`
346  *
347  * This offset is set via configuration parameter `TriggerOffsetTPC`.
348  */
349  double
351  {
352  if (fTriggerOffsetTPC < 0)
353  return fTriggerOffsetTPC;
354  else
355  return -fTriggerOffsetTPC / fTPCClock.Frequency(); // convert ticks to
356  // us
357  }
358 
359  /// Returns the @ref DetectorClocksTPCelectronicsStartTime "TPC electronics start time"
360  /// in @ref DetectorClocksElectronicsTime "electronics time".
361  double
362  TPCTime() const
363  {
364  return doTPCTime();
365  }
366 
367  /// Given Geant4 time [ns], returns relative time [us] w.r.t. electronics
368  /// time T0
369  double
370  G4ToElecTime(double const g4_time) const
371  {
372  return g4_time * 1.e-3 - fG4RefTime;
373  }
374 
375  /// Trigger electronics clock time in [us]
376  double
377  TriggerTime() const
378  {
379  return fTriggerTime;
380  }
381 
382  /// Beam gate electronics clock time in [us]
383  double
384  BeamGateTime() const
385  {
386  return fBeamGateTime;
387  }
388 
389  //
390  // Getters of TPC ElecClock
391  //
392  /// Borrow a const TPC clock with time set to Trigger time [us]
393  ElecClock const&
394  TPCClock() const noexcept
395  {
396  return fTPCClock;
397  }
398 
399  //
400  // Getters of Optical ElecClock
401  //
402  /// Borrow a const Optical clock with time set to Trigger time [us]
403  ElecClock const&
404  OpticalClock() const noexcept
405  {
406  return fOpticalClock;
407  }
408 
409  //
410  // Getters of Trigger ElecClock
411  //
412  /// Borrow a const Trigger clock with time set to Trigger time [us]
413  ElecClock const&
414  TriggerClock() const noexcept
415  {
416  return fTriggerClock;
417  }
418 
419  //
420  // Getters of External ElecClock
421  //
422  /// Borrow a const Trigger clock with time set to External Time [us]
423  ElecClock const&
424  ExternalClock() const noexcept
425  {
426  return fExternalClock;
427  }
428 
429  //
430  // Getters for time [us] w.r.t. trigger given information from waveform
431  //
432 
433  /// Given TPC time-tick (waveform index), returns time [us] w.r.t. trigger
434  /// time stamp
435  double
436  TPCTick2TrigTime(double const tick) const
437  {
438  return fTPCClock.TickPeriod() * tick + TriggerOffsetTPC();
439  }
440  /// Given TPC time-tick (waveform index), returns time [us] w.r.t. beam gate
441  /// time
442  double
443  TPCTick2BeamTime(double const tick) const
444  {
445  return TPCTick2TrigTime(tick) + TriggerTime() - BeamGateTime();
446  }
447  /// Given Optical time-tick (waveform index), sample and frame number,
448  /// returns time [us] w.r.t. trigger time stamp
449  double
450  OpticalTick2TrigTime(double const tick, size_t const sample, size_t const frame) const
451  {
452  return fOpticalClock.TickPeriod() * tick + fOpticalClock.Time(sample, frame) - TriggerTime();
453  }
454  /// Given Optical time-tick (waveform index), sample and frame number,
455  /// returns time [us] w.r.t. beam gate time stamp
456  double
457  OpticalTick2BeamTime(double const tick, size_t const sample, size_t const frame) const
458  {
459  return fOpticalClock.TickPeriod() * tick + fOpticalClock.Time(sample, frame) - BeamGateTime();
460  }
461  /// Given External time-tick (waveform index), sample and frame number,
462  /// returns time [us] w.r.t. trigger time stamp
463  double
464  ExternalTick2TrigTime(double const tick, size_t const sample, size_t const frame) const
465  {
466  return fExternalClock.TickPeriod() * tick + fExternalClock.Time(sample, frame) -
467  TriggerTime();
468  }
469  /// Given External time-tick (waveform index), sample and frame number,
470  /// returns time [us] w.r.t. beam gate time stamp
471  double
472  ExternalTick2BeamTime(double const tick, size_t const sample, size_t const frame) const
473  {
474  return fExternalClock.TickPeriod() * tick + fExternalClock.Time(sample, frame) -
475  BeamGateTime();
476  }
477 
478  /// Returns the specified electronics time in TDC electronics ticks.
479  double
480  Time2Tick(double const time) const
481  {
482  return doTime2Tick(time);
483  }
484 
485  //
486  // Getters for time [tdc] (electronics clock counting ... in double
487  // precision)
488  //
489 
490  /// Given TPC time-tick (waveform index), returns electronics clock count
491  /// [tdc]
492  double
493  TPCTick2TDC(double const tick) const
494  {
495  return (doTPCTime() / fTPCClock.TickPeriod() + tick);
496  }
497  /// Given G4 time [ns], returns corresponding TPC electronics clock count
498  /// [tdc]
499  double
500  TPCG4Time2TDC(double const g4time) const
501  {
502  return G4ToElecTime(g4time) / fTPCClock.TickPeriod();
503  }
504  /// Given Optical time-tick (waveform index), sample and frame number,
505  /// returns time electronics clock count [tdc]
506  double
507  OpticalTick2TDC(double const tick, size_t const sample, size_t const frame) const
508  {
509  return fOpticalClock.Ticks(sample, frame) + tick;
510  }
511  /// Given G4 time [ns], returns corresponding Optical electronics clock
512  /// count [tdc]
513  double
514  OpticalG4Time2TDC(double const g4time) const
515  {
516  return G4ToElecTime(g4time) / fOpticalClock.TickPeriod();
517  }
518  /// Given External time-tick (waveform index), sample and frame number,
519  /// returns time electronics clock count [tdc]
520  double
521  ExternalTick2TDC(double const tick, size_t const sample, size_t const frame) const
522  {
523  return fExternalClock.Ticks(sample, frame) + tick;
524  }
525  /// Given G4 time [ns], returns corresponding External electronics clock
526  /// count [tdc]
527  double
528  ExternalG4Time2TDC(double const g4time) const
529  {
530  return G4ToElecTime(g4time) / fExternalClock.TickPeriod();
531  }
532 
533  //
534  // Getters for time [us] (electronics clock counting ... in double
535  // precision)
536  //
537  /// Given TPC time-tick (waveform index), returns electronics clock [us]
538  double
539  TPCTick2Time(double const tick) const
540  {
541  return doTPCTime() + tick * fTPCClock.TickPeriod();
542  }
543  /// Given Optical time-tick (waveform index), sample and frame number,
544  /// returns electronics clock [us]
545  double
546  OpticalTick2Time(double const tick, size_t const sample, size_t const frame) const
547  {
548  return fOpticalClock.Time(sample, frame) + tick * fOpticalClock.TickPeriod();
549  }
550  /// Given External time-tick (waveform index), sample and frame number,
551  /// returns electronics clock [us]
552  double
553  ExternalTick2Time(double const tick, size_t const sample, size_t const frame) const
554  {
555  return fExternalClock.Time(sample, frame) + tick * fExternalClock.TickPeriod();
556  }
557 
558  //
559  // Getters for time [ticks] (waveform index number)
560  //
561 
562  /// Given electronics clock count [tdc] returns TPC time-tick
563  double
564  TPCTDC2Tick(double const tdc) const
565  {
566  return (tdc - doTPCTime() / fTPCClock.TickPeriod());
567  }
568  /// Given G4 time returns electronics clock count [tdc]
569  double
570  TPCG4Time2Tick(double const g4time) const
571  {
572  return (G4ToElecTime(g4time) - doTPCTime()) / fTPCClock.TickPeriod();
573  }
574 
575 
576  template <typename Stream>
577  void debugReport(Stream& out) const
578  {
579  out
580  << "Trigger time @ " << fTriggerTime
581  << "\nBeamGate time @ " << fBeamGateTime
582  << "\nTrigOffsetTPC @ " << TriggerOffsetTPC()
583  << "\nG4RefTime @ " << fG4RefTime
584  << "\nTPC Freq. @ " << fTPCClock.Frequency()
585  << "\nOptical Freq. @ " << fOpticalClock.Frequency()
586  << "\nTrigger Freq. @ " << fTriggerClock.Frequency()
587  << "\nExternal Freq. @ " << fExternalClock.Frequency()
588  << "\nTPC start tick [tdc] : " << TPCTick2TDC(0)
589  << "\nTPC start tick from trigger [us] : " << TPCTick2TrigTime(0)
590  << "\nTPC start tick from beam [us] : " << TPCTick2BeamTime(0)
591  << "\nTPC tdc=0 in tick : " << TPCTDC2Tick(0)
592  << "\nTPC G4 time 0 in tick : " << TPCG4Time2Tick(0)
593  << "\nTrigger in TPC tick : " << Time2Tick(TriggerTime())
594  << "\n";
595  }
596 
597  private:
598  /// Trigger time in [us]
599  double fTriggerTime;
600 
601  /// Time offset from trigger to TPC readout start
603 
604  /// BeamGate time in [us]
606 
607  /// Electronics clock counting start time in G4 time frame [us]
608  double fG4RefTime;
609 
614 
615  /// Implementation of `TPCTime()`.
616  double
617  doTPCTime() const
618  {
619  return fTriggerTime + fTriggerOffsetTPC;
620  }
621 
622  /// Implementation of `Time2Tick()`.
623  double
624  doTime2Tick(double const time) const
625  {
626  return (time - doTPCTime()) / fTPCClock.TickPeriod();
627  }
628 
629  }; // class DetectorClocksData
630 
631  inline int
633  {
634  return data.TPCClock().Ticks(data.TriggerOffsetTPC() * -1.);
635  }
636 
637  /**
638  * @brief Returns the period of the TPC readout electronics clock.
639  * @returns the period of the TPC readout electronics clock [&micro;s]
640  * @see `detinfo::DetectorClocks::TPCClock()`
641  */
642  inline double
644  {
645  return data.TPCClock().TickPeriod() * 1.e3;
646  }
647 
648 } // namespace detinfo
649 
650 #endif // LARDATAALG_DETECTORINFO_DETECTORCLOCKSDATA_H
double OpticalTick2TrigTime(double const tick, size_t const sample, size_t const frame) const
double TPCTick2BeamTime(double const tick) const
double fTriggerOffsetTPC
Time offset from trigger to TPC readout start.
double ExternalTick2BeamTime(double const tick, size_t const sample, size_t const frame) const
double OpticalTick2BeamTime(double const tick, size_t const sample, size_t const frame) const
double TPCG4Time2Tick(double const g4time) const
Given G4 time returns electronics clock count [tdc].
double TPCTick2Time(double const tick) const
Given TPC time-tick (waveform index), returns electronics clock [us].
ElecClock const & TriggerClock() const noexcept
Borrow a const Trigger clock with time set to Trigger time [us].
double TPCTDC2Tick(double const tdc) const
Given electronics clock count [tdc] returns TPC time-tick.
constexpr int Ticks() const noexcept
Current clock tick (that is, the number of tick Time() falls in).
Definition: ElecClock.h:205
double fBeamGateTime
BeamGate time in [us].
constexpr double TickPeriod() const noexcept
A single tick period in microseconds.
Definition: ElecClock.h:352
double doTPCTime() const
Implementation of TPCTime().
double fG4RefTime
Electronics clock counting start time in G4 time frame [us].
double BeamGateTime() const
Beam gate electronics clock time in [us].
double fTriggerTime
Trigger time in [us].
double TPCG4Time2TDC(double const g4time) const
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
ElecClock const & TPCClock() const noexcept
Borrow a const TPC clock with time set to Trigger time [us].
double OpticalTick2TDC(double const tick, size_t const sample, size_t const frame) const
ElecClock const & OpticalClock() const noexcept
Borrow a const Optical clock with time set to Trigger time [us].
constexpr double Time() const noexcept
Current time (as stored) in microseconds.
Definition: ElecClock.h:137
General LArSoft Utilities.
double TriggerTime() const
Trigger electronics clock time in [us].
DetectorClocksData(double const g4_ref_time, double const trigger_offset_tpc, double const trig_time, double const beam_time, ElecClock const &tpc_clock, ElecClock const &optical_clock, ElecClock const &trigger_clock, ElecClock const &external_clock)
Returns a complete detinfo::DetectorClocksData object.
double ExternalG4Time2TDC(double const g4time) const
double G4ToElecTime(double const g4_time) const
double OpticalG4Time2TDC(double const g4time) const
Contains all timing reference information for the detector.
double ExternalTick2TDC(double const tick, size_t const sample, size_t const frame) const
double OpticalTick2Time(double const tick, size_t const sample, size_t const frame) const
double ExternalTick2TrigTime(double const tick, size_t const sample, size_t const frame) const
int trigger_offset(DetectorClocksData const &data)
constexpr double Frequency() const
Frequency in MHz.
Definition: ElecClock.h:191
ElecClock const & ExternalClock() const noexcept
Borrow a const Trigger clock with time set to External Time [us].
double TPCTick2TrigTime(double const tick) const
double doTime2Tick(double const time) const
Implementation of Time2Tick().
Class representing the time measured by an electronics clock.
Definition: ElecClock.h:91
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
void debugReport(Stream &out) const
double TPCTick2TDC(double const tick) const
double Time2Tick(double const time) const
Returns the specified electronics time in TDC electronics ticks.
double ExternalTick2Time(double const tick, size_t const sample, size_t const frame) const