LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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 | size
7 //
8 // ======================================================================
9 
17 #include "cetlib/column_width.h"
18 #include "cetlib/lpad.h"
19 #include "cetlib/rpad.h"
20 #include "fhiclcpp/ParameterSet.h"
22 
23 #include <algorithm>
24 #include <iomanip>
25 #include <iostream>
26 #include <string>
27 #include <vector>
28 
29 namespace art {
30  namespace detail {
31  struct ProductInfo {
32  std::string module_label;
33  std::string instance_name;
34  std::string product_type;
35  std::string friendly_type;
36  std::string str_size;
37  };
38  }
39 }
40 
41 namespace {
42 
43  std::string
44  product_size(art::EDProduct const* product, bool const isPresent)
45  {
46  return isPresent ? product->productSize() : "?";
47  }
48 
49  std::string
50  dummyProcess()
51  {
52  return "PROCESS NAME";
53  }
54  auto
55  dummyInfo()
56  {
57  return art::detail::ProductInfo{"MODULE_LABEL",
58  "PRODUCT INSTANCE NAME",
59  "DATA PRODUCT TYPE",
60  "PRODUCT FRIENDLY TYPE",
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 
90 namespace art {
91  class FileDumperOutput;
92 }
93 
95 
97 public:
98  struct Config {
100  fhicl::Atom<bool> wantProductFullClassName{
101  fhicl::Name("wantProductFullClassName"),
102  true};
103  fhicl::Atom<bool> wantProductFriendlyClassName{
104  fhicl::Name("wantProductFriendlyClassName"),
105  wantProductFullClassName()};
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 
132 }; // FileDumperOutput
133 
136  : OutputModule{ps().omConfig, ps.get_PSet()}
137  , wantProductFullClassName_{ps().wantProductFullClassName()}
138  , wantProductFriendlyClassName_{ps().wantProductFriendlyClassName()}
139  , wantResolveProducts_{ps().resolveProducts()}
140  , wantPresentOnly_{ps().onlyIfPresent()}
141 {}
142 
143 void
145 {
146  printPrincipal(e);
147 }
148 
149 void
151 {
152  printPrincipal(r);
153 }
154 
155 void
157 {
158  printPrincipal(sr);
159 }
160 
161 void
163 {
164  printPrincipal(resp);
165 }
166 
167 template <typename P>
168 void
170 {
171  if (!p.size())
172  return;
173 
174  size_t present{0};
175  size_t not_present{0};
176  std::map<std::string, std::vector<detail::ProductInfo>> products;
177 
178  auto const& dinfo = dummyInfo();
179 
180  products[dummyProcess()].emplace_back(dinfo);
181 
182  for (auto const& pr : p) {
183  auto const& g = *pr.second;
184  auto const& oh =
185  p.getForOutput(g.productDescription().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{g.moduleLabel(),
198  g.productInstanceName(),
199  g.productDescription().producedClassName(),
200  g.productDescription().friendlyClassName(),
201  product_size(product, productPresent)};
202  products[g.processName()].emplace_back(std::move(pi));
203  }
204  }
205 
206  std::cout << "PRINCIPAL TYPE: " << BranchTypeToString(p.branchType())
207  << std::endl;
208 
209  std::vector<std::size_t> const widths{
210  columnWidthFirst(products, dummyProcess()),
211  columnWidth(
212  products, &detail::ProductInfo::module_label, dinfo.module_label),
213  columnWidth(
214  products, &detail::ProductInfo::instance_name, dinfo.instance_name),
215  columnWidth(
216  products, &detail::ProductInfo::product_type, dinfo.product_type),
217  columnWidth(
218  products, &detail::ProductInfo::friendly_type, dinfo.friendly_type),
219  columnWidth(products, &detail::ProductInfo::str_size, dinfo.str_size)};
220 
221  // Print banner
222  printProductInfo(widths, dummyProcess(), dummyInfo());
223  for (auto const& processConfig : p.processHistory()) {
224  auto const& processName = processConfig.processName();
225  for (auto const& pi : products[processName]) {
226  printProductInfo(widths, processName, pi);
227  }
228  }
229 
230  std::cout << "\nTotal products (present, not present): "
231  << present + not_present << " (" << present << ", " << not_present
232  << ").\n\n";
233 }
234 
235 void
236 art::FileDumperOutput::printProductInfo(std::vector<std::size_t> const& widths,
237  std::string const& processName,
238  detail::ProductInfo const& pi) const
239 {
240  std::ostringstream oss;
241  oss << cet::rpad(processName, widths[0], '.') << " | "
242  << cet::rpad(pi.module_label, widths[1], '.') << " | "
243  << cet::rpad(pi.instance_name, widths[2], '.') << " | ";
245  oss << cet::rpad(pi.product_type, widths[3], '.') << " | ";
247  oss << cet::rpad(pi.friendly_type, widths[4], '.') << " | ";
248  oss << cet::lpad(pi.str_size, widths[5], '.');
249  std::cout << oss.str() << '\n';
250 }
251 
void write(EventPrincipal &e) override
auto const & get_PSet() const
std::size_t columnWidth(T const &coll, std::string const Elem::*cp, std::string const &header)
FileDumperOutput(Parameters const &)
Int_t max
Definition: plot.C:27
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
void printProductInfo(std::vector< std::size_t > const &columnWidths, std::string const &processName, detail::ProductInfo const &pi) const
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:55
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
HLT enums.
bool isPresent() const
Definition: EDProduct.h:28
void writeSubRun(SubRunPrincipal &sr) override
Float_t e
Definition: plot.C:34
ProductStatus present()
Definition: ProductStatus.h:16
std::string const & processName() const