LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
AllowedConfiguration.cc
Go to the documentation of this file.
7 #include "cetlib/HorizontalRule.h"
8 #include "cetlib/container_algorithms.h"
10 
11 #include <iomanip>
12 #include <iostream>
13 #include <tuple>
14 
15 using namespace art::detail;
16 using std::cout;
17 
18 namespace {
19 
20  constexpr cet::HorizontalRule fixed_rule{100};
21 
22  std::vector<art::detail::PluginMetadata>
23  matchesBySpec(std::string const& specified_plugin_type,
24  std::string const& instance_pattern)
25  {
26  std::vector<PluginMetadata> result;
27  auto collect_metadata = [&result,
28  &instance_pattern](art::suffix_type const st) {
29  auto mc = get_MetadataCollector(st);
30  cet::transform_all(
31  get_LibraryInfoCollection(st, instance_pattern),
32  std::back_inserter(result),
33  [&mc](auto const& info) { return mc->collect(info, indent__2()); });
34  };
35 
36  if (specified_plugin_type.empty()) {
37  // Search through all plugin types if the user has not specified one.
38  for (auto const& pr : art::Suffixes::all()) {
39  collect_metadata(pr.first);
40  }
41  } else {
42  collect_metadata(art::Suffixes::get(specified_plugin_type));
43  }
44  return result;
45  }
46 
47  using Duplicates_t = std::map<std::string, std::vector<std::string>>;
48  void
49  duplicates_message(art::suffix_type const st, Duplicates_t const& duplicates)
50  {
51  using namespace art;
52  std::string const type_spec =
53  (st == suffix_type::plugin) ? "plugin_type" : "module_type";
54  cout
55  << indent0() << "The " << Suffixes::get(st)
56  << "s marked '*' above are degenerate--i.e. specifying the short\n"
57  << indent0() << type_spec
58  << " value leads to an ambiguity. In order to use a degenerate\n"
59  << indent0() << Suffixes::get(st)
60  << ", in your configuration file, give the long specification (as\n"
61  << indent0()
62  << "shown in the table below), surrounded by quotation (\") marks.\n\n";
63  std::size_t const firstColW{
64  columnWidth(duplicates, &Duplicates_t::value_type::first, "module_type")};
65  cout << indent0() << std::setw(firstColW + 4) << std::left << type_spec
66  << std::left << "Long specification" << '\n';
67  cout << indent0() << fixed_rule('-') << '\n';
68  for (auto const& dup : duplicates) {
69  auto const& long_specs = dup.second;
70  cout << indent0() << std::setw(firstColW + 4) << std::left << dup.first
71  << std::left << long_specs[0] << '\n';
72  for (auto it = long_specs.begin() + 1, end = long_specs.end(); it != end;
73  ++it) {
74  cout << indent0() << std::setw(firstColW + 4) << "\"\"" << std::left
75  << *it << '\n';
76  }
77  }
78  }
79 }
80 
81 void
83  bool const verbose,
84  std::string const& spec)
85 {
86  auto coll = get_LibraryInfoCollection(st, spec, verbose);
87  if (coll.empty())
88  return;
89 
90  auto ms = get_MetadataSummary(st, coll);
91 
92  cet::HorizontalRule const rule{rule_size(ms->widths())};
93  cout << "\n"
94  << rule('=') << "\n\n"
95  << ms->header() << "\n"
96  << rule('-') << '\n';
97 
98  std::size_t i{};
99  Duplicates_t duplicates;
100  for (auto const& info : coll) {
101  auto summary = ms->summary(info, ++i);
102  cout << summary.message;
103  if (summary.is_duplicate)
104  duplicates[info.short_spec()].push_back(info.long_spec());
105  }
106  cout << "\n" << rule('=') << "\n\n";
107 
108  if (duplicates.empty())
109  return;
110 
111  duplicates_message(st, duplicates);
112  cout << "\n\n";
113 }
114 
115 bool
117  std::string const& spec,
118  std::string const& key)
119 {
120  art::Exception e{art::errors::LogicError, "art::detail::has_key"};
121  auto coll = get_LibraryInfoCollection(st, spec);
122  if (coll.empty()) {
123  throw e << (spec.empty() ? "[Missing specification]" : bold_fontify(spec))
124  << " did not match any plugin.\n";
125  } else if (coll.size() > 1ull) {
126  throw e << bold_fontify(spec) << " matched more than one plugin.\n"
127  << "When querying plugin configurations, the plugin specification\n"
128  << "must resolve to a unique library.\n";
129  }
130  if (auto config = coll.begin()->allowed_config()) {
132  *config->parameter_base(), key);
133  }
134  return false;
135 }
136 
137 void
138 art::detail::print_description(std::vector<PluginMetadata> const& matches)
139 {
140  for (auto const& m : matches) {
141  cout << m.header() << m.details() << m.allowed_configuration();
142  cout << '\n' << fixed_rule('=') << "\n\n";
143  }
144 }
145 
146 namespace {
147  std::pair<std::string, std::string>
148  parse_specified_plugin(std::string const& spec)
149  {
150  // The specified plugin can be of the pattern:
151  //
152  // [<plugin_type>:]<regex corresponding to plugin instance>
153  //
154  // If '<plugin_type>:' is omitted, then all plugin types are searched.
155  std::string specified_plugin_type{};
156  std::string instance_pattern{spec};
157  auto const pos = spec.find(":");
158  if (pos != std::string::npos) {
159  specified_plugin_type = spec.substr(0, pos);
160  if (specified_plugin_type.empty()) {
162  "Error while parsing specified plugins:\n"}
163  << "The specification '" << spec
164  << "' is missing a module type before the colon (':').\n"
165  "If you intend to search through all plugin types, remove the "
166  "colon; otherwise specify\n"
167  "one of the following plugin types:"
168  << art::Suffixes::print() << '\n';
169  }
170  instance_pattern = spec.substr(pos + 1);
171  }
172  return std::make_pair(std::move(specified_plugin_type),
173  std::move(instance_pattern));
174  }
175 }
176 
177 void
178 art::detail::print_descriptions(std::vector<std::string> const& specs)
179 {
180  cout << '\n' << fixed_rule('=') << "\n\n";
181  for (auto const& spec : specs) {
182  std::string plugin_type{}, instance_pattern{};
183  std::tie(plugin_type, instance_pattern) = parse_specified_plugin(spec);
184 
185  auto matches = matchesBySpec(plugin_type, instance_pattern);
186  if (matches.empty()) {
187  cout << indent0()
188  << (instance_pattern.empty() ? "[Missing specification]" :
189  bold_fontify(instance_pattern))
190  << " did not match any plugin";
191  cout << (plugin_type.empty() ? "" : " of type '" + plugin_type + "'");
192  cout << ".\n";
193  cout << '\n' << fixed_rule('=') << "\n\n";
194  continue;
195  }
196  print_description(matches);
197  }
198 }
std::string bold_fontify(std::string const &s)
Definition: bold_fontify.h:9
static std::map< suffix_type, std::string > const & all()
std::size_t columnWidth(T const &coll, std::string const Elem::*cp, std::string const &header)
static std::string print()
std::size_t rule_size(Widths const &widths)
std::string indent__2()
LibraryInfoCollection get_LibraryInfoCollection(suffix_type suffix, std::string const &pattern, bool const verbose=false)
void print_available_plugins(suffix_type st, bool const verbose, std::string const &spec)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
void print_descriptions(std::vector< std::string > const &plugins)
static std::string const & get(suffix_type st)
std::string indent0()
HLT enums.
void print_description(std::vector< PluginMetadata > const &matches)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
std::unique_ptr< MetadataSummary > get_MetadataSummary(suffix_type st, LibraryInfoCollection const &coll)
Float_t e
Definition: plot.C:34
static bool supports_key(ParameterBase const &pb, std::string const &searched_for_key)
bool supports_key(suffix_type st, std::string const &spec, std::string const &key)
std::unique_ptr< MetadataCollector > get_MetadataCollector(suffix_type st)