10 #include "cetlib/canonical_string.h" 29 bpo::options_description& desc)
31 bpo::options_description output_options{
"Output options"};
33 output_options.add_options()
34 (
"TFileName,T", bpo::value<std::string>(),
"File name for TFileService.")
36 bpo::value<std::string>(&tmpDir_),
37 "Temporary directory for in-progress output files (defaults to directory " 38 "of specified output file names).")
39 (
"tmpDir", bpo::value<std::string>(&tmpDir_),
"Synonym for --tmpdir.")
41 bpo::value<stringvec>()->composing(),
42 "Event output stream file (optionally specify stream with " 43 "stream-label:fileName in which case multiples are OK).")
44 (
"no-output",
"Disable all output streams.");
46 desc.add(output_options);
63 std::string
const& pathName,
64 std::string
const& key)
69 auto path_end = std::remove_if(
73 if (path_end != path.end()) {
74 path.resize(std::distance(path.begin(), path_end));
86 std::string
const& key)
88 std::string
const& physicsKey{
"physics"};
92 auto& physics_table(raw_config.
get<
table_t&>(physicsKey));
93 std::vector<std::string>
const ignoredParameters(
94 {
"analyzers",
"filters",
"producers",
"end_paths",
"trigger_paths"});
95 auto i = physics_table.begin();
96 auto e = physics_table.end();
98 if (std::find(ignoredParameters.cbegin(),
99 ignoredParameters.cend(),
100 i->first) == ignoredParameters.end() &&
102 maybeRemoveFromPath(raw_config, physicsKey +
'.' + i->first, key)) {
104 maybeRemoveFromPath(raw_config, physicsKey +
".end_paths", i->first);
106 i = physics_table.erase(i);
117 auto const b = outputs.begin(),
e = outputs.end();
118 for (
auto i = b; i !=
e; ++i) {
120 bool new_path_entry(
false);
121 auto const outputsKey =
"outputs"s;
124 auto& outputs_table(raw_config.
get<
table_t&>(outputsKey));
125 std::smatch splitResult;
126 static std::regex
const streamSplitter(
"([[:alnum:]]+):(?:/[^/]|[^/]).*");
127 std::string streamName;
128 if (std::regex_match(output, splitResult, streamSplitter)) {
129 streamName = splitResult[1];
130 output.erase(0ull, streamName.size() + 1ull);
133 <<
"While processing specified output " << output
134 <<
": only the first specified output may omit the stream " 136 "(\"label:fileName\").\n";
137 }
else if (outputs_table.size() == 1ull) {
138 streamName = outputs_table.cbegin()->first;
143 if (outputs_table.size() > 1ull && splitResult.empty()) {
145 <<
"Output configuration is ambiguous: configuration has " 146 <<
"multiple output modules. Cannot decide where to add " 147 <<
"specified output filename " << output
148 <<
".\nUse stream-specification (\"label:fileName\") to resolve the " 152 if (outputs_table.find(streamName) == outputs_table.cend()) {
153 new_path_entry =
true;
154 std::string
const defaultOutputModule =
160 raw_config.
put(outputsKey +
'.' + streamName +
'.' +
"module_type",
161 defaultOutputModule);
163 std::string out_table_path(outputsKey);
164 out_table_path +=
'.' + streamName;
165 raw_config.
put(out_table_path +
".fileName", output);
166 if (new_path_entry) {
172 auto& physics_table = raw_config.
get<
table_t&>(
"physics");
175 std::string end_path =
"injected_end_path_";
176 size_t n = physics_table.size() + 2;
177 for (
size_t i = 1; i <
n; ++i) {
178 std::ostringstream os;
180 if (physics_table.find(os.str()) == physics_table.end()) {
186 raw_config.
put(
"physics."s + end_path +
"[0]", streamName);
188 auto const key =
"physics.end_paths"s;
200 processFileOutputOptions(bpo::variables_map
const& vm,
204 if (vm.count(
"no-output") == 1) {
205 if (vm.count(
"output")) {
207 <<
"Output configuration is ambiguous: command-line specifies " 208 <<
"--output and --no-output simultaneously.";
210 std::string
const& key{
"outputs"};
212 auto& outputs_table(raw_config.
get<
table_t&>(key));
214 for (
auto const& p : outputs_table) {
215 removeFromEndPaths(raw_config, p.first);
217 raw_config.
erase(key);
219 }
else if (vm.count(
"output") == 1) {
220 processSpecifiedOutputs(raw_config, vm[
"output"].as<stringvec>());
227 bpo::variables_map
const& vm,
231 if (vm.count(
"TFileName") == 1) {
232 std::string tFileName(vm[
"TFileName"].as<std::string>());
233 std::string
const& key{
"services.TFileService"};
236 tFileName =
"hist.root";
238 if (!tFileName.empty()) {
239 raw_config.
put(key +
".fileName", tFileName);
243 processFileOutputOptions(vm, raw_config);
245 if (!tmpDir_.empty()) {
246 std::string
const& tfile_key =
fhicl_key(
"services",
"TFileService");
248 auto has_tmpDir [[maybe_unused]] =
251 raw_config.
put(
fhicl_key(tfile_key,
"tmpDir"), tmpDir_);
255 std::string
const outputs_stem{
"outputs"};
257 auto const& table = raw_config.
get<
table_t const&>(outputs_stem);
258 for (
auto const& output : table) {
259 auto const& module_label =
fhicl_key(outputs_stem, output.first);
268 raw_config.
put(
fhicl_key(module_label,
"tmpDir"), tmpDir_);
LibraryInfoCollection get_LibraryInfoCollection(std::string const &suffix, std::string const &pattern, bool verbose=false)
bool exists_outside_prolog(fhicl::intermediate_table const &config, std::string const &key)
bool supports_key(std::string const &suffix, std::string const &spec, std::string const &key)
ModuleType module_type(std::string const &full_key)
BasicOutputOptionsHandler(bpo::options_description &desc)
void ensureTable(fhicl::intermediate_table &table, std::string const &fhicl_spec)
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
std::vector< std::string > stringvec
int doCheckOptions(bpo::variables_map const &vm) override
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
std::enable_if_t< std::is_convertible_v< T, std::string >, std::string > fhicl_key(T const &name)
std::vector< extended_value > sequence_t
shims::map< std::string, extended_value > table_t
fhicl::extended_value::sequence_t sequence_t
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
static std::string const & module()
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
int doProcessOptions(bpo::variables_map const &vm, fhicl::intermediate_table &raw_config) override