10 #include "cetlib/canonical_string.h" 33 bpo::options_description& desc)
35 bpo::options_description output_options{
"Output options"};
36 auto options = output_options.add_options();
39 bpo::value<std::string>(),
40 "File name for TFileService.");
44 bpo::value<std::string>(&tmpDir_),
45 "Temporary directory for in-progress output files (defaults to directory " 46 "of specified output file names).");
49 bpo::value<std::string>(&tmpDir_),
50 "Synonym for --tmpdir.");
53 bpo::value<stringvec>()->composing(),
54 "Event output stream file (optionally specify stream with " 55 "stream-label:fileName in which case multiples are OK).");
56 add_opt(options,
"no-output",
"Disable all output streams.");
57 desc.add(output_options);
74 std::string
const& pathName,
75 std::string
const& key)
80 auto path_end = std::remove_if(
84 if (path_end != path.end()) {
85 path.resize(std::distance(path.begin(), path_end));
97 std::string
const& key)
99 std::string
const& physicsKey{
"physics"};
103 auto& physics_table(raw_config.
get<
table_t&>(physicsKey));
104 std::vector<std::string>
const ignoredParameters(
105 {
"analyzers",
"filters",
"producers",
"end_paths",
"trigger_paths"});
106 auto i = physics_table.begin();
107 auto e = physics_table.end();
109 if (std::find(ignoredParameters.cbegin(),
110 ignoredParameters.cend(),
111 i->first) == ignoredParameters.end() &&
113 maybeRemoveFromPath(raw_config, physicsKey +
'.' + i->first, key)) {
115 maybeRemoveFromPath(raw_config, physicsKey +
".end_paths", i->first);
117 i = physics_table.erase(i);
128 auto const b = outputs.begin(),
e = outputs.end();
129 for (
auto i = b; i !=
e; ++i) {
131 bool new_path_entry(
false);
132 auto const outputsKey =
"outputs"s;
135 auto& outputs_table(raw_config.
get<
table_t&>(outputsKey));
136 std::smatch splitResult;
137 static std::regex
const streamSplitter(
"([[:alnum:]]+):(?:/[^/]|[^/]).*");
138 std::string streamName;
139 if (std::regex_match(output, splitResult, streamSplitter)) {
140 streamName = splitResult[1];
141 output.erase(0ull, streamName.size() + 1ull);
144 <<
"While processing specified output " << output
145 <<
": only the first specified output may omit the stream " 147 "(\"label:fileName\").\n";
148 }
else if (outputs_table.size() == 1ull) {
149 streamName = outputs_table.cbegin()->first;
154 if (outputs_table.size() > 1ull && splitResult.empty()) {
156 <<
"Output configuration is ambiguous: configuration has " 157 <<
"multiple output modules. Cannot decide where to add " 158 <<
"specified output filename " << output
159 <<
".\nUse stream-specification (\"label:fileName\") to resolve the " 163 if (outputs_table.find(streamName) == outputs_table.cend()) {
164 new_path_entry =
true;
165 raw_config.
put(outputsKey +
'.' + streamName +
'.' +
"module_type",
168 std::string out_table_path(outputsKey);
169 out_table_path +=
'.' + streamName;
170 raw_config.
put(out_table_path +
".fileName", output);
171 if (new_path_entry) {
177 auto& physics_table = raw_config.
get<
table_t&>(
"physics");
180 std::string end_path =
"injected_end_path_";
181 size_t n = physics_table.size() + 2;
182 for (
size_t i = 1; i <
n; ++i) {
183 std::ostringstream os;
185 if (physics_table.find(os.str()) == physics_table.end()) {
191 raw_config.
put(
"physics."s + end_path +
"[0]", streamName);
193 auto const key =
"physics.end_paths"s;
205 processFileOutputOptions(bpo::variables_map
const& vm,
209 if (vm.count(
"no-output") == 1) {
210 if (vm.count(
"output")) {
212 <<
"Output configuration is ambiguous: command-line specifies " 213 <<
"--output and --no-output simultaneously.";
215 std::string
const& key{
"outputs"};
217 auto& outputs_table(raw_config.
get<
table_t&>(key));
219 for (
auto const& p : outputs_table) {
220 removeFromEndPaths(raw_config, p.first);
222 raw_config.
erase(key);
224 }
else if (vm.count(
"output") == 1) {
225 processSpecifiedOutputs(raw_config, vm[
"output"].as<stringvec>());
229 struct RootErrorHandlerSentry {
230 RootErrorHandlerSentry(
bool const reset)
234 ~RootErrorHandlerSentry() { SetErrorHandler(DefaultErrorHandler); }
241 bpo::variables_map
const& vm,
245 if (vm.count(
"TFileName") == 1) {
246 std::string tFileName(vm[
"TFileName"].as<std::string>());
247 std::string
const& key{
"services.TFileService"};
249 raw_config.
get<
table_t const&>(key).empty()) {
250 tFileName =
"hist.root";
252 if (!tFileName.empty()) {
253 raw_config.
put(key +
".fileName", tFileName);
257 processFileOutputOptions(vm, raw_config);
259 if (!tmpDir_.empty()) {
260 std::string
const& tfile_key =
fhicl_key(
"services",
"TFileService");
264 raw_config.
put(
fhicl_key(tfile_key,
"tmpDir"), tmpDir_);
268 std::string
const outputs_stem{
"outputs"};
270 auto const& table = raw_config.
get<
table_t const&>(outputs_stem);
271 for (
auto const& output : table) {
272 auto const& module_label =
fhicl_key(outputs_stem, output.first);
273 auto const& module_type =
fhicl_key(module_label,
"module_type");
277 auto const& spec = raw_config.
get<std::string>(module_type);
281 raw_config.
put(
fhicl_key(module_label,
"tmpDir"), tmpDir_);
287 auto const unload_key =
fhicl_key(
"scheduler",
"unloadRootSigHandler");
288 auto const unloadRSHandler =
290 raw_config.
get<
bool>(unload_key) :
292 if (unloadRSHandler) {
296 auto const reset_key =
fhicl_key(
"scheduler",
"resetRootErrHandler");
297 auto const maybe_reset =
299 raw_config.
get<
bool>(reset_key) :
301 RootErrorHandlerSentry re_sentry{maybe_reset};
bool exists_outside_prolog(fhicl::intermediate_table const &config, std::string const &key)
void add_opt(T &t, Args &&...args)
void unloadRootSigHandler()
BasicOutputOptionsHandler(bpo::options_description &desc)
void ensureTable(fhicl::intermediate_table &table, std::string const &fhicl_spec)
std::vector< std::string > stringvec
int doCheckOptions(bpo::variables_map const &vm) override
std::vector< extended_value > sequence_t
shims::map< std::string, extended_value > table_t
void setRootErrorHandler(bool const want_custom)
std::enable_if_t< std::is_convertible< T, std::string >::value, std::string > fhicl_key(T const &name)
fhicl::extended_value::sequence_t sequence_t
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
void completeRootHandlers()
bool supports_key(suffix_type st, std::string const &spec, std::string const &key)
int doProcessOptions(bpo::variables_map const &vm, fhicl::intermediate_table &raw_config) override