All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TrackedTriggerGate.h
Go to the documentation of this file.
1 /**
2  * @file icaruscode/PMT/Trigger/Utilities/TrackedTriggerGate.h
3  * @brief A wrapper to trigger gate objects tracking the contributions.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date December 21, 2021
6  *
7  * This library is header-only.
8  */
9 
10 #ifndef ICARUSCODE_PMT_TRIGGER_UTILITIES_TRACKEDTRIGGERGATE_H
11 #define ICARUSCODE_PMT_TRIGGER_UTILITIES_TRACKEDTRIGGERGATE_H
12 
13 // SBN libraries
15 
16 // LArSoft libraries
17 #include "larcorealg/CoreUtils/span.h" // util::make_transformed_span()
18 
19 // C/C++ standard libraries
20 #include <iosfwd>
21 #include <set>
22 #include <functional> // std::mem_fn()
23 #include <utility> // std::in_place_t, std::forward(), ...
24 #include <type_traits> // std::true_type...
25 
26 
27 
28 // -----------------------------------------------------------------------------
29 namespace icarus::trigger {
30 
31  /// Trait returning whether `T` is some form of TrackedTriggerGate`.
32  template <typename T>
34 
35  /// Whether `T` is some form of TrackedTriggerGate`.
36  template <typename T>
38 
39  template <typename Gate, typename TrackedType>
40  class TrackedTriggerGate; // see below
41 
42  template <typename Gate, typename TrackedType>
43  std::ostream& operator<<
44  (std::ostream& out, TrackedTriggerGate<Gate, TrackedType> const& gate);
45 
46 
47  // --- BEGIN -- TrackedTriggerGate simple helpers ----------------------------
48  /// @name `icarus::trigger::TrackedTriggerGate` simple helpers
49  /// @{
50 
51  /// Returns the trigger data (a `TriggerGateData`) from the specofied `gate`.
52  template <typename Gate>
53  decltype(auto) gateDataIn(Gate&& gate);
54 
55  /// Returns the trigger gate (a `ReadoutTriggerGate`) from the specified `gate`.
56  template <typename Gate>
57  decltype(auto) gateIn(Gate&& gate);
58 
59  /// Returns a sequence of all the readout trigger gates contained in
60  /// `trackingGates`.
61  template <typename TrackingGateColl>
62  auto gatesIn(TrackingGateColl& trackingGates);
63 
64 
65 
66  /// @}
67  // --- END ---- TrackedTriggerGate simple helpers ----------------------------
68 
69 } // namespace icarus::trigger
70 
71 // -----------------------------------------------------------------------------
72 /**
73  * @brief A wrapper to trigger gate objects tracking the input of operations.
74  * @tparam Gate type of trigger gate object being wrapped
75  * @tparam TrackedType type of the objects being tracked
76  *
77  * This object includes its own `Gate` object, plus `tracking()`.
78  *
79  * Functions taking as argument a generic sequence of `Gate` objects can be
80  * passed the result of `icarus::trigger::gatesIn()` (sold separately),
81  * which behaves like a sequence of `Gate`.
82  *
83  * Supporting functions can add specific tracking operations when operating
84  * of a `TrackedTriggerGate` object. The trait
85  * `icarus::trigger::isTrackedTriggerGate_v` will return whether that is the
86  * case.
87  *
88  * Tracking is performed by accessing `tracking()` and `add()`'ing objects
89  * to be tracked. Tracking is currently just a collection of objects of a
90  * specific type (`TrackedType`). That type is expected to support strict
91  * comparison. A copy of each tracking object is used and owned: if the object
92  * is complex and externally owned, a pointer or handle should be stored
93  * as tracking object instead of the object itself.
94  * If an object is already present, it is not added again into the tracking.
95  *
96  * The `Gate` type is expected to be a trigger gate type, like
97  * `icarus::trigger::ReadoutTriggerGate`.
98  */
99 template <typename Gate, typename TrackedType>
100 class icarus::trigger::TrackedTriggerGate {
101 
102  public:
103 
104  using TriggerGate_t = Gate; ///< Gate type being wrapped.
105  using Tracked_t = TrackedType; ///< Type for tracking.
106 
107  /// Tracked information. Interface is pretty minimal so far.
108  class TrackingInfo {
109 
110  std::set<Tracked_t> fTracked; ///< All tracked objects.
111 
112  public:
113 
114  /// Add an object to the list of tracked objects, if it's not present yet.
115  void add(TrackedType tracked);
116 
117  /// Adds all the objects `tracked` in the specified information object.
118  void add(TrackingInfo const& tracked);
119 
120  /// Returns the number of objects currently tracked;
121  std::size_t nTracked() const;
122 
123  /// Whether any tracked object is present.
124  bool hasTracked() const;
125 
126  /// Returns an iterable of all tracked objects.
127  auto getTracked() const;
128 
129  }; // class TrackingInfo
130 
131  /// Default constructor: default-constructed gate, no tracking.
132  TrackedTriggerGate() = default;
133 
134  /// Constructor: copies the data of the specified gate (no tracking added).
135  TrackedTriggerGate(TriggerGate_t gate): fGate(std::move(gate)) {}
136 
137 
138  // @{
139 
140  /// Returns the tracking information.
141  TrackingInfo const& tracking() const { return fTracking; }
142  TrackingInfo& tracking() { return fTracking; }
143 
144  // @}
145 
146 
147  // @{
148 
149  /// Returns the enclosed gate.
150  TriggerGate_t const& gate() const& { return fGate; }
151  TriggerGate_t& gate() & { return fGate; }
152  TriggerGate_t&& gate() && { return std::move(fGate); }
153 
154  // @}
155 
156 
157  /// Returns the list of channels of the enclosed gate.
158  decltype(auto) channels() const { return gate().channels(); }
159 
160 
161  private:
162  TriggerGate_t fGate; ///< Local copy of the gate information.
163  TrackingInfo fTracking; ///< Tracking information.
164 
165 }; // class icarus::trigger::TrackedTriggerGate
166 
167 
168 // -----------------------------------------------------------------------------
169 // --- template implementation
170 // -----------------------------------------------------------------------------
171 namespace icarus::trigger {
172 
173  namespace details {
174 
175  template <typename T>
176  struct isTrackedTriggerGateImpl: std::false_type {};
177 
178  template <typename Gate, typename TrackedType>
179  struct isTrackedTriggerGateImpl<TrackedTriggerGate<Gate, TrackedType>>
180  : std::true_type
181  {};
182 
183  } // namespace details
184 
185  template <typename T>
186  struct isTrackedTriggerGate
187  : details::isTrackedTriggerGateImpl<std::decay_t<T>>
188  {};
189 
190 
191 } // namespace icarus::trigger
192 
193 
194 // -----------------------------------------------------------------------------
195 // --- icarus::trigger::TrackedTriggerGate<>
196 // -----------------------------------------------------------------------------
197 template <typename Gate, typename TrackedType>
199  (TrackedType tracked)
200  { fTracked.insert(std::move(tracked)); }
201 
202 
203 // -----------------------------------------------------------------------------
204 template <typename Gate, typename TrackedType>
206  (TrackingInfo const& tracked)
207  { fTracked.insert(begin(tracked.fTracked), end(tracked.fTracked)); }
208 
209 
210 // -----------------------------------------------------------------------------
211 template <typename Gate, typename TrackedType>
212 std::size_t
214  const
215  { return fTracked.size(); }
216 
217 
218 // -----------------------------------------------------------------------------
219 template <typename Gate, typename TrackedType>
220 bool
222  const
223  { return !(fTracked.empty()); }
224 
225 
226 // -----------------------------------------------------------------------------
227 template <typename Gate, typename TrackedType>
229  const
230  { return fTracked; }
231 
232 
233 // -----------------------------------------------------------------------------
234 // --- free function implementation
235 // -----------------------------------------------------------------------------
236 namespace icarus::trigger::details {
237 
238  template <typename T, typename = void>
239  struct GateExtractorImpl; // undefined
240 
241  template <typename Gate>
243  Gate,
244  std::enable_if_t<icarus::trigger::isReadoutTriggerGate<Gate>::value>
245  >
246  {
247  // bypass
248  template <typename T>
249  static decltype(auto) gateFrom(T&& gate) { return std::forward<T>(gate); }
250 
251  // TriggerGateData::gateLevels() as of now does not support rvalue refs
252  static typename Gate::GateData_t&& gateDataFrom(Gate&& gate)
253  { return std::move(gateFrom(std::move(gate)).gateLevels()); }
254  static decltype(auto) gateDataFrom(Gate const& gate)
255  { return gateFrom(gate).gateLevels(); }
256  static decltype(auto) gateDataFrom(Gate& gate)
257  { return gateFrom(gate).gateLevels(); }
258  };
259 
260  template <typename Gate>
262  Gate,
263  std::enable_if_t<isTrackedTriggerGate<Gate>::value>
264  >
265  {
266  template <typename T>
267  static decltype(auto) gateFrom(T&& gate)
268  { return std::forward<T>(gate).gate(); }
269  template <typename T>
270  static decltype(auto) gateDataFrom(T&& gate)
271  { return gateDataIn(gateFrom(std::forward<T>(gate))); }
272  };
273 
274  template <typename Tick, typename TickInterval>
275  struct GateExtractorImpl<icarus::trigger::TriggerGateData<Tick, TickInterval>>
276  {
277  // template <typename T>
278  // static decltype(auto) gateFrom(T&& gate); // not defined!
279  template <typename T>
280  static decltype(auto) gateDataFrom(T&& gate)
281  { return std::forward<T>(gate); }
282  };
283 
284 } // namespace icarus::trigger::details
285 
286 
287 // -----------------------------------------------------------------------------
288 template <typename Gate, typename TrackedType>
289 std::ostream& icarus::trigger::operator<<
290  (std::ostream& out, TrackedTriggerGate<Gate, TrackedType> const& gate)
291  { return out << gateIn(gate); }
292 
293 
294 // -----------------------------------------------------------------------------
295 template <typename Gate>
296 decltype(auto) icarus::trigger::gateIn(Gate&& gate) {
297  return details::GateExtractorImpl<std::decay_t<Gate>>::gateFrom
298  (std::forward<Gate>(gate));
299 }
300 
301 
302 // -----------------------------------------------------------------------------
303 template <typename Gate>
304 decltype(auto) icarus::trigger::gateDataIn(Gate&& gate) {
305  return details::GateExtractorImpl<std::decay_t<Gate>>::gateDataFrom
306  (std::forward<Gate>(gate));
307 }
308 
309 
310 // -----------------------------------------------------------------------------
311 template <typename TrackingGateColl>
312 auto icarus::trigger::gatesIn(TrackingGateColl& trackingGates) {
313 
314  // C++20: this is definitely a template concept...
315 
316  // constantness is driven by the one of type `TrackedTriggerGate`;
317  // decltype(auto) return preserves referencehood
318  auto getGate = [](auto& gate) -> decltype(auto) { return gateIn(gate); };
319 
320 #if 0
321  // C++20: this is some
322  return trackingGates | std::ranges::view::transform(getGate);
323 #endif // 0
324 
325  return util::make_transformed_span(trackingGates, getGate);
326 
327 } // icarus::trigger::gatesIn()
328 
329 
330 // -----------------------------------------------------------------------------
331 
332 
333 #endif // ICARUSCODE_PMT_TRIGGER_UTILITIES_TRACKEDTRIGGERGATE_H
TrackedTriggerGate(TriggerGate_t gate)
Constructor: copies the data of the specified gate (no tracking added).
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
static constexpr Sample_t transform(Sample_t sample)
An object with a begin and end iterator.
A wrapper to trigger gate objects tracking the input of operations.
constexpr bool isTrackedTriggerGate_v
Whether T is some form of TrackedTriggerGate`.
auto getTracked() const
Returns an iterable of all tracked objects.
std::size_t nTracked() const
Returns the number of objects currently tracked;.
auto gatesIn(TrackingGateColl &trackingGates)
void add(TrackedType tracked)
Add an object to the list of tracked objects, if it&#39;s not present yet.
TriggerGate_t fGate
Local copy of the gate information.
TrackingInfo const & tracking() const
Returns the tracking information.
auto make_transformed_span(BIter begin, EIter end, Op &&op)
Definition: span.h:294
Tracked information. Interface is pretty minimal so far.
Trait returning whether T is some form of TrackedTriggerGate`.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:2191
Gate TriggerGate_t
Gate type being wrapped.
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
TrackingInfo fTracking
Tracking information.
std::set< Tracked_t > fTracked
All tracked objects.
TriggerGate_t const & gate() const &
Returns the enclosed gate.
bool hasTracked() const
Whether any tracked object is present.
A trigger gate data object associated to one or more channels.
Logical multi-level gate.
decltype(auto) gateDataIn(Gate &&gate)
Returns the trigger data (a TriggerGateData) from the specofied gate.
decltype(auto) gateIn(Gate &&gate)
Returns the trigger gate (a ReadoutTriggerGate) from the specified gate.
TrackedType Tracked_t
Type for tracking.