17 #include "messagefacility/MessageLogger/MessageLogger.h"
34 template <
typename BIter,
typename EIter>
35 auto median(BIter
begin, EIter
end) {
37 using value_type =
typename BIter::value_type;
39 std::vector<value_type> data{
begin, end };
40 assert(!data.empty());
42 auto const middle = data.begin() + data.size() / 2;
43 std::nth_element(data.begin(), middle, data.end());
56 template <
typename Iter>
57 Iter findOutOfBoundary(
59 typename Iter::value_type lower,
typename Iter::value_type upper,
60 unsigned int maxLower,
unsigned int maxUpper
62 assert(lower <= upper);
63 assert(maxLower > 0U);
64 assert(maxUpper > 0U);
66 unsigned int nAbove = 0U;
67 unsigned int nBelow = 0U;
68 for (
auto it = begin; it !=
end; ++it) {
71 if (++nAbove >= maxUpper)
return it - maxUpper + 1;
77 if (++nBelow >= maxLower)
return it - maxLower + 1;
92 struct waveformIntro {
100 std::ostream&
operator<< (std::ostream& out, waveformIntro wf) {
103 out <<
"waveform channel="
105 <<
" size=" << waveform.size();
107 else out <<
"<no waveform>";
119 auto opdet::SharedWaveformBaseline::operator()
120 (std::vector<raw::OpDetWaveform const*>
const& waveforms)
const
123 if (waveforms.empty())
return {};
128 std::vector<raw::ADC_Count_t> samples;
129 samples.reserve(fParams.nSample * waveforms.size());
130 std::vector<double> RMSs;
131 RMSs.reserve(waveforms.size());
135 mf::LogTrace{
fLogCategory } <<
"Now processing: " << waveformIntro(waveform);
137 if (waveform->size() < fParams.nSample) {
139 <<
": skipped because shorter than " << fParams.nSample
144 auto const begin = waveform->cbegin();
145 auto const end = std::next(begin, fParams.nSample);
148 for (
auto it = begin; it !=
end; ++it) stats.
add(*it);
149 RMSs.push_back(stats.
RMS());
151 std::copy(waveform->begin(), waveform->end(), back_inserter(samples));
154 double const medRMS = median(RMSs.cbegin(), RMSs.cend());
158 << waveforms.front()->ChannelNumber() <<
" from "
159 << fParams.nSample <<
" starting samples of " << waveforms.size()
160 <<
" waveforms: median=" << med <<
" ADC, median RMS of each waveform="
171 auto const sampleOutOfBoundary
172 = [
this, aboveThreshold, belowThreshold](
auto begin,
auto end)
174 return findOutOfBoundary(begin, end,
175 belowThreshold, aboveThreshold,
176 fParams.nExcessSamples, fParams.nExcessSamples);
180 unsigned int nUsedWaveforms = 0U;
183 auto const begin = waveform->cbegin();
184 auto const end = std::next(begin, fParams.nSample);
189 auto const firstExcess = sampleOutOfBoundary(begin, end);
190 if (firstExcess != end) {
194 << waveformIntro(waveform) <<
" has " << fParams.nExcessSamples
195 <<
" samples in a row out of [ " << belowThreshold <<
" ; "
196 << aboveThreshold <<
" ] ADC starting at sample #"
197 << (firstExcess -
begin) <<
":";
199 auto it = firstExcess; it != firstExcess + fParams.nExcessSamples; ++it
224 , (
unsigned int) stats.
N()
Classes gathering simple statistics.
Weight_t RMS() const
Returns the root mean square.
Weight_t Average() const
Returns the value average.
int N() const
Returns the number of entries added.
void add_unweighted(Iter begin, Iter end)
Adds entries from a sequence with weight 1.
auto end(FixedBins< T, C > const &) noexcept
auto begin(FixedBins< T, C > const &) noexcept
std::ostream & operator<<(std::ostream &out, lar::example::CheatTrack const &track)
void add(Data_t value, Weight_t weight=Weight_t(1.0))
Adds one entry with specified value and weight.