Line data Source code
1 : #ifndef artdaq_proto_LoadParameterSet_hh
2 : #define artdaq_proto_LoadParameterSet_hh 1
3 :
4 : // note: in header files (this LoadParameterSet.hh) consider if you want TRACE/LOG to use "name" from .cc or name for this file
5 : #include "TRACE/tracemf.h"
6 :
7 : #include "fhiclcpp/ParameterSet.h"
8 : #include "fhiclcpp/types/Name.h"
9 : #include "fhiclcpp/types/Table.h"
10 :
11 : #include "cetlib/filepath_maker.h"
12 :
13 : #include <boost/program_options.hpp>
14 : namespace bpo = boost::program_options;
15 :
16 : #include <iostream>
17 : #include <sstream>
18 : #include <string>
19 :
20 : /**
21 : * \brief Load a FHiCL ParameterSet from a string or file
22 : * \param psetOrFile A FHiCL string or a path to a FHiCL file
23 : * \return The parsed fhicl::ParameterSet
24 : */
25 3 : inline fhicl::ParameterSet LoadParameterSet(std::string const& psetOrFile)
26 : {
27 3 : fhicl::ParameterSet pset;
28 :
29 : try
30 : {
31 3 : pset = fhicl::ParameterSet::make(psetOrFile);
32 : }
33 3 : catch (const fhicl::exception& e)
34 : {
35 3 : if (getenv("FHICL_FILE_PATH") == nullptr)
36 0 : setenv("FHICL_FILE_PATH", ".", 0);
37 3 : cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
38 3 : pset = fhicl::ParameterSet::make(psetOrFile, lookup_policy);
39 3 : }
40 :
41 3 : return pset;
42 0 : }
43 :
44 : /**
45 : * \brief Print the allowed configuration for a given FHiCL table type to the console
46 : * \tparam C The FHiCL table configuration type
47 : * \param name Name of the top-level FHiCL table
48 : */
49 : template<typename C>
50 : void PrintConfigurationToConsole(std::string const& name)
51 : {
52 : fhicl::Table<C> config_description(fhicl::Name{name});
53 : config_description.print_allowed_configuration(std::cout);
54 : }
55 :
56 : /**
57 : * \brief Load a FHiCL ParameterSet from command-line arguments
58 : * \tparam C The FHiCL table configuration type used for validation and help output
59 : * \param argc Argument count from main()
60 : * \param argv Argument vector from main()
61 : * \param name Name of the top-level FHiCL table key to extract from the configuration
62 : * \param description Description of the application, printed with --help
63 : * \return The parsed fhicl::ParameterSet for the named table
64 : */
65 : template<typename C>
66 3 : inline fhicl::ParameterSet LoadParameterSet(int argc, char* argv[], std::string const& name, std::string const& description)
67 : {
68 3 : std::ostringstream descstr;
69 : descstr << argv[0] // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
70 3 : << " <-c <config>> <other-options> [<source-file>]+";
71 3 : bpo::options_description desc(descstr.str());
72 3 : desc.add_options()("config,c", bpo::value<std::string>(), "Configuration")("help,h", "produce help message");
73 3 : bpo::variables_map vm;
74 : try
75 : {
76 3 : bpo::store(bpo::command_line_parser(argc, argv).options(desc).run(), vm);
77 3 : bpo::notify(vm);
78 : }
79 0 : catch (bpo::error const& e)
80 : {
81 0 : TLOG_ERROR("LoadParameterSet") << "Exception from command line processing in " << argv[0] // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
82 0 : << ": " << e.what() << "\n";
83 0 : exit(-1);
84 : }
85 6 : if (vm.count("help"))
86 : {
87 0 : std::cout << desc << std::endl;
88 0 : std::cout << description << std::endl;
89 0 : std::cout << "Sample FHiCL configuration for this application: " << std::endl;
90 0 : fhicl::Table<C> config_description(fhicl::Name{name});
91 0 : config_description.print_allowed_configuration(std::cout);
92 0 : exit(1);
93 0 : }
94 :
95 3 : fhicl::ParameterSet pset;
96 :
97 6 : if (vm.count("config"))
98 : {
99 3 : std::string config = vm["config"].as<std::string>();
100 :
101 3 : if (config == "-" || config == "--")
102 : {
103 0 : TLOG_ERROR("LoadParameterSet") << "Reading configuration from standard input. Press Ctrl-D to end" << std::endl;
104 0 : std::stringstream ss;
105 0 : std::string line;
106 0 : while (std::getline(std::cin, line))
107 : {
108 0 : ss << line << std::endl;
109 : }
110 0 : std::cin.clear();
111 :
112 0 : pset = fhicl::ParameterSet::make(ss.str());
113 0 : }
114 : else
115 : {
116 6 : TLOG(TLVL_DEBUG + 32, "LoadParameterSet") << config << std::endl;
117 3 : auto pset_tmp = LoadParameterSet(config);
118 3 : if (pset_tmp.has_key(name)) { pset = pset_tmp.get<fhicl::ParameterSet>(name); }
119 : else
120 : {
121 3 : pset = pset_tmp;
122 : }
123 3 : }
124 3 : }
125 : else
126 : {
127 0 : TLOG_ERROR("LoadParameterSet") << "Exception from command line processing in " << argv[0] // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
128 0 : << ": no configuration given.\n"
129 0 : << "For usage and an options list, please do '"
130 0 : << argv[0] << " --help" // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
131 0 : << "'.\n";
132 0 : exit(2);
133 : }
134 6 : return pset;
135 3 : }
136 : #endif // artdaq_proto_LoadParameterSet_hh
|