All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ReadoutTriggerGate.h
Go to the documentation of this file.
1 /**
2  * @file sbnobj/ICARUS/PMT/Trigger/Data/ReadoutTriggerGate.h
3  * @brief A trigger gate data object associated to one or more channels.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date December 16, 2019
6  *
7  * This is a header-only library.
8  */
9 
10 #ifndef SBNOBJ_ICARUS_PMT_TRIGGER_DATA_READOUTTRIGGERGATE_H
11 #define SBNOBJ_ICARUS_PMT_TRIGGER_DATA_READOUTTRIGGERGATE_H
12 
13 
14 // ICARUS libraries
16 
17 
18 // LArSoft libraries
19 
20 // C/C++ standard libraries
21 #include <iosfwd> // std::ostream
22 #include <vector>
23 #include <initializer_list>
24 #include <string>
25 #include <stdexcept> // std::runtime_error
26 #include <utility> // std::move()
27 #include <cstddef> // std::size_t
28 
29 
30 //------------------------------------------------------------------------------
31 
32 //
33 // declarations
34 //
35 namespace icarus::trigger {
36 
37  /// All `ReadoutTriggerGate` template instances derive from this tag.
39 
40  template <typename Tick, typename TickInterval, typename ChannelIDType>
42 
43  template <typename Tick, typename TickInterval, typename ChannelIDType>
44  std::ostream& operator<< (
46  );
47 
48 
49  // --- BEGIN Exceptions ------------------------------------------------------
50  /// @name Exceptions associated to `icarus::trigger::ReadoutTriggerGate` class
51  /// @{
52 
53  /// Base class for all exceptions from `icarus::trigger::ReadoutTriggerGate`.
54  struct ReadoutTriggerGateError: std::runtime_error
55  { using std::runtime_error::runtime_error; };
56 
57  /// No channel associated to the readout gate.
59  { using ReadoutTriggerGateError::ReadoutTriggerGateError; };
60 
61  /// More than one channel associated to the readout gate.
63  MoreThanOneChannelError(std::string msg, std::size_t nChannels)
64  : ReadoutTriggerGateError(std::move(msg)), nChannels(nChannels) {}
65  using ReadoutTriggerGateError::ReadoutTriggerGateError;
66 
67  std::size_t nChannels; ///< Number of channels.
68  }; // struct MoreThanOneChannelError
69 
70  // --- END Exceptions --------------------------------------------------------
71 
72  /// Type traits: `Gate` type derives from a `ReadoutTriggerGate` instance.
73  template <typename Gate>
75 
76  /// Flag: `true` if `Gate` type derives from a `ReadoutTriggerGate` instance.
77  template <typename Gate>
79 
80 } // namespace icarus::trigger
81 
82 
83 //------------------------------------------------------------------------------
84 /**
85  * @brief Logical multi-level gate associated to one or more readout channels.
86  * @tparam Tick type used to count the ticks
87  * @tparam TickInterval type used to quantify tick difference
88  * @tparam ChannelIDType type of channel ID
89  *
90  * This object is a trigger gate associated with one or more readout channels.
91  * The channels are expressed as channel identifiers.
92  *
93  * @note This object should be parametrized with optical ticks
94  * (`detinfo::timescales::optical_tick`). But currently the quantities
95  * (`util::quantity` derived objects) are not well suited to be serialized
96  * by ROOT, because
97  * 1. they are defined in `lardataalg` rather than `lardataobj`
98  * 2. writing all their serialization is daunting (see how ROOT dealt with
99  * GenVector vectors for an example of how to do it)
100  * So we chicken out here and use simple data types instead.
101  */
102 template <typename Tick, typename TickInterval, typename ChannelIDType>
104  : public icarus::trigger::TriggerGateData<Tick, TickInterval>
105  , public ReadoutTriggerGateTag
106  {
107  /// Type of the base class.
109 
110  /// Type of this class.
111  using This_t
113 
114  public:
115 
116  using ClockTick_t = Tick; ///< Tick point.
117  using ClockTicks_t = TickInterval; ///< Tick interval.
118  using ChannelID_t = ChannelIDType; ///< Type of stored channel ID.
119 
120  /// Type for gate data access.
122 
123  /// Type of list of associated channels.
124  using ChannelList_t = std::vector<ChannelID_t>;
125 
126 
127  /// Constructor: a closed gate with no associated channels
128  /// @see `ReadoutTriggerGate(std::initializer_list<ChannelID_t>)`,
129  /// `addChannel()`, `addChannels()`
130  ReadoutTriggerGate() = default;
131 
132  ReadoutTriggerGate(ReadoutTriggerGate const&) = default;
136 
137  /// Constructor: a closed gate associated to the specified `channels`.
138  ReadoutTriggerGate(std::initializer_list<ChannelID_t> channels);
139 
140 
141  //@{
142  /// Copies/steals all the levels from the specified data.
144  { GateData_t::operator=(data); return *this; }
146  { GateData_t::operator=(std::move(data)); return *this; }
147  //@}
148 
149 
150  // --- BEGIN Gate query ------------------------------------------------------
151  /// @name Gate query
152  /// @{
153 
154  /// Access to the underlying gate level data.
155  GateData_t const& gateLevels() const { return *this; }
156 
157  /// Access to the underlying gate level data (mutable).
158  GateData_t& gateLevels() { return *this; }
159 
160  /// @}
161  // --- END Gate query --------------------------------------------------------
162 
163 
164 
165  // --- BEGIN Access to channel information -----------------------------------
166  /**
167  * @brief Returns whether there is any channel id associated to the gate data.
168  * @return whether channel ids are associated to the gate data
169  * @see `hasChannel()`
170  */
171  bool hasChannels() const { return !fChannels.empty(); }
172 
173  /**
174  * @brief Returns whether exactly one channel id associated to the gate data.
175  * @return whether exactly one channel id associated to the gate data
176  * @see `channel()`
177  *
178  * If this methods returns `true`, `channel()` can safely be used.
179  */
180  bool hasChannel() const { return nChannels() == 1U; }
181 
182  /// Returns the number of associated channels.
183  std::size_t nChannels() const { return fChannels.size(); }
184 
185  /**
186  * @brief Returns the channels associated to the gate data.
187  * @return an iterable object with all channel IDs associated to the gate data
188  * @see `hasChannels()`, `channel()`
189  */
190  decltype(auto) channels() const;
191 
192  /**
193  * @brief Returns the channel associated to the gate data.
194  * @return the channel associated to the gate data
195  * @throw MoreThanOneChannelError if more than one associated channel
196  * @throw NoChannelError if no channel is associated
197  * @see `hasChannel()`
198  */
199  ChannelID_t channel() const;
200 
201 
202  /// Associates the specified channel to this readout gate.
204 
205  /// Associates the specified channels to this readout gate.
207  { associateChannels(channels); return *this; }
208 
209  // --- END Access to channel information -------------------------------------
210 
211 
212 
213  // --- BEGIN Combination operations ------------------------------------------
214  /// @name Combination operations
215  /// @{
216 
217  /**
218  * @brief Combines with a gate, keeping the minimum opening among the two.
219  * @param other gate to combine to
220  * @return this object
221  * @see `Max()`
222  *
223  * Multi-level equivalent of an _and_ logical operation.
224  */
226 
227  /**
228  * @brief Combines with a gate, keeping the maximum opening among the two.
229  * @param other gate to combine to
230  * @return this object
231  * @see `Min()`, `Sum()`
232  *
233  * Multi-level equivalent of an _or_ logical operation.
234  */
236 
237  /**
238  * @brief Combines with a gate, keeping the sum of openings of the two.
239  * @param other gate to combine to
240  * @return this object
241  * @see `Min()`, `Max()`
242  */
244 
245  /**
246  * @brief Combines with a gate, keeping the product of openings of the two.
247  * @param other gate to combine to
248  * @return this object
249  * @see `Min()`, `Max()`, `Sum()`
250  */
252 
253  /**
254  * @brief Returns a gate with the minimum opening between the specified two.
255  * @param a first gate
256  * @param b second gate
257  * @return gate with at every tick the minimum opening among `a` and `b`
258  * @see `Max()`
259  *
260  * Multi-level equivalent of an _and_ logical operation.
261  */
262  static ReadoutTriggerGate Min
263  (ReadoutTriggerGate const& a, ReadoutTriggerGate const& b);
264 
265  /**
266  * @brief Returns a gate with the maximum opening between the specified two.
267  * @param a first gate
268  * @param b second gate
269  * @return gate with at every tick the maximum opening among `a` and `b`
270  * @see `Min()`, `Sum()`
271  *
272  * Multi-level equivalent of an _or_ logical operation.
273  */
274  static ReadoutTriggerGate Max
275  (ReadoutTriggerGate const& a, ReadoutTriggerGate const& b);
276 
277  /**
278  * @brief Returns a gate with opening sum of the specified two.
279  * @param a first gate
280  * @param b second gate
281  * @return gate with at every tick the total opening of `a` and `b`
282  * @see `Max()`
283  */
284  static ReadoutTriggerGate Sum
285  (ReadoutTriggerGate const& a, ReadoutTriggerGate const& b);
286 
287  /**
288  * @brief Returns a gate with opening product of the specified two.
289  * @param a first gate
290  * @param b second gate
291  * @return gate with at every tick the product of openings of `a` and `b`
292  * @see `Max()`
293  */
294  static ReadoutTriggerGate Mul
295  (ReadoutTriggerGate const& a, ReadoutTriggerGate const& b);
296 
297 
298  /**
299  * @brief Returns a gate combination of the openings of two other gates.
300  * @tparam Op binary operation: `OpeningCount_t` (x2) to `OpeningCount_t`
301  * @param op symmetric binary combination operation
302  * @param a first gate
303  * @param b second gate
304  * @return gate with opening combination of `a` and `b`
305  *
306  * For this algorithm to work, the operation needs to be symmetric, i.e.
307  * `op(c1, c2) == op(c2, c1)` for every valid combinations of counts
308  * `c1` and `c2`.
309  *
310  */
311  template <typename Op>
313  Op&& op, ReadoutTriggerGate const& a, ReadoutTriggerGate const& b,
314  ClockTicks_t aDelay = ClockTicks_t{ 0 },
315  ClockTicks_t bDelay = ClockTicks_t{ 0 }
316  );
317 
318  /// @}
319  // --- END Combination operations --------------------------------------------
320 
321  // standard comparison operators: all must be the same
322  bool operator == (ReadoutTriggerGate const&) const;
323  bool operator != (ReadoutTriggerGate const&) const;
324 
325  protected:
326  // we allow some manipulation by the derived classes
328 
329  /// Protected constructor: set the data directly.
331  : Base_t(std::move(gateLevel)), fChannels(std::move(channels))
332  { normalizeChannels(); }
333 
334  /// Protected constructor: set the data directly.
335  template <typename BIter, typename EIter>
336  ReadoutTriggerGate(GateEvolution_t&& gateLevel, BIter b, EIter e)
337  : Base_t(std::move(gateLevel)), fChannels(b, e)
338  { normalizeChannels(); }
339 
340 
341  /// Removes duplicate channel IDs and sorts the remaining ones.
343 
344  //@{
345  /// Associates this data with the channels from the specified list.
346  void associateChannels
347  (std::initializer_list<ChannelID_t> const& moreChannels);
348  void associateChannels(ChannelList_t const& moreChannels);
349  //@}
350 
351  /// Associates this data with the channels from the `other` gate.
353  { associateChannels(other.channels()); }
354 
355  template <typename BIter, typename EIter>
357  (ChannelList_t& channels, BIter b, EIter e);
358 
359 
360  /// Removes duplicate channel IDs.
362 
363  //@{
364  /// Removes duplicate channel IDs and sorts the remaining ones.
367  //@}
368 
369  /// Adds channels from iterators `b` to `e` into `channels` (returned).
370  template <typename BIter, typename EIter>
372  (ChannelList_t& channels, BIter b, EIter e);
373 
374 
375  /// Returns a merged list of channels from `a` and `b`.
377  (ChannelList_t const& a, ChannelList_t const& b);
378 
379  private:
380 
381  /// List of readout channels associated to this data.
383 
384 
385  }; // class icarus::trigger::ReadoutTriggerGate
386 
387 
388 //------------------------------------------------------------------------------
389 //--- template implementation
390 //------------------------------------------------------------------------------
391 
392 #include "sbnobj/ICARUS/PMT/Trigger/Data/ReadoutTriggerGate.tcc"
393 
394 //------------------------------------------------------------------------------
395 
396 #endif // SBNOBJ_ICARUS_PMT_TRIGGER_DATA_READOUTTRIGGERGATE_H
decltype(auto) channels() const
Returns the channels associated to the gate data.
ReadoutTriggerGate & Mul(ReadoutTriggerGate const &other)
Combines with a gate, keeping the product of openings of the two.
This_t & addChannels(std::initializer_list< ChannelID_t > channels)
Associates the specified channels to this readout gate.
ChannelID_t channel() const
Returns the channel associated to the gate data.
ChannelList_t & normalizeChannels()
Removes duplicate channel IDs and sorts the remaining ones.
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
icarus::trigger::ReadoutTriggerGate< Tick, TickInterval, ChannelIDType > This_t
Type of this class.
std::size_t nChannels() const
Returns the number of associated channels.
constexpr bool isReadoutTriggerGate_v
Flag: true if Gate type derives from a ReadoutTriggerGate instance.
std::ostream & operator<<(std::ostream &out, icarus::trigger::ApplyBeamGateClass const &gate)
bool operator!=(ReadoutTriggerGate const &) const
ReadoutTriggerGate & Max(ReadoutTriggerGate const &other)
Combines with a gate, keeping the maximum opening among the two.
std::vector< ChannelID_t > ChannelList_t
Type of list of associated channels.
More than one channel associated to the readout gate.
void associateChannels(std::initializer_list< ChannelID_t > const &moreChannels)
Associates this data with the channels from the specified list.
static ReadoutTriggerGate SymmetricCombination(Op &&op, ReadoutTriggerGate const &a, ReadoutTriggerGate const &b, ClockTicks_t aDelay=ClockTicks_t{0}, ClockTicks_t bDelay=ClockTicks_t{0})
Returns a gate combination of the openings of two other gates.
ChannelIDType ChannelID_t
Type of stored channel ID.
GateData_t const & gateLevels() const
Access to the underlying gate level data.
process_name gaushit a
static ChannelList_t & mergeSortedChannelsInto(ChannelList_t &channels, BIter b, EIter e)
ReadoutTriggerGate & Min(ReadoutTriggerGate const &other)
Combines with a gate, keeping the minimum opening among the two.
This_t & addChannel(ChannelID_t const channel)
Associates the specified channel to this readout gate.
static ChannelList_t & mergeChannelsInto(ChannelList_t &channels, BIter b, EIter e)
Adds channels from iterators b to e into channels (returned).
Base class for all exceptions from icarus::trigger::ReadoutTriggerGate.
Logical multi-level gate associated to one or more readout channels.
A logical multilevel gate for triggering.
void associateChannelsFromGate(ReadoutTriggerGate const &other)
Associates this data with the channels from the other gate.
bool hasChannel() const
Returns whether exactly one channel id associated to the gate data.
std::size_t nChannels
Number of channels.
static ChannelList_t mergeChannels(ChannelList_t const &a, ChannelList_t const &b)
Returns a merged list of channels from a and b.
Type traits: Gate type derives from a ReadoutTriggerGate instance.
GateData_t & gateLevels()
Access to the underlying gate level data (mutable).
static ChannelList_t & normalizeSortedChannels(ChannelList_t &channels)
Removes duplicate channel IDs.
MoreThanOneChannelError(std::string msg, std::size_t nChannels)
ReadoutTriggerGate(GateEvolution_t &&gateLevel, BIter b, EIter e)
Protected constructor: set the data directly.
ReadoutTriggerGate & operator=(ReadoutTriggerGate const &)=default
ReadoutTriggerGate & Sum(ReadoutTriggerGate const &other)
Combines with a gate, keeping the sum of openings of the two.
TickInterval ClockTicks_t
Tick interval.
do i e
typename Base_t::GateEvolution_t GateEvolution_t
Logical multi-level gate.
icarus::trigger::TriggerGateData< Tick, TickInterval > Base_t
Type of the base class.
No channel associated to the readout gate.
bool hasChannels() const
Returns whether there is any channel id associated to the gate data.
std::vector< Status > GateEvolution_t
Type to describe the time evolution of the gate.
All ReadoutTriggerGate template instances derive from this tag.
bool operator==(ReadoutTriggerGate const &) const
ChannelList_t fChannels
List of readout channels associated to this data.
ReadoutTriggerGate(GateEvolution_t &&gateLevel, ChannelList_t &&channels)
Protected constructor: set the data directly.