LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DumpTracks_module.cc
Go to the documentation of this file.
1 
8 // LArSoft includes
13 
14 // support libraries
15 #include "fhiclcpp/types/Atom.h"
16 #include "fhiclcpp/types/Comment.h"
17 #include "fhiclcpp/types/Name.h"
18 #include "fhiclcpp/types/Table.h"
20 
21 // art libraries
28 
29 // C//C++ standard libraries
30 #include <algorithm> // std::max(), std::sort(), std::transform()
31 #include <functional> // std::mem_fn()
32 #include <iomanip> // std::setw()
33 #include <iterator> // std::back_inserter()
34 #include <memory> // std::unique_ptr()
35 #include <sstream>
36 #include <string>
37 
38 namespace {
39 
41  template <typename T>
42  size_t StringLength(const T& value)
43  {
44  std::ostringstream sstr;
45  sstr << value;
46  return sstr.str().length();
47  } // StringLength()
48 
57  template <typename STREAM, typename CONT>
58  void PrintCompactIndexTable(STREAM& log,
59  const CONT& Indices,
60  unsigned int IndicesPerLine,
61  std::string IndentStr = "")
62  {
63  unsigned int Padding = StringLength(Indices.back());
64 
65  typename CONT::const_iterator iIndex = Indices.begin(), iend = Indices.end();
66  size_t RangeStart = *iIndex, RangeStop = RangeStart;
67  std::ostringstream output_line;
68  size_t nItemsInLine = 0;
69  while (++iIndex != iend) {
70 
71  if (*iIndex == RangeStop + 1) { ++RangeStop; }
72  else {
73  // the new item does not belong to the current range:
74  // - print the current range
75  if (nItemsInLine) output_line << " ";
76  if (RangeStart == RangeStop) {
77  output_line << std::setw(Padding) << RangeStart;
78  ++nItemsInLine;
79  }
80  else {
81  char fill = (RangeStart + 1 == RangeStop) ? ' ' : '-';
82  output_line << std::setw(Padding) << RangeStart << fill << fill << std::setw(Padding)
83  << std::setfill(fill) << RangeStop << std::setfill(' ');
84  nItemsInLine += 2;
85  }
86  // - start a new one
87  RangeStart = RangeStop = *iIndex;
88  } // if ... else
89 
90  // if we have enough stuff in the buffer, let's print it
91  if (nItemsInLine >= IndicesPerLine) {
92  nItemsInLine = 0;
93  log << IndentStr << output_line.str() << "\n";
94  output_line.str("");
95  }
96 
97  } // while
98 
99  // print what we have accumulated so far of the last line
100  log << IndentStr << output_line.str();
101  // print the last range (or single element)
102  if (nItemsInLine) log << " ";
103  if (RangeStart == RangeStop)
104  log << std::setw(Padding) << RangeStart;
105  else {
106  char fill = (RangeStart + 1 == RangeStop) ? ' ' : '-';
107  log << std::setw(Padding) << RangeStart << fill << fill << std::setw(Padding)
108  << std::setfill(fill) << RangeStop << std::setfill(' ');
109  }
110  log << std::endl;
111  } // PrintCompactIndexTable()
112 
124  template <typename STREAM, typename CONT, typename GETINDEX>
125  void PrintCompactIndexTable(STREAM& log,
126  const CONT& Objects,
127  unsigned int IndicesPerLine,
128  GETINDEX IndexExtractor,
129  std::string IndentStr)
130  {
131  if ((IndicesPerLine == 0) || Objects.empty()) return;
132 
133  std::vector<size_t> Indices;
134  Indices.reserve(Objects.size());
135  std::transform(Objects.begin(), Objects.end(), std::back_inserter(Indices), IndexExtractor);
136  std::sort(Indices.begin(), Indices.end());
137  PrintCompactIndexTable(log, Indices, IndicesPerLine, IndentStr);
138 
139  } // PrintCompactIndexTable()
140 
152  template <typename STREAM, typename T>
153  inline void PrintAssociatedIndexTable(STREAM& log,
154  const std::vector<art::Ptr<T>>& Objects,
155  unsigned int IndicesPerLine,
156  std::string IndentStr = "")
157  {
158  PrintCompactIndexTable(log, Objects, IndicesPerLine, std::mem_fn(&art::Ptr<T>::key), IndentStr);
159  } // PrintAssociatedIndexTable()
160 
172  template <typename STREAM, typename T>
173  inline void PrintAssociatedIDTable(STREAM& log,
174  const std::vector<art::Ptr<T>>& Objects,
175  unsigned int IndicesPerLine,
176  std::string IndentStr = "")
177  {
178  PrintCompactIndexTable(
179  log, Objects, IndicesPerLine, [](const art::Ptr<T>& ptr) { return ptr->ID(); }, IndentStr);
180  } // PrintAssociatedIDTable()
181 
182 } // local namespace
183 
184 namespace recob {
185 
215  class DumpTracks : public art::EDAnalyzer {
216  public:
218  struct Config {
220  using Name = fhicl::Name;
221 
223  Comment("input tag for the tracks to be dumped")};
225  Name("OutputCategory"),
226  Comment("name of the category used for message facility output"),
227  "DumpTracks"};
229  Comment("number of points along the trajectory printed"),
230  10U};
232  Name("SpacePointAssociations"),
233  Comment("prints the number of space points associated to the track"),
234  true};
236  Name("PrintSpacePoints"),
237  Comment("prints the index of all space points associated to the track"),
238  false};
240  Name("HitAssociations"),
241  Comment("prints the number of hits associated to the track"),
242  true};
244  Comment("prints the index of all hits associated to the track"),
245  false};
247  Name("ParticleAssociations"),
248  Comment("prints the number of PF particles associated to the track"),
249  true};
250 
251  }; // Config
252 
254 
256  explicit DumpTracks(Parameters const& config);
257 
259  void analyze(const art::Event& evt);
260 
261  private:
263  std::string fOutputCategory;
264  unsigned int fPrintWayPoints;
265 
266  bool fPrintNHits;
269  bool fPrintHits;
272 
274  void DumpTrack(unsigned int iTrack, recob::Track const& track) const;
275 
276  }; // class DumpTracks
277 
278 } // namespace recob
279 
280 //------------------------------------------------------------------------------
281 
282 namespace recob {
283 
284  //-------------------------------------------------
286  : EDAnalyzer(config)
287  , fTrackModuleLabel(config().TrackModuleLabel())
288  , fOutputCategory(config().OutputCategory())
289  , fPrintWayPoints(config().WayPoints())
290  , fPrintNHits(config().HitAssociations())
293  , fPrintHits(config().PrintHits())
294  , fPrintSpacePoints(config().PrintSpacePoints())
296  {}
297 
298  //-------------------------------------------------
300  {
301 
302  // fetch the data to be dumped on screen
303  auto Tracks = evt.getValidHandle<std::vector<recob::Track>>(fTrackModuleLabel);
304 
305  mf::LogInfo(fOutputCategory) << "The event contains " << Tracks->size() << " '"
306  << fTrackModuleLabel.encode() << "'tracks";
307 
308  std::unique_ptr<art::FindManyP<recob::Hit>> pHits(
309  fPrintNHits ? new art::FindManyP<recob::Hit>(Tracks, evt, fTrackModuleLabel) : nullptr);
310  if (pHits && !pHits->isValid()) {
312  << "No hit associated with '" << fTrackModuleLabel.encode() << "' tracks.\n";
313  }
314 
315  std::unique_ptr<art::FindManyP<recob::SpacePoint>> pSpacePoints(
317  nullptr);
318  if (pSpacePoints && !pSpacePoints->isValid()) {
320  << "No space point associated with '" << fTrackModuleLabel.encode() << "' tracks.\n";
321  }
322 
323  std::unique_ptr<art::FindManyP<recob::PFParticle>> pPFParticles(
325  nullptr);
326  if (pPFParticles && !pPFParticles->isValid()) {
328  << "No particle-flow particle associated with '" << fTrackModuleLabel.encode()
329  << "' tracks.\n";
330  }
331 
332  for (unsigned int iTrack = 0; iTrack < Tracks->size(); ++iTrack) {
333  const recob::Track& track = Tracks->at(iTrack);
334 
335  // print track information
336  DumpTrack(iTrack, track);
337 
339  if (pHits || pSpacePoints || pPFParticles) {
340  log << "\n associated with:";
341  if (pHits) log << " " << pHits->at(iTrack).size() << " hits;";
342  if (pSpacePoints) log << " " << pSpacePoints->at(iTrack).size() << " space points;";
343  if (pPFParticles) log << " " << pPFParticles->at(iTrack).size() << " PF particles;";
344  } // if we have any association
345 
346  if (pHits && fPrintHits) {
347  const auto& Hits = pHits->at(iTrack);
348  log << "\n hit indices (" << Hits.size() << "):\n";
349  PrintAssociatedIndexTable(log, Hits, 10 /* 10 hits per line */, " ");
350  } // if print individual hits
351 
352  if (pSpacePoints && fPrintSpacePoints) {
353  const auto& SpacePoints = pSpacePoints->at(iTrack);
354  log << "\n space point IDs (" << SpacePoints.size() << "):\n";
355  PrintAssociatedIDTable(log, SpacePoints, 10 /* 10 hits per line */, " ");
356  } // if print individual space points
357 
358  if (pPFParticles && fPrintParticles) {
359  const auto& PFParticles = pPFParticles->at(iTrack);
360  log << "\n particle indices (" << PFParticles.size() << "):\n";
361  // currently a particle has no ID
362  PrintAssociatedIndexTable(log, PFParticles, 10 /* 10 hits per line */, " ");
363  } // if print individual particles
364  } // for tracks
365  } // DumpTracks::analyze()
366 
367  //---------------------------------------------------------------------------
368  void DumpTracks::DumpTrack(unsigned int iTrack, recob::Track const& track) const
369  {
370  // print a header for the track
371  const unsigned int nPoints = track.NumberTrajectoryPoints();
373  log << "Track #" << iTrack << " ID: " << track.ID() << std::fixed << std::setprecision(3)
374  << " theta: " << track.Theta() << " rad, phi: " << track.Phi()
375  << " rad, length: " << track.Length() << " cm"
376  << "\n start at: ( " << track.Vertex().X() << " ; " << track.Vertex().Y() << " ; "
377  << track.Vertex().Z() << " ), direction: ( " << track.VertexDirection().X() << " ; "
378  << track.VertexDirection().Y() << " ; " << track.VertexDirection().Z() << " )"
379  << "\n end at: ( " << track.End().X() << " ; " << track.End().Y() << " ; "
380  << track.End().Z() << " ), direction: ( " << track.EndDirection().X() << " ; "
381  << track.EndDirection().Y() << " ; " << track.EndDirection().Z() << " )"
382  << "\n with " << nPoints << " trajectory points";
383 
384  if (fPrintWayPoints > 0) {
385  // print up to 10 (actually, 8 or 9) way points
386  log << "\n passes through:";
387  unsigned int skip = std::max(nPoints / fPrintWayPoints, 1U);
388  unsigned int iPoint = 0;
389  while ((iPoint += skip) < nPoints) {
390  const auto& point = track.LocationAtPoint(iPoint);
391  log << "\n [#" << iPoint << "] (" << point.X() << ", " << point.Y() << ", " << point.Z()
392  << ")";
393  } // while (iPoint)
394  } // if print way points
395  } // DumpTracks::DumpTrack()
396 
397  //---------------------------------------------------------------------------
399 
400 } // namespace recob
void DumpTrack(unsigned int iTrack, recob::Track const &track) const
Dumps information about the specified track.
fhicl::Atom< unsigned int > WayPoints
bool fPrintNSpacePoints
prints the number of associated space points
Reconstruction base classes.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
fhicl::Atom< std::string > OutputCategory
Declaration of signal hit object.
Point_t const & LocationAtPoint(size_t i) const
Access to track position at different points.
Definition: Track.h:160
fhicl::Atom< bool > PrintHits
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:136
Vector_t VertexDirection() const
Access to track direction at different points.
Definition: Track.h:166
intermediate_table::const_iterator const_iterator
void analyze(const art::Event &evt)
Does the printing.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
std::string encode() const
Definition: InputTag.cc:97
fhicl::Atom< bool > ParticleAssociations
Configuration object.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
double Phi() const
Access to spherical or geographical angles at vertex or at any point.
Definition: Track.h:218
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:207
art::InputTag fTrackModuleLabel
name of module that produced the tracks
fhicl::Atom< bool > PrintSpacePoints
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
bool fPrintNHits
prints the number of associated hits
double Theta() const
Access to spherical or geographical angles at vertex or at any point.
Definition: Track.h:216
fhicl::Atom< bool > SpacePointAssociations
fhicl::Atom< bool > HitAssociations
Point_t const & Vertex() const
Access to track position at different points.
Definition: Track.h:158
Provides recob::Track data product.
fhicl::Atom< art::InputTag > TrackModuleLabel
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
double value
Definition: spectrum.C:18
size_type size() const
Definition: PtrVector.h:302
bool fPrintHits
prints the index of associated hits
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
art::PtrVector< recob::Hit > Hits
int ID() const
Definition: Track.h:244
Prints the content of all the tracks on screen.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
DumpTracks(Parameters const &config)
Default constructor.
Vector_t EndDirection() const
Access to track direction at different points.
Definition: Track.h:167
bool fPrintNParticles
prints the number of associated PFParticles
std::string fOutputCategory
category for LogInfo output
Point_t const & End() const
Access to track position at different points.
Definition: Track.h:159
TCEvent evt
Definition: DataStructs.cxx:8
bool fPrintParticles
prints the index of associated PFParticles
Float_t track
Definition: plot.C:35
bool fPrintSpacePoints
prints the index of associated space points
unsigned int fPrintWayPoints
number of printed way points
Definition: fwd.h:26
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49