3 #include "cetlib/container_algorithms.h" 14 std::unique_ptr<std::set<std::string>>
17 std::vector<std::string>
tmp;
18 std::unique_ptr<std::set<std::string>> result;
20 result.reset(
new std::set<std::string>);
21 result->insert(tmp.cbegin(), tmp.cend());
27 stripLabel(std::string
const& labelInPathConfig)
29 auto label_start = labelInPathConfig.find_first_not_of(
"!-");
30 if (label_start > 1) {
32 <<
"Module label " << labelInPathConfig <<
" is illegal.\n";
34 return labelInPathConfig.substr(label_start);
38 filterAction(std::string
const& labelInPathConfig)
40 switch (labelInPathConfig[0]) {
42 return art::WorkerInPath::FilterAction::Veto;
44 return art::WorkerInPath::FilterAction::Ignore;
51 check_missing_paths(std::set<std::string>
const& specified_paths,
53 std::string
const& par_name,
54 std::ostream& error_stream)
57 std::set_difference(cbegin(specified_paths),
58 cend(specified_paths),
61 std::back_inserter(missing_paths));
62 for (
auto const& path : missing_paths) {
63 error_stream <<
"ERROR: Unknown path " << path <<
" specified by user in " 70 std::vector<std::string>
const& path_names)
72 using name_t = std::string;
73 using fhicl_t = std::string;
75 std::map<name_t, fhicl_t> bad_names;
76 for (
auto const& name : path_names) {
80 bad_names.emplace(name, type);
83 if (bad_names.empty())
88 "You have specified the following unsupported parameters in the\n" 89 "\"physics\" block of your configuration:\n\n";
91 cet::for_all(bad_names, [&err_msg](
auto const& name) {
92 err_msg.append(
" \"physics." + name.first +
"\" (" + name.second +
97 .append(
"Supported parameters include the following tables:\n")
98 .append(
" \"physics.producers\"\n")
99 .append(
" \"physics.filters\"\n")
100 .append(
" \"physics.analyzers\"\n")
102 "and sequences. Atomic configuration parameters are not allowed.\n\n");
159 auto& pathsInfo = it->second;
162 pathsInfo.makeAndAppendPath(val.first, val.second);
172 std::ostringstream error_stream;
173 for (
auto const& pathRootName :
176 for (
auto const& name : pathRoot.get_names()) {
180 if (actualModType != mci.moduleType()) {
181 error_stream <<
" ERROR: Module with label " << mci.label()
182 <<
" of type " << mci.libSpec() <<
" is configured as a " 184 <<
" but defined in code as a " 187 auto result = all_modules.emplace(mci.label(), mci);
188 if (!result.second) {
189 error_stream <<
" ERROR: Module label " << mci.label()
190 <<
" has been used in " 191 << result.first->second.configPath() <<
" and " 192 << pathRootName <<
".\n";
196 error_stream <<
" ERROR: Configuration of module with label " << name
197 <<
" encountered the following error:\n" 202 auto error_messages = error_stream.str();
203 if (!error_messages.empty()) {
205 <<
"The following were encountered while processing the module " 216 auto nSchedules[[gnu::unused]] =
217 procPS_.
get<
size_t>(
"services.scheduler.num_schedules", 1);
219 std::set<std::string> known_pars{
220 "analyzers",
"filters",
"producers",
"trigger_paths",
"end_paths"};
225 std::set_difference(keys.cbegin(),
229 std::back_inserter(path_names));
230 std::set<std::string> specified_modules;
231 std::ostringstream error_stream;
243 check_misspecified_paths(physics, path_names);
246 size_t num_end_paths{0};
247 for (
auto const& path_name : path_names) {
248 auto const path_seq = physics.get<
vstring>(path_name);
250 path_name, path_seq, trigger_path_names, error_stream)) {
253 for (
auto const& mod : path_seq) {
254 specified_modules.insert(stripLabel(mod));
257 if (num_end_paths > 1) {
259 <<
"Multiple end paths have been combined into one end path,\n" 260 <<
"\"end_path\" since order is irrelevant.\n";
264 std::set<std::string> all_module_labels;
266 all_module_labels.insert(val.first);
269 std::set_difference(all_module_labels.cbegin(),
270 all_module_labels.cend(),
271 specified_modules.cbegin(),
272 specified_modules.cend(),
273 std::back_inserter(unused_modules));
276 if (!unused_modules.empty()) {
277 std::ostringstream unusedStream;
278 unusedStream <<
"The following module label" 279 << ((unused_modules.size() == 1) ?
" is" :
"s are")
280 <<
" not assigned to any path:\n" 281 <<
"'" << unused_modules.front() <<
"'";
282 for (
auto i = unused_modules.cbegin() + 1,
e = unused_modules.cend();
285 unusedStream <<
", '" << *i <<
"'";
291 auto error_messages = error_stream.str();
292 if (!error_messages.empty()) {
294 <<
"The following were encountered while processing path " 298 return trigger_path_names;
305 std::ostream& error_stream)
307 enum class mod_cat_t { UNSET, OBSERVER, MODIFIER };
308 mod_cat_t cat{mod_cat_t::UNSET};
309 for (
auto const& modname : path_seq) {
310 auto const label = stripLabel(modname);
313 error_stream <<
" ERROR: Entry " << modname <<
" in path " << path_name
314 <<
" refers to a module label " <<
label 315 <<
" which is not configured.\n";
318 auto const& mci = it->second;
320 is_observer(mci.moduleType()) ? mod_cat_t::OBSERVER : mod_cat_t::MODIFIER;
321 if (cat == mod_cat_t::UNSET) {
324 if (cat == mod_cat_t::MODIFIER) {
328 <<
"Detected trigger path \"" << path_name
329 <<
"\" which was not found in\n" 330 <<
"parameter \"physics.trigger_paths\". " 331 <<
"Path will be ignored.";
340 <<
"'" << path_name <<
"'" 341 <<
" is configured as an end path but is actually a trigger path.";
343 trigger_path_names.push_back(path_name);
348 mf::LogInfo(
"DeactivatedPath") <<
"Detected end path \"" << path_name
349 <<
"\" which was not found in\n" 350 <<
"parameter \"physics.end_paths\". " 351 <<
"Path will be ignored.";
360 <<
"'" << path_name <<
"'" 361 <<
" is configured as a trigger path but is actually an end path.";
365 }
else if (cat != mtype) {
366 error_stream <<
" ERROR: Entry " << modname <<
" in path " << path_name
368 << (cat == mod_cat_t::OBSERVER ?
" modifier" :
"n observer")
369 <<
" while previous entries in the same path are all " 370 << (cat == mod_cat_t::OBSERVER ?
"observers" :
"modifiers")
374 auto const filtAction = filterAction(modname);
377 error_stream <<
" ERROR: Module " << stripLabel(modname) <<
" in path " 378 << path_name <<
" is" 379 << (cat == mod_cat_t::OBSERVER ?
" an " :
" a ")
381 <<
" and cannot have a '!' or '-' prefix.\n";
384 if (cat == mod_cat_t::MODIFIER) {
390 return (cat == mod_cat_t::OBSERVER);
detail::ModuleConfigInfoMap allModules_
std::unique_ptr< std::set< std::string > > end_paths_config_
ProductDescriptions & productsToProduce_
vstring triggerPathNames_
detail::ModuleConfigInfoMap fillAllModules_()
ModuleType moduleType(std::string const &libspec)
vstring processPathConfigs_()
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::vector< BranchDescription > ProductDescriptions
std::map< ScheduleID, PathsInfo > triggerPathsInfo_
detail::ModuleFactory fact_
bool is_key_to_sequence(std::string const &key) const
bool is_key_to_table(std::string const &key) const
std::unique_ptr< std::set< std::string > > trigger_paths_config_
std::vector< std::string > vstring
ActionTable & exceptActions_
T get(std::string const &key) const
bool get_if_present(std::string const &key, T &value) const
std::map< std::string, ModInfos > protoTrigPathMap_
MasterProductRegistry & preg_
PathsInfo & endPathInfo()
PathsInfo & triggerPathsInfo(ScheduleID sID)
static std::vector< std::string > const & allModulePathRoots()
bool is_observer(ModuleType mt)
bool processOnePathConfig_(std::string const &path_name, vstring const &path_seq, vstring &trigger_path_names, std::ostream &error_stream)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
void makeAndAppendPath(std::string const &pathName, ModInfos const &modInfos, bool trigResultsNeeded=true)
std::vector< std::string > get_names() const
PathManager(PathManager const &)=delete
ModInfos protoEndPathInfo_
std::string to_string(ModuleType mt)
fhicl::ParameterSet procPS_
PathPtrs const & pathPtrs() const
cet::coded_exception< error, detail::translate > exception
std::map< std::string, ModuleConfigInfo > ModuleConfigInfoMap