All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OpticalTriggerGate.cxx
Go to the documentation of this file.
1 /**
2  * @file sbnobj/ICARUS/PMT/Trigger/Data/OpticalTriggerGate.cxx
3  * @brief A trigger gate data object for optical detector electronics.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date April 1, 2019
6  * @see sbnobj/ICARUS/PMT/Trigger/Data/OpticalTriggerGate.h
7  *
8  */
9 
10 // ICARUS libraries
12 
13 // C/C++ standard libraries
14 #include <ostream>
15 #include <algorithm> // std::inplace_merge(), std::unique(), ...
16 
17 
18 //------------------------------------------------------------------------------
19 namespace {
20  /// Comparison for `raw::OpDetWaveform`.
21  struct OpDetWaveformComp {
22 
23  /// Returns whether `a < b`.
24  static bool less(raw::OpDetWaveform const& a, raw::OpDetWaveform const& b)
25  {
26  if (a.ChannelNumber() < b.ChannelNumber()) return true;
27  if (a.ChannelNumber() > b.ChannelNumber()) return false;
28 
29  if (a.TimeStamp() < b.TimeStamp()) return true;
30  if (a.TimeStamp() > b.TimeStamp()) return false;
31 
32  return false; // they're equivalent
33  } // less()
34 
35  bool operator()
36  (raw::OpDetWaveform const& a, raw::OpDetWaveform const& b) const
37  { return less(a, b); }
38 
39  bool operator()
40  (raw::OpDetWaveform const* a, raw::OpDetWaveform const* b) const
41  { return less(*a, *b); }
42 
43  }; // OpDetWaveformComp
44 
45 
46  //----------------------------------------------------------------------------
47 
48 } // local namespace
49 
50 
51 //------------------------------------------------------------------------------
52 //--- icarus::trigger::OpticalTriggerGate
53 //------------------------------------------------------------------------------
55 (Waveforms_t const& moreWaveforms)
56 {
57  //
58  // add channels
59  //
60  associateChannels(extractChannels(moreWaveforms));
61 
62  //
63  // merge the two lists, then sort them
64  //
65  auto const middle = fWaveforms.insert
66  (fWaveforms.end(), moreWaveforms.begin(), moreWaveforms.end());
67  std::inplace_merge
68  (fWaveforms.begin(), middle, fWaveforms.end(), ::OpDetWaveformComp());
69 
70  // finally remove any duplicate (there should be none, should it?)
71  auto const actualEnd
72  = std::unique(fWaveforms.begin(), fWaveforms.end()); // pointer comparison
73  fWaveforms.erase(actualEnd, fWaveforms.end());
74 
75 
76 } // OpticalTriggerGate::registerWaveforms()
77 
78 
79 //------------------------------------------------------------------------------
81 (Waveforms_t const& a, Waveforms_t const& b) -> Waveforms_t
82 {
83  Waveforms_t merged;
84  merged.reserve(a.size() + b.size());
85  std::merge(
86  a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(merged),
87  ::OpDetWaveformComp()
88  );
89 
90  // finally remove any duplicate (there should be non, should it?)
91  auto const actualEnd
92  = std::unique(merged.begin(), merged.end()); // pointer comparison
93  merged.erase(actualEnd, merged.end());
94 
95  return merged;
96 } // icarus::trigger::OpticalTriggerGate::mergeWaveforms()
97 
98 
99 //------------------------------------------------------------------------------
101 (OpticalTriggerGate const& other)
102 {
103  GateData_t::Min(other);
104  mergeWaveformsFromGate(other);
105  return *this;
106 } // icarus::trigger::OpticalTriggerGate::Min()
107 
108 
109 //------------------------------------------------------------------------------
111 (OpticalTriggerGate const& other)
112 {
113  GateData_t::Max(other);
114  mergeWaveformsFromGate(other);
115  return *this;
116 } // icarus::trigger::OpticalTriggerGate::Max()
117 
118 
119 //------------------------------------------------------------------------------
121 (OpticalTriggerGate const& other)
122 {
123  GateData_t::Sum(other);
124  mergeWaveformsFromGate(other);
125  return *this;
126 } // icarus::trigger::OpticalTriggerGate::Sum()
127 
128 
129 //------------------------------------------------------------------------------
131 (OpticalTriggerGate const& other)
132 {
133  GateData_t::Mul(other);
134  mergeWaveformsFromGate(other);
135  return *this;
136 } // icarus::trigger::OpticalTriggerGate::Mul()
137 
138 
139 //------------------------------------------------------------------------------
142 { auto combination { a }; combination.Min(b); return combination; }
143 
144 
145 //------------------------------------------------------------------------------
148 { auto combination { a }; combination.Max(b); return combination; }
149 
150 
151 //------------------------------------------------------------------------------
154 { auto combination { a }; combination.Sum(b); return combination; }
155 
156 
157 //------------------------------------------------------------------------------
160 { auto combination { a }; combination.Mul(b); return combination; }
161 
162 
163 //------------------------------------------------------------------------------
164 template <typename Op>
167  Op&& op, OpticalTriggerGate const& a, OpticalTriggerGate const& b,
168  TriggerGateTicks_t aDelay /* = TriggerGateTicks_t{ 0 } */,
169  TriggerGateTicks_t bDelay /* = TriggerGateTicks_t{ 0 } */
170  )
171 {
172  return {
174  (std::forward<Op>(op), a, b, aDelay, bDelay),
176  };
177 
178 } // icarus::trigger::OpticalTriggerGate::SymmetricCombination()
179 
180 
181 //------------------------------------------------------------------------------
183 (OpticalTriggerGate const& other) const
184 {
185  return
186  (gateLevels() == other.gateLevels()) && (waveforms() == other.waveforms());
187 } // icarus::trigger::OpticalTriggerGate::operator==()
188 
189 
190 //------------------------------------------------------------------------------
191 bool icarus::trigger::OpticalTriggerGate::operator!=
192 (OpticalTriggerGate const& other) const
193 {
194  return
195  (gateLevels() != other.gateLevels()) || (waveforms() != other.waveforms());
196 } // icarus::trigger::OpticalTriggerGate::operator==()
197 
198 
199 //------------------------------------------------------------------------------
201 (raw::OpDetWaveform const& waveform)
202 {
203  // insertion keeps the list ordered and the elements unique
204  auto const& insertionPoint = std::lower_bound
205  (fWaveforms.begin(), fWaveforms.end(), &waveform, ::OpDetWaveformComp());
206  if ((insertionPoint != fWaveforms.end()) && (*insertionPoint == &waveform))
207  return false;
208  fWaveforms.insert(insertionPoint, &waveform);
209  addChannel(waveform.ChannelNumber());
210  return true;
211 } // icarus::trigger::OpticalTriggerGate::add()
212 
213 
214 //------------------------------------------------------------------------------
217 {
219  channels.reserve(waveforms.size());
221  waveforms.begin(), waveforms.end(), std::back_inserter(channels),
223  );
224  return channels;
225 } // icarus::trigger::OpticalTriggerGate::extractChannels()
226 
227 
228 //------------------------------------------------------------------------------
231 {
233 } // icarus::trigger::OpticalTriggerGate::waveformChannels()
234 
235 
236 //------------------------------------------------------------------------------
237 std::ostream& icarus::trigger::operator<<
238 (std::ostream& out, icarus::trigger::OpticalTriggerGate const& gate)
239 {
240  out << gate.gateLevels();
241  return out;
242 } // icarus::trigger::operator<< (icarus::trigger::OpticalTriggerGate)
243 
244 
245 //------------------------------------------------------------------------------
static GateData_t::ChannelList_t waveformChannels(Waveforms_t const &waveforms)
Returns the list of all unique channels (sorted) from the waveforms.
decltype(auto) channels() const
Returns the channels associated to the gate data.
std::vector< raw::OpDetWaveform const * > waveforms() const
ChannelList_t & normalizeChannels()
Removes duplicate channel IDs and sorts the remaining ones.
OpticalTriggerGate & Max(OpticalTriggerGate const &other)
Combines with a gate, keeping the maximum opening among the two.
static OpticalTriggerGate SymmetricCombination(Op &&op, OpticalTriggerGate const &a, OpticalTriggerGate const &b, TriggerGateTicks_t aDelay=TriggerGateTicks_t{0}, TriggerGateTicks_t bDelay=TriggerGateTicks_t{0})
Returns a gate combination of the openings of two other gates.
static constexpr Sample_t transform(Sample_t sample)
std::vector< ChannelID_t > ChannelList_t
Type of list of associated channels.
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.
bool add(raw::OpDetWaveform const &waveform)
Adds another waveform to the gate (unless it has already been added).
OpticalTriggerGate & Sum(OpticalTriggerGate const &other)
Combines with a gate, keeping the sum of openings of the two.
GateData_t & gateLevels()
Access to the underlying gate level data (mutable).
process_name gaushit a
void registerWaveforms(Waveforms_t const &moreWaveforms)
Registers the waveforms from the specified list.
This_t & addChannel(ChannelID_t const channel)
Associates the specified channel to this readout gate.
static Waveforms_t mergeWaveforms(Waveforms_t const &a, Waveforms_t const &b)
Registers the waveforms from the other gate into this one.
A trigger gate data object for optical detector electronics.
OpticalTriggerGate & Min(OpticalTriggerGate const &other)
Combines with a gate, keeping the minimum opening among the two.
util::quantities::tick::value_t TriggerGateTicks_t
Tick interval.
static GateData_t::ChannelList_t extractChannels(Waveforms_t const &waveforms)
Returns the list of all channels from the waveforms (duplicate allowed).
OpticalTriggerGate & Mul(OpticalTriggerGate const &other)
Combines with a gate, keeping the product of openings of the two.
std::vector< raw::OpDetWaveform const * > Waveforms_t
Internal list of registered waveforms.
Logical multi-level gate associated to one or more waveforms.
std::vector< raw::OpDetWaveform const * > fWaveforms
List of waveforms involved in this channel.
friend std::ostream & operator(std::ostream &, triggergatedata_t const &)