All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DumpWires_module.cc
Go to the documentation of this file.
1 /**
2  * @file DumpWires_module.cc
3  * @brief Dumps on screen the content of the wires
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date July 31st, 2014
6  */
7 
8 // LArSoft includes
9 #include "lardataalg/Utilities/StatCollector.h" // lar::util::MinMaxCollector<>
12 
13 // art libraries
14 #include "art/Framework/Core/EDAnalyzer.h"
15 #include "art/Framework/Core/ModuleMacros.h"
16 #include "art/Framework/Principal/Event.h"
17 #include "art/Framework/Principal/Handle.h"
18 #include "canvas/Utilities/InputTag.h"
19 
20 // support libraries
21 #include "fhiclcpp/types/Atom.h"
22 #include "fhiclcpp/types/Name.h"
23 #include "fhiclcpp/types/Comment.h"
24 #include "messagefacility/MessageLogger/MessageLogger.h"
25 
26 // C//C++ standard libraries
27 #include <string>
28 #include <ios> // std::fixed
29 #include <iomanip> // std::setprecision(), std::setw()
30 
31 
32 namespace {
33 
34  // Copied from geo::PlaneGeo, local so far
35  std::string ViewName(geo::View_t view) {
36  switch (view) {
37  case geo::kU: return "U";
38  case geo::kV: return "V";
39  case geo::kZ: return "Z";
40  // case geo::kY: return "Y";
41  // case geo::kX: return "X";
42  case geo::k3D: return "3D";
43  case geo::kUnknown: return "?";
44  default:
45  return "<UNSUPPORTED (" + std::to_string((int) view) + ")>";
46  } // switch
47  } // ViewName()
48 
49 } // local namespace
50 
51 
52 
53 namespace caldata {
54 
55  /**
56  * @brief Prints the content of all the wires on screen.
57  *
58  * This analyser prints the content of all the wires into the
59  * `LogVerbatim` stream.
60  *
61  * Configuration parameters
62  * =========================
63  *
64  * - *CalWireModuleLabel* (string, default: `"caldata"`): label of the
65  * producer used to create the `recob::Wire` collection to be dumped
66  * - *OutputCategory* (string, default: `"DumpWires"`): the category used
67  * for the output (useful for filtering)
68  * - *DigitsPerLine* (integer, default: `20`): the dump of digits and ticks
69  * will put this many of them for each line; `0` suppresses digit printout
70  */
71  class DumpWires : public art::EDAnalyzer {
72  public:
73 
74  struct Config {
75  using Name = fhicl::Name;
76  using Comment = fhicl::Comment;
77 
78  fhicl::Atom<art::InputTag> CalWireModuleLabel{
79  Name("CalWireModuleLabel"),
80  Comment("tag of producer used to create the recob::Wire collection"),
81  "caldata" /* default */
82  };
83 
84  fhicl::Atom<std::string> OutputCategory{
85  Name("OutputCategory"),
86  Comment("the messagefacility category used for the output"),
87  "DumpWires" /* default */
88  };
89 
90  fhicl::Atom<unsigned int> DigitsPerLine {
91  Name("DigitsPerLine"),
92  Comment("number of digits printed per line (0: don't print digits)"),
93  20 /* default */
94  };
95 
96  }; // Config
97 
98  using Parameters = art::EDAnalyzer::Table<Config>;
99 
100 
101  /// Constructor.
102  explicit DumpWires(Parameters const& config);
103 
104  /// Does the printing.
105  virtual void analyze (art::Event const& evt) override;
106 
107  private:
108 
109  art::InputTag fCalWireModuleLabel; ///< Input tag for wires.
110  std::string fOutputCategory; ///< Category for `LogVerbatim` output.
111  unsigned int fDigitsPerLine; ///< Ticks/digits per line in the output.
112 
113  /// Dumps a single `recob:Wire` to the specified output stream.
114  template <typename Stream>
115  void PrintWire(
116  Stream&& out, recob::Wire const& wire,
117  std::string indent = " ", std::string firstIndent = " "
118  ) const;
119 
120  }; // class DumpWires
121 
122 } // namespace caldata
123 
124 
125 //------------------------------------------------------------------------------
126 //--- Implementation
127 //------------------------------------------------------------------------------
129  : EDAnalyzer (config)
130  , fCalWireModuleLabel(config().CalWireModuleLabel())
131  , fOutputCategory (config().OutputCategory())
132  , fDigitsPerLine (config().DigitsPerLine())
133  {}
134 
135 
136 //------------------------------------------------------------------------------
137 void caldata::DumpWires::analyze(art::Event const& evt) {
138 
139  auto const& Wires
140  = *(evt.getValidHandle<std::vector<recob::Wire>>(fCalWireModuleLabel));
141 
142  mf::LogVerbatim(fOutputCategory) << "Event " << evt.id()
143  << " contains " << Wires.size() << " '" << fCalWireModuleLabel.encode()
144  << "' wires";
145 
146  for (recob::Wire const& wire: Wires) {
147 
148  PrintWire(mf::LogVerbatim(fOutputCategory), wire);
149 
150  } // for wire
151 
152 } // caldata::DumpWires::analyze()
153 
154 
155 //------------------------------------------------------------------------------
156 template <typename Stream>
158  Stream&& out, recob::Wire const& wire,
159  std::string indent /* = " " */, std::string firstIndent /* = " " */
160 ) const {
161 
162  using RegionsOfInterest_t = recob::Wire::RegionsOfInterest_t;
163 
164  RegionsOfInterest_t const & RoIs = wire.SignalROI();
165 
166  //
167  // print a header for the wire
168  //
169  out << firstIndent << "channel #" << wire.Channel() << " on view "
170  << ViewName(wire.View()) << "; " << wire.NSignal() << " time ticks";
171  if (wire.NSignal() != RoIs.size())
172  out << " [!!! EXPECTED " << RoIs.size() << "]";
173  if (RoIs.n_ranges() == 0) {
174  out << " with nothing in them";
175  return;
176  }
177  out << " with " << RoIs.n_ranges() << " regions of interest:";
178 
179  //
180  // print the list of regions of interest
181  //
182  for (RegionsOfInterest_t::datarange_t const& RoI: RoIs.get_ranges()) {
183  out << "\n" << indent
184  << " from " << RoI.offset << " for " << RoI.size() << " ticks";
185  } // for
186 
187  //
188  // print the content of the wire
189  //
190  if (fDigitsPerLine > 0) {
191 
192  std::vector<RegionsOfInterest_t::value_type> DigitBuffer(fDigitsPerLine),
193  LastBuffer;
194 
195  unsigned int repeat_count = 0; // additional lines like the last one
196  unsigned int index = 0;
198  out << "\n" << indent
199  << " content of the wire (" << fDigitsPerLine << " ticks per line):";
200  auto iTick = RoIs.cbegin(), tend = RoIs.cend();
201  while (iTick != tend) {
202  // the next line will show at most fDigitsPerLine ticks
203  unsigned int line_size
204  = std::min(fDigitsPerLine, (unsigned int) RoIs.size() - index);
205  if (line_size == 0) break; // no more ticks
206 
207  // fill the new buffer (iTick will move forward)
208  DigitBuffer.resize(line_size);
209  auto iBuf = DigitBuffer.begin(), bend = DigitBuffer.end();
210  while ((iBuf != bend) && (iTick != tend))
211  Extrema.add(*(iBuf++) = *(iTick++));
212  index += line_size;
213 
214  // if the new buffer is the same as the old one, just mark it
215  if (DigitBuffer == LastBuffer) {
216  repeat_count += 1;
217  continue;
218  }
219 
220  // if there are previous repeats, write that on screen
221  // before the new, different line
222  if (repeat_count > 0) {
223  out << "\n" << indent
224  << " [ ... repeated " << repeat_count << " more times, "
225  << (repeat_count * LastBuffer.size()) << " ticks ]";
226  repeat_count = 0;
227  }
228 
229  // dump the new line of ticks
230  out << "\n" << indent
231  << " " << std::fixed << std::setprecision(3);
232  for (auto digit: DigitBuffer) out << std::setw(8) << digit;
233 
234  // quick way to assign DigitBuffer to LastBuffer
235  // (we don't care we lose the former)
236  std::swap(LastBuffer, DigitBuffer);
237 
238  } // while
239  if (repeat_count > 0) {
240  out << "\n" << indent
241  << " [ ... repeated " << repeat_count << " more times to the end ]";
242  }
243  if (Extrema.min() < Extrema.max()) {
244  out << "\n" << indent
245  << " range of " << index
246  << " samples: [" << Extrema.min() << ";" << Extrema.max() << "]";
247  }
248  } // if dumping the ticks
249 
250 } // caldata::DumpWires::PrintWire()
251 
252 //------------------------------------------------------------------------------
253 DEFINE_ART_MODULE(caldata::DumpWires)
254 
255 //------------------------------------------------------------------------------
Data_t max() const
Returns the accumulated maximum, or a very small number if no values.
This_t & add(Data_t value)
Include a single value in the statistics.
Prints the content of all the wires on screen.
fhicl::Atom< std::string > OutputCategory
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Planes which measure V.
Definition: geo_types.h:130
Unknown view.
Definition: geo_types.h:136
art::InputTag fCalWireModuleLabel
Input tag for wires.
Planes which measure Z direction.
Definition: geo_types.h:132
lar::sparse_vector< float > RegionsOfInterest_t
a region of interest is a pair (TDC offset, readings)
Definition: Wire.h:121
Classes gathering simple statistics.
3-dimensional objects, potentially hits, clusters, prongs, etc.
Definition: geo_types.h:135
geo::View_t View() const
Returns the view the channel belongs to.
Definition: Wire.h:230
Keeps track of the minimum and maximum value we observed.
Planes which measure U.
Definition: geo_types.h:129
Data_t min() const
Returns the accumulated minimum, or a very large number if no values.
fhicl::Atom< art::InputTag > CalWireModuleLabel
std::string fOutputCategory
Category for LogVerbatim output.
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
Definition: Wire.h:231
void PrintWire(Stream &&out, recob::Wire const &wire, std::string indent=" ", std::string firstIndent=" ") const
Dumps a single recob:Wire to the specified output stream.
unsigned int fDigitsPerLine
Ticks/digits per line in the output.
const RegionsOfInterest_t & SignalROI() const
Returns the list of regions of interest.
Definition: Wire.h:228
BEGIN_PROLOG vertical distance to the surface Name
Definition of data types for geometry description.
DumpWires(Parameters const &config)
Constructor.
std::string to_string(WindowPattern const &pattern)
Class holding the regions of interest of signal from a channel.
Definition: Wire.h:118
virtual void analyze(art::Event const &evt) override
Does the printing.
Declaration of basic channel signal object.
TCEvent evt
Definition: DataStructs.cxx:8
fhicl::Atom< unsigned int > DigitsPerLine
process_name can override from command line with o or output caldata
Definition: pid.fcl:40
art::EDAnalyzer::Table< Config > Parameters
bnb BNB Stream
std::size_t NSignal() const
Returns the number of time ticks, or samples, in the channel.
Definition: Wire.h:229