LArSoft  v06_85_00
Liquid Argon Software toolkit - http://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/Table.h"
24 #include "fhiclcpp/types/Name.h"
25 #include "fhiclcpp/types/Comment.h"
27 
28 // C//C++ standard libraries
29 #include <string>
30 #include <sstream>
31 #include <iomanip> // std::setw()
32 #include <algorithm> // std::min(), std::sort()
33 
34 
35 namespace recob {
36 
54  class DumpClusters : public art::EDAnalyzer {
55  public:
56 
58  struct Config {
60  using Name = fhicl::Name;
61 
63  Name("ClusterModuleLabel"),
64  Comment("input tag for the clusters to be dumped")
65  };
67  Name("OutputCategory"),
68  Comment("name of the category used for message facility output"),
69  "DumpClusters"
70  };
72  Name("HitsPerLine"),
73  Comment("number of hits per line (0 suppresses hit dumping)"),
74  20U
75  };
76 
77  }; // Config
78 
80 
82  explicit DumpClusters(Parameters const& config);
83 
85  void analyze (const art::Event& evt);
86 
87  private:
88 
90  std::string fOutputCategory;
91  unsigned int fHitsPerLine;
92 
93  }; // class DumpWires
94 
95 } // namespace recob
96 
97 
98 //------------------------------------------------------------------------------
99 namespace {
100 
102  template <typename T>
103  size_t StringLength(const T& value) {
104  std::ostringstream sstr;
105  sstr << value;
106  return sstr.str().length();
107  } // StringLength()
108 
109 } // local namespace
110 
111 namespace recob {
112 
113  //-------------------------------------------------
115  : EDAnalyzer (config)
117  , fOutputCategory (config().OutputCategory())
118  , fHitsPerLine (config().HitsPerLine())
119  {}
120 
121 
122  //-------------------------------------------------
124 
125  // fetch the data to be dumped on screen
126  art::InputTag ClusterInputTag(fClusterModuleLabel);
127 
128  auto Clusters
129  = evt.getValidHandle<std::vector<recob::Cluster>>(ClusterInputTag);
130 
131  // get cluster-hit associations
132  art::FindManyP<recob::Hit> HitAssn(Clusters, evt, ClusterInputTag);
133 
135  << "The event contains " << Clusters->size() << " '"
136  << ClusterInputTag.encode() << "' clusters";
137 
138  unsigned int iCluster = 0;
139  std::vector<size_t> HitBuffer(fHitsPerLine), LastBuffer;
140  for (const recob::Cluster& cluster: *Clusters) {
141  decltype(auto) ClusterHits = HitAssn.at(iCluster);
142 
143  // print a header for the cluster
145  << "Cluster #" << (iCluster++) << " from " << ClusterHits.size()
146  << " hits: " << cluster;
147 
148 
149  // print the hits of the cluster
150  if ((fHitsPerLine > 0) && !ClusterHits.empty()) {
151  std::vector<size_t> HitIndices;
152  for (art::Ptr<recob::Hit> pHit: ClusterHits)
153  HitIndices.push_back(pHit.key());
154  std::sort(HitIndices.begin(), HitIndices.end());
155 
156  unsigned int Padding = ::StringLength(HitIndices.back());
157 
158  mf::LogVerbatim(fOutputCategory) << " hit indices:";
159 
160  std::vector<size_t>::const_iterator iHit = HitIndices.begin(),
161  hend = HitIndices.end();
162  size_t RangeStart = *iHit, RangeStop = RangeStart;
163  std::ostringstream output_line;
164  size_t nItemsInLine = 0;
165  while (++iHit != hend) {
166 
167  if (*iHit == RangeStop + 1) {
168  ++RangeStop;
169  }
170  else {
171  // the new item does not belong to the current range:
172  // - print the current range
173  if (RangeStart == RangeStop) {
174  output_line << " " << std::setw(Padding) << RangeStart;
175  ++nItemsInLine;
176  }
177  else {
178  char fill = (RangeStart + 1 == RangeStop)? ' ': '-';
179  output_line << " " << std::setw(Padding) << RangeStart
180  << fill << fill
181  << std::setw(Padding) << std::setfill(fill) << RangeStop
182  << std::setfill(' ');
183  nItemsInLine += 2;
184  }
185  // - start a new one
186  RangeStart = RangeStop = *iHit;
187  } // if ... else
188 
189  // if we have enough stuff in the buffer, let's print it
190  if (nItemsInLine >= fHitsPerLine) {
191  nItemsInLine = 0;
192  mf::LogVerbatim(fOutputCategory) << " " << output_line.str();
193  output_line.str("");
194  }
195 
196  } // while
197 
199  line_out << " " << output_line.str();
200  if (RangeStart == RangeStop)
201  line_out << " " << std::setw(Padding) << RangeStart;
202  else {
203  char fill = (RangeStart + 1 == RangeStop)? ' ': '-';
204  line_out << " " << std::setw(Padding) << RangeStart
205  << fill << fill
206  << std::setw(Padding) << std::setfill(fill) << RangeStop;
207  }
208  } // if dumping the hits
209 
210  } // for clusters
211 
212  } // DumpClusters::analyze()
213 
215 
216 } // namespace recob
217 
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:71
Cluster finding and building.
unsigned int fHitsPerLine
hits per line in the output
fhicl::Atom< art::InputTag > ClusterModuleLabel
intermediate_table::const_iterator const_iterator
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
fhicl::Atom< unsigned int > HitsPerLine
std::string encode() const
Definition: InputTag.cc:36
art::InputTag fClusterModuleLabel
tag of the cluster data product
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
EDAnalyzer(Table< Config > const &config)
Definition: EDAnalyzer.h:100
Declaration of cluster object.
fhicl::Atom< std::string > OutputCategory
std::string value(boost::any const &)
void analyze(const art::Event &evt)
Does the printing.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
std::string fOutputCategory
category for LogInfo output
DumpClusters(Parameters const &config)
Default constructor.