LArSoft  v06_85_00
Liquid Argon Software toolkit - http://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/Table.h"
17 #include "fhiclcpp/types/Name.h"
18 #include "fhiclcpp/types/Comment.h"
20 
21 // art libraries
28 
29 // C//C++ standard libraries
30 #include <string>
31 #include <sstream>
32 #include <iomanip> // std::setw()
33 #include <algorithm> // std::max(), std::sort(), std::transform()
34 #include <iterator> // std::back_inserter()
35 #include <functional> // std::mem_fn()
36 #include <memory> // std::unique_ptr()
37 
38 
39 namespace {
40 
42  template <typename T>
43  size_t StringLength(const T& value) {
44  std::ostringstream sstr;
45  sstr << value;
46  return sstr.str().length();
47  } // StringLength()
48 
57  template <typename STREAM, typename CONT>
58  void PrintCompactIndexTable(
59  STREAM& log, const CONT& Indices, unsigned int IndicesPerLine,
60  std::string IndentStr = "")
61  {
62  unsigned int Padding = StringLength(Indices.back());
63 
64  typename CONT::const_iterator iIndex = Indices.begin(),
65  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) {
72  ++RangeStop;
73  }
74  else {
75  // the new item does not belong to the current range:
76  // - print the current range
77  if (nItemsInLine) output_line << " ";
78  if (RangeStart == RangeStop) {
79  output_line << std::setw(Padding) << RangeStart;
80  ++nItemsInLine;
81  }
82  else {
83  char fill = (RangeStart + 1 == RangeStop)? ' ': '-';
84  output_line << std::setw(Padding) << RangeStart
85  << fill << fill
86  << std::setw(Padding) << std::setfill(fill) << RangeStop
87  << std::setfill(' ');
88  nItemsInLine += 2;
89  }
90  // - start a new one
91  RangeStart = RangeStop = *iIndex;
92  } // if ... else
93 
94  // if we have enough stuff in the buffer, let's print it
95  if (nItemsInLine >= IndicesPerLine) {
96  nItemsInLine = 0;
97  log << IndentStr << output_line.str() << "\n";
98  output_line.str("");
99  }
100 
101  } // while
102 
103  // print what we have accumulated so far of the last line
104  log << IndentStr << output_line.str();
105  // print the last range (or single element)
106  if (nItemsInLine) log << " ";
107  if (RangeStart == RangeStop)
108  log << std::setw(Padding) << RangeStart;
109  else {
110  char fill = (RangeStart + 1 == RangeStop)? ' ': '-';
111  log << std::setw(Padding) << RangeStart
112  << fill << fill
113  << std::setw(Padding) << std::setfill(fill) << RangeStop
114  << std::setfill(' ');
115  }
116  log << std::endl;
117  } // PrintCompactIndexTable()
118 
119 
120 
132  template <typename STREAM, typename CONT, typename GETINDEX>
133  void PrintCompactIndexTable(
134  STREAM& log, const CONT& Objects, unsigned int IndicesPerLine,
135  GETINDEX IndexExtractor, std::string IndentStr)
136  {
137  if ((IndicesPerLine == 0) || Objects.empty()) return;
138 
139  std::vector<size_t> Indices;
140  Indices.reserve(Objects.size());
141  std::transform(Objects.begin(), Objects.end(), std::back_inserter(Indices),
142  IndexExtractor);
143  std::sort(Indices.begin(), Indices.end());
144  PrintCompactIndexTable(log, Indices, IndicesPerLine, IndentStr);
145 
146  } // PrintCompactIndexTable()
147 
159  template <typename STREAM, typename T>
160  inline void PrintAssociatedIndexTable(
161  STREAM& log, const std::vector<art::Ptr<T>>& Objects,
162  unsigned int IndicesPerLine, std::string IndentStr = ""
163  ) {
164  PrintCompactIndexTable(
165  log, Objects, IndicesPerLine, std::mem_fn(&art::Ptr<T>::key),
166  IndentStr
167  );
168  } // PrintAssociatedIndexTable()
169 
170 
182  template <typename STREAM, typename T>
183  inline void PrintAssociatedIDTable(
184  STREAM& log, const std::vector<art::Ptr<T>>& Objects,
185  unsigned int IndicesPerLine, std::string IndentStr = ""
186  ) {
187  PrintCompactIndexTable(
188  log, Objects, IndicesPerLine,
189  [](const art::Ptr<T>& ptr) { return ptr->ID(); },
190  IndentStr
191  );
192  } // PrintAssociatedIDTable()
193 
194 } // local namespace
195 
196 
197 namespace recob {
198 
228  class DumpTracks : public art::EDAnalyzer {
229  public:
230 
232  struct Config {
234  using Name = fhicl::Name;
235 
237  Name("TrackModuleLabel"),
238  Comment("input tag for the tracks to be dumped")
239  };
241  Name("OutputCategory"),
242  Comment("name of the category used for message facility output"),
243  "DumpTracks"
244  };
246  Name("WayPoints"),
247  Comment("number of points along the trajectory printed"),
248  10U
249  };
251  Name("SpacePointAssociations"),
252  Comment("prints the number of space points associated to the track"),
253  true
254  };
256  Name("PrintSpacePoints"),
257  Comment("prints the index of all space points associated to the track"),
258  false
259  };
261  Name("HitAssociations"),
262  Comment("prints the number of hits associated to the track"),
263  true
264  };
266  Name("PrintHits"),
267  Comment("prints the index of all hits associated to the track"),
268  false
269  };
271  Name("ParticleAssociations"),
272  Comment("prints the number of PF particles associated to the track"),
273  true
274  };
275 
276  }; // Config
277 
279 
281  explicit DumpTracks(Parameters const& config);
282 
284  void analyze (const art::Event& evt);
285 
286  private:
287 
289  std::string fOutputCategory;
290  unsigned int fPrintWayPoints;
291 
292  bool fPrintNHits;
295  bool fPrintHits;
298 
300  void DumpTrack(unsigned int iTrack, recob::Track const& track) const;
301 
302  }; // class DumpTracks
303 
304 } // namespace recob
305 
306 
307 //------------------------------------------------------------------------------
308 namespace {
309 
310  template <typename STREAM>
311  bool PrintdQdXinView(
312  STREAM& log,
313  const recob::Track& track, geo::View_t view, std::string ViewName
314  ) {
315  auto nData = 0;
316  try { nData = track.NumberdQdx(view); }
317  catch (std::out_of_range) { return false; }
318  log << " " << ViewName << ": " << nData;
319  return true;
320  } // PrintdQdXinView()
321 
322 } // local namespace
323 
324 
325 namespace recob {
326 
327  //-------------------------------------------------
329  : EDAnalyzer (config)
330  , fTrackModuleLabel (config().TrackModuleLabel())
331  , fOutputCategory (config().OutputCategory())
332  , fPrintWayPoints (config().WayPoints())
333  , fPrintNHits (config().HitAssociations())
336  , fPrintHits (config().PrintHits())
337  , fPrintSpacePoints (config().PrintSpacePoints())
339  {}
340 
341  //-------------------------------------------------
342  void DumpTracks::analyze(const art::Event& evt) {
343 
344  // fetch the data to be dumped on screen
345  auto Tracks
346  = evt.getValidHandle<std::vector<recob::Track>>(fTrackModuleLabel);
347 
349  << "The event contains " << Tracks->size() << " '"
350  << fTrackModuleLabel.encode() << "'tracks";
351 
352  std::unique_ptr<art::FindManyP<recob::Hit>> pHits(
353  fPrintNHits?
355  nullptr
356  );
357  if (pHits && !pHits->isValid()) {
359  << "No hit associated with '" << fTrackModuleLabel.encode()
360  << "' tracks.\n";
361  }
362 
363  std::unique_ptr<art::FindManyP<recob::SpacePoint>> pSpacePoints(
366  nullptr
367  );
368  if (pSpacePoints && !pSpacePoints->isValid()) {
370  << "No space point associated with '" << fTrackModuleLabel.encode()
371  << "' tracks.\n";
372  }
373 
374  std::unique_ptr<art::FindManyP<recob::PFParticle>> pPFParticles(
377  nullptr
378  );
379  if (pPFParticles && !pPFParticles->isValid()) {
381  << "No particle-flow particle associated with '"
382  << fTrackModuleLabel.encode() << "' tracks.\n";
383  }
384 
385  for (unsigned int iTrack = 0; iTrack < Tracks->size(); ++iTrack) {
386  const recob::Track& track = Tracks->at(iTrack);
387 
388  // print track information
389  DumpTrack(iTrack, track);
390 
392  if (pHits || pSpacePoints || pPFParticles) {
393  log << "\n associated with:";
394  if (pHits)
395  log << " " << pHits->at(iTrack).size() << " hits;";
396  if (pSpacePoints)
397  log << " " << pSpacePoints->at(iTrack).size() << " space points;";
398  if (pPFParticles)
399  log << " " << pPFParticles->at(iTrack).size() << " PF particles;";
400  } // if we have any association
401 
402  if (pHits && fPrintHits) {
403  const auto& Hits = pHits->at(iTrack);
404  log << "\n hit indices (" << Hits.size() << "):\n";
405  PrintAssociatedIndexTable(log, Hits, 10 /* 10 hits per line */, " ");
406  } // if print individual hits
407 
408  if (pSpacePoints && fPrintSpacePoints) {
409  const auto& SpacePoints = pSpacePoints->at(iTrack);
410  log << "\n space point IDs (" << SpacePoints.size() << "):\n";
411  PrintAssociatedIDTable
412  (log, SpacePoints, 10 /* 10 hits per line */, " ");
413  } // if print individual space points
414 
415  if (pPFParticles && fPrintParticles) {
416  const auto& PFParticles = pPFParticles->at(iTrack);
417  log << "\n particle indices (" << PFParticles.size() << "):\n";
418  // currently a particle has no ID
419  PrintAssociatedIndexTable
420  (log, PFParticles, 10 /* 10 hits per line */, " ");
421  } // if print individual particles
422  } // for tracks
423  } // DumpTracks::analyze()
424 
425 
426  //---------------------------------------------------------------------------
428  (unsigned int iTrack, recob::Track const& track) const
429  {
430  // print a header for the track
431  const unsigned int nPoints = track.NumberTrajectoryPoints();
433  log
434  << "Track #" << iTrack << " ID: " << track.ID()
435  << std::fixed << std::setprecision(3)
436  << " theta: " << track.Theta() << " rad, phi: " << track.Phi()
437  << " rad, length: " << track.Length() << " cm"
438  << "\n start at: ( " << track.Vertex().X()
439  << " ; " << track.Vertex().Y()
440  << " ; " << track.Vertex().Z()
441  << " ), direction: ( " << track.VertexDirection().X()
442  << " ; " << track.VertexDirection().Y()
443  << " ; " << track.VertexDirection().Z() << " )"
444  << "\n end at: ( " << track.End().X()
445  << " ; " << track.End().Y()
446  << " ; " << track.End().Z()
447  << " ), direction: ( " << track.EndDirection().X()
448  << " ; " << track.EndDirection().Y()
449  << " ; " << track.EndDirection().Z()
450  << " )"
451  << "\n with "
452  << nPoints << " trajectory points, "
453  << track.NumberCovariance() << " covariance matrices";
454  unsigned int nViews = 0;
455  std::ostringstream sstr;
456  if (PrintdQdXinView(sstr, track, geo::kU, "U")) ++nViews;
457  if (PrintdQdXinView(sstr, track, geo::kV, "V")) ++nViews;
458  if (PrintdQdXinView(sstr, track, geo::kZ, "Z")) ++nViews;
459  if (PrintdQdXinView(sstr, track, geo::k3D, "3D")) ++nViews;
460  if (nViews)
461  log << ", dQ/dx in " << nViews << " views: " << sstr.str();
462  else
463  log << ", no dQ/dx";
464 
465  if (fPrintWayPoints > 0) {
466  // print up to 10 (actually, 8 or 9) way points
467  log << "\n passes through:";
468  unsigned int skip = std::max(nPoints / fPrintWayPoints, 1U);
469  unsigned int iPoint = 0;
470  while ((iPoint += skip) < nPoints) {
471  const TVector3& point = track.LocationAtPoint(iPoint);
472  log << "\n [#" << iPoint << "] ("
473  << point.X() << ", " << point.Y() << ", " << point.Z()
474  << ")";
475  } // while (iPoint)
476  } // if print way points
477  } // DumpTracks::DumpTrack()
478 
479 
480  //---------------------------------------------------------------------------
482 
483 } // namespace recob
void DumpTrack(unsigned int iTrack, recob::Track const &track) const
Dumps information about the specified track.
TVector3 LocationAtPoint(unsigned int p) const
Covariance matrices are either set or not.
Definition: Track.h:241
fhicl::Atom< unsigned int > WayPoints
bool fPrintNSpacePoints
prints the number of associated space points
Reconstruction base classes.
TVector3 VertexDirection() const
Covariance matrices are either set or not.
Definition: Track.h:247
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Planes which measure V.
Definition: geo_types.h:77
fhicl::Atom< std::string > OutputCategory
Declaration of signal hit object.
fhicl::Atom< bool > PrintHits
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:109
Planes which measure Z direction.
Definition: geo_types.h:79
void analyze(const art::Event &evt)
Does the printing.
size_t NumberdQdx(geo::View_t view=geo::kUnknown) const
Covariance matrices are either set or not.
Definition: Track.cxx:67
fhicl::Atom< bool > ParticleAssociations
Configuration object.
3-dimensional objects, potentially hits, clusters, prongs, etc.
Definition: geo_types.h:82
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Planes which measure U.
Definition: geo_types.h:76
Int_t max
Definition: plot.C:27
double Phi() const
Access to spherical or geographical angles at vertex or at any point.
Definition: Track.h:185
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:174
intermediate_table::const_iterator const_iterator
art::InputTag fTrackModuleLabel
name of module that produced the tracks
fhicl::Atom< bool > PrintSpacePoints
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
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:183
fhicl::Atom< bool > SpacePointAssociations
std::string encode() const
Definition: InputTag.cc:36
fhicl::Atom< bool > HitAssociations
fhicl::Atom< art::InputTag > TrackModuleLabel
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
EDAnalyzer(Table< Config > const &config)
Definition: EDAnalyzer.h:100
Provides recob::Track data product.
size_type size() const
Definition: PtrVector.h:308
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:205
Prints the content of all the tracks on screen.
std::string value(boost::any const &)
DumpTracks(Parameters const &config)
Default constructor.
bool fPrintNParticles
prints the number of associated PFParticles
std::string fOutputCategory
category for LogInfo output
TVector3 Vertex() const
Covariance matrices are either set or not.
Definition: Track.h:245
TVector3 EndDirection() const
Covariance matrices are either set or not.
Definition: Track.h:248
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
bool fPrintParticles
prints the index of associated PFParticles
Float_t track
Definition: plot.C:34
TVector3 End() const
Covariance matrices are either set or not.
Definition: Track.h:246
size_t NumberCovariance() const
Covariance matrices are either set or not.
Definition: Track.h:239
bool fPrintSpacePoints
prints the index of associated space points
unsigned int fPrintWayPoints
number of printed way points
Definition: fwd.h:25
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:51