LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DumpClusters_module.cc
Go to the documentation of this file.
1 
8 // LArSoft includes
11 
12 // art libraries
20 
21 // support libraries
22 #include "fhiclcpp/types/Atom.h"
23 #include "fhiclcpp/types/Comment.h"
24 #include "fhiclcpp/types/Name.h"
25 #include "fhiclcpp/types/Table.h"
27 
28 // C//C++ standard libraries
29 #include <algorithm> // std::min(), std::sort()
30 #include <iomanip> // std::setw()
31 #include <sstream>
32 #include <string>
33 
34 namespace recob {
35 
53  class DumpClusters : public art::EDAnalyzer {
54  public:
56  struct Config {
58  using Name = fhicl::Name;
59 
61  Name("ClusterModuleLabel"),
62  Comment("input tag for the clusters to be dumped")};
64  Name("OutputCategory"),
65  Comment("name of the category used for message facility output"),
66  "DumpClusters"};
68  Name("HitsPerLine"),
69  Comment("number of hits per line (0 suppresses hit dumping)"),
70  20U};
71 
72  }; // Config
73 
75 
77  explicit DumpClusters(Parameters const& config);
78 
80  void analyze(const art::Event& evt);
81 
82  private:
84  std::string fOutputCategory;
85  unsigned int fHitsPerLine;
86 
87  }; // class DumpWires
88 
89 } // namespace recob
90 
91 //------------------------------------------------------------------------------
92 namespace {
93 
95  template <typename T>
96  size_t StringLength(const T& value)
97  {
98  std::ostringstream sstr;
99  sstr << value;
100  return sstr.str().length();
101  } // StringLength()
102 
103 } // local namespace
104 
105 namespace recob {
106 
107  //-------------------------------------------------
109  : EDAnalyzer(config)
111  , fOutputCategory(config().OutputCategory())
112  , fHitsPerLine(config().HitsPerLine())
113  {}
114 
115  //-------------------------------------------------
117  {
118 
119  // fetch the data to be dumped on screen
120  art::InputTag ClusterInputTag(fClusterModuleLabel);
121 
122  auto Clusters = evt.getValidHandle<std::vector<recob::Cluster>>(ClusterInputTag);
123 
124  // get cluster-hit associations
125  art::FindManyP<recob::Hit> HitAssn(Clusters, evt, ClusterInputTag);
126 
127  mf::LogInfo(fOutputCategory) << "The event contains " << Clusters->size() << " '"
128  << ClusterInputTag.encode() << "' clusters";
129 
130  unsigned int iCluster = 0;
131  std::vector<size_t> HitBuffer(fHitsPerLine), LastBuffer;
132  for (const recob::Cluster& cluster : *Clusters) {
133  decltype(auto) ClusterHits = HitAssn.at(iCluster);
134 
135  // print a header for the cluster
137  << "Cluster #" << (iCluster++) << " from " << ClusterHits.size() << " hits: " << cluster;
138 
139  // print the hits of the cluster
140  if ((fHitsPerLine > 0) && !ClusterHits.empty()) {
141  std::vector<size_t> HitIndices;
142  for (art::Ptr<recob::Hit> pHit : ClusterHits)
143  HitIndices.push_back(pHit.key());
144  std::sort(HitIndices.begin(), HitIndices.end());
145 
146  unsigned int Padding = ::StringLength(HitIndices.back());
147 
148  mf::LogVerbatim(fOutputCategory) << " hit indices:";
149 
150  std::vector<size_t>::const_iterator iHit = HitIndices.begin(), hend = HitIndices.end();
151  size_t RangeStart = *iHit, RangeStop = RangeStart;
152  std::ostringstream output_line;
153  size_t nItemsInLine = 0;
154  while (++iHit != hend) {
155 
156  if (*iHit == RangeStop + 1) { ++RangeStop; }
157  else {
158  // the new item does not belong to the current range:
159  // - print the current range
160  if (RangeStart == RangeStop) {
161  output_line << " " << std::setw(Padding) << RangeStart;
162  ++nItemsInLine;
163  }
164  else {
165  char fill = (RangeStart + 1 == RangeStop) ? ' ' : '-';
166  output_line << " " << std::setw(Padding) << RangeStart << fill << fill
167  << std::setw(Padding) << std::setfill(fill) << RangeStop
168  << std::setfill(' ');
169  nItemsInLine += 2;
170  }
171  // - start a new one
172  RangeStart = RangeStop = *iHit;
173  } // if ... else
174 
175  // if we have enough stuff in the buffer, let's print it
176  if (nItemsInLine >= fHitsPerLine) {
177  nItemsInLine = 0;
178  mf::LogVerbatim(fOutputCategory) << " " << output_line.str();
179  output_line.str("");
180  }
181 
182  } // while
183 
185  line_out << " " << output_line.str();
186  if (RangeStart == RangeStop)
187  line_out << " " << std::setw(Padding) << RangeStart;
188  else {
189  char fill = (RangeStart + 1 == RangeStop) ? ' ' : '-';
190  line_out << " " << std::setw(Padding) << RangeStart << fill << fill << std::setw(Padding)
191  << std::setfill(fill) << RangeStop;
192  }
193  } // if dumping the hits
194 
195  } // for clusters
196 
197  } // DumpClusters::analyze()
198 
200 
201 } // namespace recob
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Reconstruction base classes.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Declaration of signal hit object.
Prints the content of all the clusters on screen.
Set of hits with a 2D structure.
Definition: Cluster.h:69
intermediate_table::const_iterator const_iterator
Cluster finding and building.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
unsigned int fHitsPerLine
hits per line in the output
std::string encode() const
Definition: InputTag.cc:97
fhicl::Atom< art::InputTag > ClusterModuleLabel
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
fhicl::Atom< unsigned int > HitsPerLine
art::InputTag fClusterModuleLabel
tag of the cluster data product
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
Declaration of cluster object.
double value
Definition: spectrum.C:18
fhicl::Atom< std::string > OutputCategory
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
void analyze(const art::Event &evt)
Does the printing.
TCEvent evt
Definition: DataStructs.cxx:8
std::string fOutputCategory
category for LogInfo output
DumpClusters(Parameters const &config)
Default constructor.