All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TriggerGateBuilder.cxx
Go to the documentation of this file.
1 /**
2  * @file icaruscode/PMT/Trigger/Algorithms/TriggerGateBuilder.cxx
3  * @brief Algorithm to produce trigger gates out of optical readout waveforms.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date April 1, 2019
6  * @see `icaruscode/PMT/Trigger/Algorithms/TriggerGateBuilder.h`
7  *
8  */
9 
10 
11 // class header
17 
18 // LArSoft libraries
20 
21 // framework libraries
22 #include "messagefacility/MessageLogger/MessageLogger.h"
23 #include "cetlib_except/exception.h"
24 
25 // C/C++ standard libraries
26 #include <algorithm> // std::lower_bound(), std::transform()
27 #include <iterator> // std::back_inserter()
28 
29 
30 //------------------------------------------------------------------------------
31 namespace {
32 
33  //----------------------------------------------------------------------------
34  // comparison using the channel number (special comparison operator)
35  template <typename Comp = std::less<raw::Channel_t>>
36  struct ChannelComparison {
37 
38  using Comparer_t = Comp;
39 
40  Comparer_t comp;
41 
42  constexpr ChannelComparison(): comp() {}
43  constexpr ChannelComparison(Comparer_t comp): comp(comp) {}
44 
45  template <typename A, typename B>
46  constexpr bool operator() (A const& a, B const& b) const
47  { return comp(channelOf(a), channelOf(b)); }
48 
49  static constexpr raw::Channel_t channelOf(raw::Channel_t channel)
50  { return channel; }
51  static raw::Channel_t channelOf(raw::OpDetWaveform const& waveform)
52  { return waveform.ChannelNumber(); }
53  static raw::Channel_t channelOf(sbn::OpDetWaveformMeta const& waveformMeta)
54  { return waveformMeta.ChannelNumber(); }
55  static raw::Channel_t channelOf
57  { return gate.channel(); }
58  template <typename Gate, typename OpDetInfo>
59  static raw::Channel_t channelOf
61  { return channelOf(gate.gate()); }
62 
63  }; // struct ChannelComparison
64 
65 
66  //----------------------------------------------------------------------------
67  /*
68  * Currently util::Quantity objects have serious issues with FHiCL validation,
69  * so we are not reading them directly as such. This pulls in a number of
70  * workarounds for:
71  * * every `Quantity` parameter: its FHiCL parameter must be declared as
72  * the base type `Quantity::value_t`
73  * * every optional parameter must be then read indirectly since a reference
74  * to the exact type of the parameter is required in such reading
75  * * for sequences, direct vector assignment
76  * (`vector<Quantity> = vector<Quantity::value_t>`) won't work, and since
77  * `Sequence::operator()` returns a temporary, this needs to be wraped too
78  */
79  template <typename SeqValueType>
80  struct FHiCLsequenceWrapper {
81  SeqValueType seqValue;
82 
83  FHiCLsequenceWrapper(SeqValueType seqValue): seqValue(seqValue) {}
84 
85  template <typename T>
86  operator std::vector<T>() const
87  { return { seqValue.cbegin(), seqValue.cend() }; }
88 
89  }; // FHiCLsequenceWrapper
90 
91 
92  //----------------------------------------------------------------------------
93 
94 } // local namespace
95 
96 
97 //------------------------------------------------------------------------------
98 //--- icarus::trigger::TriggerGateBuilder::TriggerGates
99 //------------------------------------------------------------------------------
100 auto icarus::trigger::TriggerGateBuilder::TriggerGates::gateFor
101  (raw::OpDetWaveform const& waveform) -> triggergate_t&
102 {
103  // keeping the gates sorted by channel
104  raw::Channel_t const channel = waveform.ChannelNumber();
105  auto iGate = std::lower_bound
106  (fGates.begin(), fGates.end(), waveform, ::ChannelComparison<>());
107  if (iGate != fGates.end()) { // found, it's there already
108  MF_LOG_TRACE(details::TriggerGateDebugLog)
109  << "Appending waveform to trigger gate (thr=" << threshold()
110  << ") of channel " << channel;
111  iGate->tracking().add(&waveform);
112  return *iGate;
113  }
114  // add the new gate in channel order
115  MF_LOG_TRACE(details::TriggerGateDebugLog)
116  << "Creating a new trigger gate (thr=" << threshold()
117  << ") for channel " << channel;
118  // wrap a new trigger gate on `channel` in a also new tracking gate
119  iGate = fGates.emplace(iGate, triggergate_t::TriggerGate_t{ channel });
120 // iGate->addChannel(channel);
121  iGate->tracking().add(&waveform);
122  return *iGate;
123 } // icarus::trigger::TriggerGateBuilder::TriggerGates::gateFor()
124 
125 
126 //------------------------------------------------------------------------------
127 //--- icarus::trigger::TriggerGateBuilder
128 //------------------------------------------------------------------------------
130  : fChannelThresholds(FHiCLsequenceWrapper(config.ChannelThresholds()))
131 {
132  std::sort(fChannelThresholds.begin(), fChannelThresholds.end());
133 
134  if (!fChannelThresholds.empty()
135  && (fChannelThresholds.front() < ADCCounts_t{0})
136  ) {
137  throw cet::exception("TriggerGateBuilder")
138  << "icarus::trigger::TriggerGateBuilder does not support"
139  " negative thresholds (like "
140  << fChannelThresholds.front() << ").\n";
141  }
142 
143 } // icarus::trigger::TriggerGateBuilder::TriggerGateBuilder()
144 
145 
146 //------------------------------------------------------------------------------
148  (detinfo::DetectorTimings const& timings)
149 {
150  fDetTimings = timings;
151 } // icarus::trigger::TriggerGateBuilder::setup()
152 
153 
154 //------------------------------------------------------------------------------
156  (microsecond time) const -> optical_tick
157 {
159  return detTimings().toTick<optical_tick>(optical_time{ time });
160 }
161 
162 
163 //------------------------------------------------------------------------------
166 {
167  return timeToOpticalTick(microsecond{ time });
168 } // icarus::trigger::TriggerGateBuilder::timeStampToOpticalTick()
169 
170 
171 //------------------------------------------------------------------------------
173  -> std::vector<TriggerGates>
174 {
175 
176  // create an empty TriggerGates object for each threshold;
177  // thresholds are kept relative
178  std::vector<TriggerGates> allGates;
179  allGates.reserve(nChannelThresholds());
180  for (auto threshold: channelThresholds()) allGates.emplace_back(threshold);
181  return allGates;
182 
183 } // icarus::trigger::TriggerGateBuilder::prepareAllGates()
184 
185 
186 //------------------------------------------------------------------------------
virtual void setup(detinfo::DetectorTimings const &timings)
Algorithm setup.
ChannelID_t channel() const
Returns the channel associated to the gate data.
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
A wrapper to trigger gate objects tracking the input of operations.
Algorithm to produce trigger gates out of optical readout waveforms.
microsecond_as<> microsecond
Type of time stored in microseconds, in double precision.
Definition: spacetime.h:119
Derivative information from raw::OpDetWaveform data.
double TimeStamp_t
us since 1970, based on TimeService
Derivative information from raw::OpDetWaveform data.
optical_tick timeStampToOpticalTick(raw::TimeStamp_t time) const
Converts a timestamp from raw::OpDetWaveform into optical ticks.
process_name gaushit a
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Container of logical gates for all triggering channels for a threshold.
Logical multi-level gate associated to one or more readout channels.
raw::Channel_t ChannelNumber() const
Returns the channnel ID of the PMT waveform.
constexpr auto TriggerGateDebugLog
A value measured in the specified unit.
Definition: quantities.h:566
A trigger gate data object for optical detector electronics.
timescale_traits< OpticalTimeCategory >::time_point_t optical_time
A point in time on the optical detector electronics time scale.
Operations on waveform samples.
std::vector< TriggerGates > prepareAllGates() const
TriggerGateBuilder(Config const &config)
Constructor: sets the configuration.
A wrapper to trigger gate objects tracking the contributions.
timescale_traits< OpticalTimeCategory >::tick_t optical_tick
std::vector< ADCCounts_t > fChannelThresholds
All single channel thresholds, sorted in increasing order.
TriggerGate_t const & gate() const &
Returns the enclosed gate.
optical_tick timeToOpticalTick(microsecond time) const
Converts a time [s] into optical ticks.
A class exposing an upgraded interface of detinfo::DetectorClocksData.
fDetProps &fDetProps fDetProps &fDetProps detTimings
float A
Definition: dedx.py:137