LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
FileDumperOutput_module.cc
Go to the documentation of this file.
1 // ======================================================================
2 //
3 // FileDumperOutput.cc: "dump contents of a file"
4 //
5 // Proposed output format (Feature #941):
6 // Process Name | Module Label | Process Label | Data Product type | (ProductID
7 // |) size
8 //
9 // ======================================================================
10 
16 #include "cetlib/lpad.h"
17 #include "cetlib/rpad.h"
19 #include "range/v3/view.hpp"
20 
21 #include <algorithm>
22 #include <iostream>
23 #include <string>
24 #include <vector>
25 
26 using namespace ::ranges;
27 
28 namespace art::detail {
29  struct ProductInfo {
30  std::string module_label;
31  std::string instance_name;
32  std::string product_type;
33  std::string friendly_type;
34  std::string product_id;
35  std::string str_size;
36  };
37 } // namespace art::detail
38 
39 namespace {
40 
41  std::string
42  product_size(art::EDProduct const* product, bool const isPresent)
43  {
44  return isPresent ? product->productSize() : "?";
45  }
46 
47  std::string
48  dummyProcess()
49  {
50  return "PROCESS NAME";
51  }
52 
53  auto
54  dummyInfo()
55  {
56  return art::detail::ProductInfo{"MODULE LABEL",
57  "PRODUCT INSTANCE NAME",
58  "DATA PRODUCT TYPE",
59  "PRODUCT FRIENDLY TYPE",
60  "PRODUCT ID",
61  "SIZE"};
62  }
63 
64  using ProductInfos = std::vector<art::detail::ProductInfo>;
65  std::size_t
66  columnWidthFirst(std::map<std::string, ProductInfos> const& m,
67  std::string const& title)
68  {
69  std::size_t i{title.size()};
70  cet::for_all(
71  m, [&i](auto const& entry) { i = std::max(i, entry.first.size()); });
72  return i;
73  }
74 
75  std::size_t
76  columnWidth(std::map<std::string, ProductInfos> const& m,
77  std::string const art::detail::ProductInfo::*pim,
78  std::string const& title)
79  {
80  std::size_t i{title.size()};
81  for (auto const& entry : m) {
82  for (auto const& pi : entry.second) {
83  i = std::max(i, (pi.*pim).size());
84  }
85  }
86  return i;
87  }
88 
89 } // namespace
90 
91 namespace art {
92  class FileDumperOutput;
93 }
94 
96 public:
97  struct Config {
99  fhicl::Atom<bool> wantProductFullClassName{
100  fhicl::Name("wantProductFullClassName"),
101  true};
102  fhicl::Atom<bool> wantProductFriendlyClassName{
103  fhicl::Name("wantProductFriendlyClassName"),
104  wantProductFullClassName()};
105  fhicl::Atom<bool> wantProductID{fhicl::Name{"wantProductID"}, false};
106  fhicl::Atom<bool> resolveProducts{fhicl::Name("resolveProducts"), true};
107  fhicl::Atom<bool> onlyIfPresent{fhicl::Name("onlyIfPresent"), false};
108  };
109 
110  using Parameters =
112 
113  explicit FileDumperOutput(Parameters const&);
114 
115 private:
116  void write(EventPrincipal& e) override;
117  void writeRun(RunPrincipal& r) override;
118  void writeSubRun(SubRunPrincipal& sr) override;
119  void readResults(ResultsPrincipal const& resp) override;
120 
121  template <typename P>
122  void printPrincipal(P const& p);
123 
124  void printProductInfo(std::vector<std::size_t> const& columnWidths,
125  std::string const& processName,
126  detail::ProductInfo const& pi) const;
127 
130  bool const wantProductID_;
132  bool const wantPresentOnly_;
133 }; // FileDumperOutput
134 
136  : OutputModule{ps().omConfig}
137  , wantProductFullClassName_{ps().wantProductFullClassName()}
138  , wantProductFriendlyClassName_{ps().wantProductFriendlyClassName()}
139  , wantProductID_{ps().wantProductID()}
140  , wantResolveProducts_{ps().resolveProducts()}
141  , wantPresentOnly_{ps().onlyIfPresent()}
142 {}
143 
144 void
146 {
147  printPrincipal(e);
148 }
149 
150 void
152 {
153  printPrincipal(r);
154 }
155 
156 void
158 {
159  printPrincipal(sr);
160 }
161 
162 void
164 {
165  printPrincipal(resp);
166 }
167 
168 template <typename P>
169 void
171 {
172  if (!p.size())
173  return;
174 
175  size_t present{0};
176  size_t not_present{0};
177  std::map<std::string, std::vector<detail::ProductInfo>> products;
178 
179  auto const& dinfo = dummyInfo();
180 
181  products[dummyProcess()].emplace_back(dinfo);
182 
183  for (auto const& g : p | views::values | views::indirect) {
184  auto const& pd = g.productDescription();
185  auto const& oh = p.getForOutput(pd.productID(), wantResolveProducts_);
186 
187  EDProduct const* product = oh.isValid() ? oh.wrapper() : nullptr;
188  bool const productPresent = product != nullptr && product->isPresent();
189 
190  if (productPresent) {
191  ++present;
192  } else {
193  ++not_present;
194  }
195 
196  if (!wantPresentOnly_ || productPresent) {
197  auto pi = detail::ProductInfo{pd.moduleLabel(),
198  pd.productInstanceName(),
199  pd.producedClassName(),
200  pd.friendlyClassName(),
201  std::to_string(pd.productID().value()),
202  product_size(product, productPresent)};
203  products[pd.processName()].emplace_back(std::move(pi));
204  }
205  }
206 
207  std::cout << "PRINCIPAL TYPE: " << BranchTypeToString(p.branchType())
208  << std::endl;
209 
210  std::vector<std::size_t> const widths{
211  columnWidthFirst(products, dummyProcess()),
212  columnWidth(
213  products, &detail::ProductInfo::module_label, dinfo.module_label),
214  columnWidth(
215  products, &detail::ProductInfo::instance_name, dinfo.instance_name),
216  columnWidth(
217  products, &detail::ProductInfo::product_type, dinfo.product_type),
218  columnWidth(
219  products, &detail::ProductInfo::friendly_type, dinfo.friendly_type),
220  columnWidth(products, &detail::ProductInfo::product_id, dinfo.product_id),
221  columnWidth(products, &detail::ProductInfo::str_size, dinfo.str_size)};
222 
223  // Print banner
224  printProductInfo(widths, dummyProcess(), dummyInfo());
225  for (auto const& processConfig : p.processHistory()) {
226  auto const& processName = processConfig.processName();
227  for (auto const& pi : products[processName]) {
228  printProductInfo(widths, processName, pi);
229  }
230  }
231 
232  std::cout << "\nTotal products (present, not present): "
233  << present + not_present << " (" << present << ", " << not_present
234  << ").\n\n";
235 }
236 
237 void
238 art::FileDumperOutput::printProductInfo(std::vector<std::size_t> const& widths,
239  std::string const& processName,
240  detail::ProductInfo const& pi) const
241 {
242  std::ostringstream oss;
243  oss << cet::rpad(processName, widths[0], '.') << " | "
244  << cet::rpad(pi.module_label, widths[1], '.') << " | "
245  << cet::rpad(pi.instance_name, widths[2], '.') << " | ";
247  oss << cet::rpad(pi.product_type, widths[3], '.') << " | ";
248  }
250  oss << cet::rpad(pi.friendly_type, widths[4], '.') << " | ";
251  }
252  if (wantProductID_) {
253  oss << cet::rpad(pi.product_id, widths[5], '.') << " | ";
254  }
255  oss << cet::lpad(pi.str_size, widths[6], '.');
256  std::cout << oss.str() << '\n';
257 }
258 
TRandom r
Definition: spectrum.C:23
std::string const & processName() const
Definition: Observer.cc:57
void write(EventPrincipal &e) override
std::size_t columnWidth(T const &coll, std::string const Elem::*cp, std::string const &header)
FileDumperOutput(Parameters const &)
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
void printProductInfo(std::vector< std::size_t > const &columnWidths, std::string const &processName, detail::ProductInfo const &pi) const
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
std::string const & BranchTypeToString(BranchType const bt)
Definition: BranchType.cc:65
void writeRun(RunPrincipal &r) override
void readResults(ResultsPrincipal const &resp) override
fhicl::TableFragment< OutputModule::Config > omConfig
virtual std::string productSize() const
Definition: EDProduct.h:49
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
Definition: MVAAlg.h:12
bool isPresent() const
Definition: EDProduct.h:31
void writeSubRun(SubRunPrincipal &sr) override
Float_t e
Definition: plot.C:35
constexpr ProductStatus present() noexcept
Definition: ProductStatus.h:10