LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DumpOpFlashes_module.cc
Go to the documentation of this file.
1 
8 // LArSoft libraries
13 
14 // art libraries
22 
23 // support libraries
24 #include "fhiclcpp/types/Atom.h"
25 #include "fhiclcpp/types/Comment.h"
26 #include "fhiclcpp/types/Name.h"
28 
29 // C//C++ standard libraries
30 #include <cassert>
31 #include <optional>
32 #include <ostream>
33 #include <string>
34 #include <unordered_map>
35 #include <vector>
36 
37 // -----------------------------------------------------------------------------
38 namespace ophit {
39  class DumpOpFlashes;
40 }
41 
72 public:
73  struct Config {
74  using Name = fhicl::Name;
76 
78  Name{"OpFlashModuleLabel"},
79  Comment{"tag of the recob::OpFlash collection to be dumped"}};
80 
82  Name("PrintOpHitAssociations"),
83  Comment("also prints a list of optical hits associated to the flash"),
84  true};
85 
87  Name("OutputCategory"),
88  Comment("the messagefacility category used for the output"),
89  "DumpOpFlashes"};
90 
91  }; // Config
92 
94 
96  explicit DumpOpFlashes(Parameters const& config);
97 
99  void analyze(const art::Event& evt) override;
100 
101 private:
104  std::string const fOutputCategory;
105 
106 }; // class ophit::DumpOpFlashes
107 
108 // -----------------------------------------------------------------------------
109 // --- implementation
110 // -----------------------------------------------------------------------------
111 namespace {
112 
113  struct ProductSourceEntry_t {
114  std::size_t index = 0;
115  art::BranchDescription const* info = nullptr;
116  };
117  using ProductSourceDirectory_t = std::unordered_map<art::ProductID, ProductSourceEntry_t>;
118 
133  template <std::size_t Side = 1U, typename Assns, typename Event>
134  ProductSourceDirectory_t buildAssnsSourceDirectory(Assns const& assns, Event const& event)
135  {
136 
137  ProductSourceDirectory_t dir;
138 
139  // extract all the unique IDs
140  for (auto const& ptrs : assns)
141  dir.try_emplace(std::get<Side>(ptrs).id());
142 
143  // assign the index and pointer to each entry (order is not defined)
144  std::size_t index{0};
145  for (auto& [id, info] : dir)
146  info = {index++, event.getProductDescription(id).get()};
147 
148  return dir;
149  } // buildAssnsSourceDirectory()
150 
151  //----------------------------------------------------------------------------
152  void printAssociatedOpHits(std::ostream& out,
154  ProductSourceDirectory_t const* sourceMap,
155  std::string const& indent,
156  int const itemsPerLine)
157  {
158  out << hits.size() << " hits associated:";
159  int itemsLeft = 0;
160  const bool bPrintSources = sourceMap && (sourceMap->size() >= 2);
161  for (art::Ptr<recob::OpHit> const& hitPtr : hits) {
162  if (itemsLeft-- <= 0) {
163  itemsLeft += itemsPerLine;
164  out << "\n" << indent;
165  }
166 
167  out << " [";
168  if (bPrintSources) out << "S#" << sourceMap->at(hitPtr.id()).index << ";";
169  out << "#" << hitPtr.key() << "]";
170  if (!hitPtr.isAvailable()) continue;
171 
172  itemsLeft -= 5; // full hit information is equivalent to 6 "items"
173 
174  recob::OpHit const& hit = *hitPtr;
175  out << " ch=" << hit.OpChannel();
176  if (hit.HasStartTime())
177  out << " time=" << hit.StartTime();
178  else
179  out << " peak time=" << hit.PeakTime();
180  out << " p.e.=" << hit.PE();
181 
182  } // for hits
183  } // printAssociatedOpHits()
184 
185  //----------------------------------------------------------------------------
186  struct dumpAssociatedOpHits {
187  std::vector<art::Ptr<recob::OpHit>> const& hits;
188  ProductSourceDirectory_t const* sourceMap;
189  };
190 
191  std::ostream& operator<<(std::ostream& out, dumpAssociatedOpHits const& hits)
192  {
193  printAssociatedOpHits(out, hits.hits, hits.sourceMap, "", 18);
194  return out;
195  }
196 
197  //----------------------------------------------------------------------------
198 
199 } // local namespace
200 
201 // -----------------------------------------------------------------------------
203  : art::EDAnalyzer(config)
206  , fOutputCategory(config().OutputCategory())
207 {
208  consumes<std::vector<recob::OpFlash>>(fOpFlashModuleTag);
210  consumes<art::Assns<recob::OpFlash, recob::OpHit>>(fOpFlashModuleTag);
211 }
212 
213 //------------------------------------------------------------------------------
215 {
216 
217  // fetch the data to be dumped on screen
218  auto const& OpFlashHandle = event.getValidHandle<std::vector<recob::OpFlash>>(fOpFlashModuleTag);
219 
221  << "Event " << event.id() << " contains " << OpFlashHandle->size() << " '"
222  << fOpFlashModuleTag.encode() << "' optical flashes.";
223 
224  std::optional const flashHits =
226  std::make_optional<art::FindManyP<recob::OpHit>>(OpFlashHandle, event, fOpFlashModuleTag) :
227  std::nullopt;
228  ProductSourceDirectory_t const sourceMap =
230  buildAssnsSourceDirectory<1>(
232  ProductSourceDirectory_t{};
233  assert(!fPrintOpHitAssociations || (flashHits->size() == 0) || !sourceMap.empty());
234 
235  for (auto const& [iFlash, flash] : util::enumerate(*OpFlashHandle)) {
236 
238  out << "OpFlash #" << iFlash << ": " << flash;
239 
240  if (flashHits) out << "\n " << dumpAssociatedOpHits{flashHits->at(iFlash), &sourceMap};
241 
242  } // for flashes
243 
244  if (sourceMap.size() > 1) {
246  out << "Hits were from " << sourceMap.size() << " data products (SRC):";
247  for (auto const& [index, info] : util::values(sourceMap))
248  out << " [S#" << index << "] '" << info->inputTag().encode() << "'";
249  out << ".";
250  }
251  else if (sourceMap.size() == 1) {
252  mf::LogVerbatim{fOutputCategory} << "All hits were from the data product '"
253  << sourceMap.begin()->second.info->inputTag().encode() << "'.";
254  }
255 
256 } // ophit::DumpOpFlashes::analyze()
257 
258 //------------------------------------------------------------------------------
260 
261 //------------------------------------------------------------------------------
void analyze(const art::Event &evt) override
Does the printing.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::string const fOutputCategory
Category for mf::LogInfo output.
fhicl::Atom< bool > PrintOpHitAssociations
Prints the content of all the flashes on screen.
Definition of util::enumerate().
bool const fPrintOpHitAssociations
Whether to print optical hits.
double PeakTime() const
Definition: OpHit.h:94
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
std::string encode() const
Definition: InputTag.cc:97
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:65
double StartTime() const
Definition: OpHit.h:102
bool HasStartTime() const
Definition: OpHit.h:130
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
void hits()
Definition: readHits.C:15
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
std::string indent(std::size_t const i)
fhicl::Atom< art::InputTag > OpFlashModuleLabel
art::InputTag const fOpFlashModuleTag
Optical hit data product tag.
double PE() const
Definition: OpHit.h:122
Detector simulation of raw signals on wires.
Stream & operator<<(Stream &&out, CallInfo_t const &info)
Helper operator to insert a call information in a stream with default options.
Definition: DebugUtils.h:389
TDirectory * dir
Definition: macro.C:5
Definition: MVAAlg.h:12
Definition of util::values() and util::const_values().
TCEvent evt
Definition: DataStructs.cxx:8
DumpOpFlashes(Parameters const &config)
Default constructor.
int OpChannel() const
Definition: OpHit.h:86
Event finding and building.
fhicl::Atom< std::string > OutputCategory