LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DumpOpDetWaveforms_module.cc
Go to the documentation of this file.
1 
8 // LArSoft includes
13 
14 // art libraries
20 
21 // support libraries
22 #include "fhiclcpp/types/Atom.h"
23 #include "fhiclcpp/types/Comment.h"
24 #include "fhiclcpp/types/Name.h"
26 
27 // C//C++ standard libraries
28 #include <algorithm> // std::sort()
29 #include <string>
30 #include <vector>
31 
32 namespace detsim {
33 
59  public:
60  struct Config {
61 
62  using Name = fhicl::Name;
64 
66  Name("OpDetWaveformsTag"),
67  Comment("input tag of the raw::OpDetWaveform collection to be dumped")};
68 
70  Comment("name of the category used for the output"),
71  "DumpOpDetWaveforms"};
72 
74  Name("DigitsPerLine"),
75  Comment("the dump of ADC readings will put this many of them for each line"),
76  20U};
77 
79  Name("Pedestal"),
80  Comment("ADC readings are written relative to this number"),
81  0};
82 
84  Name("SortByChannelAndTime"),
85  Comment("waveforms are dumped in channel number order, and then timestamp"),
86  true};
87 
89  Name("TickLabel"),
90  Comment("write an index in front of each digit dump line; choose between:"
91  " \"tick\" (waveform tick number)"
92  ", \"timestamp\" (electronics clock time in microseconds)"
93  ", \"none\" (no tick label)"),
94  "tick"};
95 
96  }; // struct Config
97 
99 
100  explicit DumpOpDetWaveforms(Parameters const& config);
101 
103  void analyze(const art::Event& evt);
104 
105  private:
106  enum class sortMode {
107  DataProductOrder,
108  ChannelAndTime
109  }; // sortMode
110 
113  double tickDuration; // should this me `util::quantities::microsecond`?
114 
116  TimestampLabelMaker(double tickDuration) : tickDuration(tickDuration) {}
117 
119  virtual std::string label(raw::OpDetWaveform const& waveform,
120  unsigned int tick) const override
121  {
122  return std::to_string(waveform.TimeStamp() + tick * tickDuration);
123  }
124 
125  }; // struct TimestampLabelMaker
126 
128  std::string fOutputCategory;
129  unsigned int fDigitsPerLine;
132 
134  std::unique_ptr<dump::raw::OpDetWaveformDumper::TimeLabelMaker> fTimeLabel;
135 
137  static std::vector<std::vector<raw::OpDetWaveform const*>> groupByChannel(
138  std::vector<raw::OpDetWaveform> const& waveforms);
139 
141  static void sortByTimestamp(std::vector<raw::OpDetWaveform const*>& waveforms);
142 
143  }; // class DumpOpDetWaveforms
144 
145 } // namespace detsim
146 
147 namespace detsim {
148 
149  //-------------------------------------------------
151  : EDAnalyzer(config)
153  , fOutputCategory(config().OutputCategory())
154  , fDigitsPerLine(config().DigitsPerLine())
155  , fPedestal(config().Pedestal())
156  , fSortByChannelAndTime(config().SortByChannelAndTime() ? sortMode::ChannelAndTime :
157  sortMode::DataProductOrder)
158  {
159  std::string const tickLabelStr = config().TickLabel();
160  if (tickLabelStr == "none") {
161  fTimeLabel.reset(); // not very useful, but let's be explicit
162  }
163  else if (tickLabelStr == "tick") {
164  fTimeLabel = std::make_unique<dump::raw::OpDetWaveformDumper::TickLabelMaker>();
165  }
166  else if (tickLabelStr == "time") {
167  auto const clock_data =
169  fTimeLabel = std::make_unique<TimestampLabelMaker>(clock_data.OpticalClock().TickPeriod());
170  }
171  else {
173  << "Invalid choice '" << tickLabelStr << "' for time label.\n";
174  }
175 
176  } // DumpOpDetWaveforms::DumpOpDetWaveforms()
177 
178  //-------------------------------------------------
180  {
181 
182  // fetch the data to be dumped on screen
183  auto const& Waveforms = event.getProduct<std::vector<raw::OpDetWaveform>>(fOpDetWaveformsTag);
184 
186  dump.setTimeLabelMaker(fTimeLabel.get());
187 
188  mf::LogVerbatim(fOutputCategory) << "The event " << event.id() << " contains data for "
189  << Waveforms.size() << " optical detector channels";
190  if (fPedestal != 0) {
192  << "A pedestal of " << fPedestal << " counts will be subtracted from all ADC readings.";
193  } // if pedestal
194 
195  switch (fSortByChannelAndTime) {
197  dump.setIndent(" ");
198  for (raw::OpDetWaveform const& waveform : Waveforms) {
200  dump(log, waveform);
201  } // for waveforms on channel
202  } break; // sortMode::DataProductOrder
204  dump.setIndent(" ");
205 
206  auto groupedWaveforms = groupByChannel(Waveforms);
207  for (auto& channelWaveforms : groupedWaveforms) {
208  if (channelWaveforms.empty()) continue;
209 
210  sortByTimestamp(channelWaveforms);
211  auto const channel = channelWaveforms.front()->ChannelNumber();
212 
213  mf::LogVerbatim(fOutputCategory) << " optical detector channel #" << channel << " has "
214  << channelWaveforms.size() << " waveforms:";
215 
216  for (raw::OpDetWaveform const* pWaveform : channelWaveforms) {
218  dump(log, *pWaveform);
219  } // for waveforms on channel
220 
221  } // for all channels
222  } break; // sortMode::ChannelAndTime
223  } // switch (fSortMode)
224 
225  } // DumpOpDetWaveforms::analyze()
226 
227  //----------------------------------------------------------------------------
228  std::vector<std::vector<raw::OpDetWaveform const*>> DumpOpDetWaveforms::groupByChannel(
229  std::vector<raw::OpDetWaveform> const& waveforms)
230  {
231  std::vector<std::vector<raw::OpDetWaveform const*>> groups;
232  for (auto const& waveform : waveforms) {
233  auto const channel = waveform.ChannelNumber();
234  if (groups.size() <= channel) groups.resize(channel + 1);
235  groups[channel].push_back(&waveform);
236  } // for
237  return groups;
238  } // DumpOpDetWaveforms::groupByChannel()
239 
240  //----------------------------------------------------------------------------
241  void DumpOpDetWaveforms::sortByTimestamp(std::vector<raw::OpDetWaveform const*>& waveforms)
242  {
243 
244  struct ChannelSorter {
245 
246  static bool sort(raw::OpDetWaveform const& a, raw::OpDetWaveform const& b)
247  {
248  if (a.ChannelNumber() < b.ChannelNumber()) return true;
249  if (a.ChannelNumber() > b.ChannelNumber()) return false;
250 
251  return (a.TimeStamp() < b.TimeStamp());
252  }
253 
254  bool operator()(raw::OpDetWaveform const& a, raw::OpDetWaveform const& b) const
255  {
256  return sort(a, b);
257  }
258 
259  bool operator()(raw::OpDetWaveform const* a, raw::OpDetWaveform const* b) const
260  {
261  return sort(*a, *b);
262  }
263 
264  }; // struct ChannelSorter
265  std::sort(waveforms.begin(), waveforms.end(), ChannelSorter());
266 
267  } // DumpOpDetWaveforms::sortByTimestamp()
268 
269  //----------------------------------------------------------------------------
271 
272  //----------------------------------------------------------------------------
273 
274 } // namespace detsim
virtual std::string label(raw::OpDetWaveform const &waveform, unsigned int tick) const override
Returns the electronics time of the specified waveform tick.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
fhicl::Atom< raw::ADC_Count_t > Pedestal
Channel_t ChannelNumber() const
Definition: OpDetWaveform.h:52
TimeStamp_t TimeStamp() const
Definition: OpDetWaveform.h:53
Detector simulation of raw signals on wires.
DumpOpDetWaveforms(Parameters const &config)
std::string fOutputCategory
Category for mf::LogInfo output.
Prints the content of all optical detector waveforms on screen.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
std::unique_ptr< dump::raw::OpDetWaveformDumper::TimeLabelMaker > fTimeLabel
The object used to print tick labels.
pure virtual base interface for detector clocks
static std::vector< std::vector< raw::OpDetWaveform const * > > groupByChannel(std::vector< raw::OpDetWaveform > const &waveforms)
Returns pointers to all waveforms in a vector with channel as index.
Utilities to dump raw::OpDetWaveform objects on screen.
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
fhicl::Atom< art::InputTag > OpDetWaveformsTag
Base functor for printing time according to tick number.
Definition: OpDetWaveform.h:46
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:73
TimestampLabelMaker(double tickDuration)
Constructor: specify the duration of optical clock tick [µs].
raw::ADC_Count_t fPedestal
ADC pedestal (subtracted from readings).
Collection of utilities for dumping data on screen.
Definition: DumperBase.h:28
Unsorted: same order as the input data product.
Prints the content of optical detector waveforms on screen.
Definition: OpDetWaveform.h:43
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static void sortByTimestamp(std::vector< raw::OpDetWaveform const * > &waveforms)
Sorts all the waveforms in the vector by growing timestamp.
void analyze(const art::Event &evt)
Does the printing.
sortMode fSortByChannelAndTime
How to sort the waveforms in the dump.
art::InputTag fOpDetWaveformsTag
Input tag of data product to dump.
TCEvent evt
Definition: DataStructs.cxx:8
unsigned int fDigitsPerLine
ADC readings per line in the output.
Base functor for printing time according to tick number.
Sort by PMT channel number, then timestamp.
short ADC_Count_t
Definition: OpDetWaveform.h:20
Event finding and building.