Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 09:14:46

0001 
0002 // Copyright 2020, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 #include "JMain.h"
0006 
0007 #include <JANA/CLI/JBenchmarker.h>
0008 #include <JANA/CLI/JSignalHandler.h>
0009 
0010 
0011 namespace jana {
0012 
0013 void PrintUsage() {
0014     /// Prints jana.cc command-line options to stdout, for use by the CLI.
0015     /// This does not include JANA parameters, which come from
0016     /// JParameterManager::PrintParameters() instead.
0017 
0018     std::cout << std::endl;
0019     std::cout << "Usage:" << std::endl;
0020     std::cout << "    jana [options] source1 source2 ..." << std::endl << std::endl;
0021 
0022     std::cout << "Description:" << std::endl;
0023     std::cout << "    Command-line interface for running JANA plugins. This can be used to" << std::endl;
0024     std::cout << "    read in events and process them. Command-line flags control configuration" << std::endl;
0025     std::cout << "    while additional arguments denote input files, which are to be loaded and" << std::endl;
0026     std::cout << "    processed by the appropriate EventSource plugin." << std::endl << std::endl;
0027 
0028     std::cout << "Options:" << std::endl;
0029     std::cout << "   -h   --help                  Display this message" << std::endl;
0030     PrintUsageOptions();
0031     std::cout << "Example:" << std::endl;
0032     std::cout << "    jana -Pplugins=plugin1,plugin2,plugin3 -Pnthreads=8 inputfile1.txt" << std::endl << std::endl;
0033 
0034 }
0035 
0036 void PrintUsageOptions() {
0037     std::cout << "   -Pkey=value                        Specify a configuration parameter" << std::endl << std::endl;
0038     std::cout << "   -v   --version                     Display version information" << std::endl;
0039     std::cout << "   -c   --configs                     Display configuration parameters" << std::endl;
0040     std::cout << "   -l   --loadconfigs <file>          Load configuration parameters from file" << std::endl;
0041     std::cout << "   -d   --dumpconfigs <file>          Dump configuration parameters to file" << std::endl;
0042     std::cout << "   -b   --benchmark                   Run in benchmark mode" << std::endl;
0043     std::cout << "        --inspect-collection <name>   Inspect a collection" << std::endl;
0044     std::cout << "        --inspect-component <name>    Inspect a component" << std::endl;
0045 }
0046 
0047 
0048 JApplication* CreateJApplication(UserOptions& options) {
0049 
0050     auto params = new JParameterManager(); // JApplication owns params_copy, does not own eventSources
0051     for (auto pair : options.params) {
0052         params->SetParameter(pair.first, pair.second);
0053     }
0054 
0055     if (options.flags[LoadConfigs]) {
0056         // If the user specified an external config file, we should definitely use that
0057         try {
0058             params->ReadConfigFile(options.load_config_file);
0059         }
0060         catch (JException &e) {
0061             std::cout << "Problem loading config file '" << options.load_config_file << "'. Exiting." << std::endl
0062                       << std::endl;
0063             exit(-1);
0064         }
0065         std::cout << "Loaded config file '" << options.load_config_file << "'." << std::endl << std::endl;
0066     }
0067 
0068     auto app = new JApplication(params);
0069 
0070     for (auto event_src : options.eventSources) {
0071         app->Add(event_src);
0072     }
0073     return app;
0074 }
0075 
0076 int Execute(JApplication* app, UserOptions &options) {
0077 
0078     JSignalHandler::register_handlers(app);
0079 
0080     if (options.flags[ShowConfigs]) {
0081         // Load all plugins, collect all parameters, exit without running anything
0082         app->Initialize();
0083         if (options.flags[Benchmark]) {
0084             JBenchmarker benchmarker(app);  // Show benchmarking configs only if benchmarking mode specified
0085         }
0086         app->GetJParameterManager()->PrintParameters(2, 1);
0087     }
0088     else if (options.flags[DumpConfigs]) {
0089         // Load all plugins, dump parameters to file, exit without running anything
0090         app->Initialize();
0091         std::cout << std::endl << "Writing configuration options to file: " << options.dump_config_file
0092                   << std::endl;
0093         app->GetJParameterManager()->WriteConfigFile(options.dump_config_file);
0094     }
0095     else if (options.flags[InspectCollection]) {
0096         app->Initialize();
0097         const auto& summary = app->GetComponentSummary();
0098         std::cout << "----------------------------------------------------------" << std::endl;
0099         if (options.collection_query.empty()) {
0100             PrintCollectionTable(std::cout, summary);
0101         }
0102         else {
0103             auto lookup = summary.FindCollections(options.collection_query);
0104             std::cout << "Collection query: '" << options.collection_query << "'" << std::endl;
0105             if (lookup.empty()) {
0106                 std::cout << "Collection not found!" << std::endl;
0107             }
0108             else {
0109                 std::cout << "----------------------------------------------------------" << std::endl;
0110                 for (auto* item : lookup) {
0111                     std::cout << *item;
0112                     std::cout << "----------------------------------------------------------" << std::endl;
0113                 }
0114             }
0115         }
0116     }
0117     else if (options.flags[InspectComponent]) {
0118         app->Initialize();
0119         const auto& summary = app->GetComponentSummary();
0120         std::cout << "----------------------------------------------------------" << std::endl;
0121         if (options.component_query.empty()) {
0122             PrintComponentTable(std::cout, summary);
0123         }
0124         else {
0125             auto lookup = summary.FindComponents(options.component_query);
0126             std::cout << "Component query: '" << options.component_query << "'" << std::endl;
0127             if (lookup.empty()) {
0128                 std::cout << "Component not found!" << std::endl;
0129             }
0130             else {
0131                 std::cout << "----------------------------------------------------------" << std::endl;
0132                 for (auto* item : lookup) {
0133                     std::cout << *item;
0134                     std::cout << "----------------------------------------------------------" << std::endl;
0135                 }
0136             }
0137         }
0138     }
0139     else if (options.flags[Benchmark]) {
0140         // Run JANA in benchmark mode
0141         JBenchmarker benchmarker(app); // Benchmarking params override default params
0142         benchmarker.RunUntilFinished(); // Benchmarker will control JApp Run/Stop
0143     }
0144     else {
0145         // Run JANA in normal mode
0146         try {
0147             app->Run(true, true);
0148         }
0149         catch (JException& e) {
0150             std::cout << "----------------------------------------------------------" << std::endl;
0151             std::cout << e << std::endl;
0152             app->SetExitCode((int) JApplication::ExitCode::UnhandledException);
0153         }
0154         catch (std::exception& e) {
0155             std::cout << "----------------------------------------------------------" << std::endl;
0156             std::cout << "Exception: " << e.what() << std::endl;
0157             app->SetExitCode((int) JApplication::ExitCode::UnhandledException);
0158         }
0159         catch (...) {
0160             std::cout << "----------------------------------------------------------" << std::endl;
0161             std::cout << "Unknown exception" << std::endl;
0162             app->SetExitCode((int) JApplication::ExitCode::UnhandledException);
0163         }
0164     }
0165     return (int) app->GetExitCode();
0166 }
0167 
0168 
0169 UserOptions ParseCommandLineOptions(int nargs, char *argv[], bool expect_extra) {
0170 
0171     UserOptions options;
0172 
0173     std::map<std::string, Flag> tokenizer;
0174     tokenizer["-h"] = ShowUsage;
0175     tokenizer["--help"] = ShowUsage;
0176     tokenizer["-v"] = ShowVersion;
0177     tokenizer["--version"] = ShowVersion;
0178     tokenizer["-c"] = ShowConfigs;
0179     tokenizer["--configs"] = ShowConfigs;
0180     tokenizer["-l"] = LoadConfigs;
0181     tokenizer["--loadconfigs"] = LoadConfigs;
0182     tokenizer["-d"] = DumpConfigs;
0183     tokenizer["--dumpconfigs"] = DumpConfigs;
0184     tokenizer["-b"] = Benchmark;
0185     tokenizer["--benchmark"] = Benchmark;
0186     tokenizer["--inspect-collection"] = InspectCollection;
0187     tokenizer["--inspect-component"] = InspectComponent;
0188 
0189     if (nargs == 1) {
0190         options.flags[ShowUsage] = true;
0191     }
0192 
0193     for (int i = 1; i < nargs; i++) {
0194 
0195         std::string arg = argv[i];
0196         //std::cout << "Found arg " << arg << std::endl;
0197 
0198         if (argv[i][0] != '-') {
0199             options.eventSources.push_back(arg);
0200             continue;
0201         }
0202 
0203         switch (tokenizer[arg]) {
0204 
0205             case Benchmark:
0206                 options.flags[Benchmark] = true;
0207                 break;
0208 
0209             case ShowUsage:
0210                 options.flags[ShowUsage] = true;
0211                 break;
0212 
0213             case ShowVersion:
0214                 options.flags[ShowVersion] = true;
0215                 break;
0216 
0217             case ShowConfigs:
0218                 options.flags[ShowConfigs] = true;
0219                 break;
0220 
0221             case LoadConfigs:
0222                 options.flags[LoadConfigs] = true;
0223                 if (i + 1 < nargs && argv[i + 1][0] != '-') {
0224                     options.load_config_file = argv[i + 1];
0225                     i += 1;
0226                 } else {
0227                     options.load_config_file = "jana.config";
0228                 }
0229                 break;
0230 
0231             case DumpConfigs:
0232                 options.flags[DumpConfigs] = true;
0233                 if (i + 1 < nargs && argv[i + 1][0] != '-') {
0234                     options.dump_config_file = argv[i + 1];
0235                     i += 1;
0236                 } else {
0237                     options.dump_config_file = "jana.config";
0238                 }
0239                 break;
0240  
0241             case InspectCollection:
0242                 options.flags[InspectCollection] = true;
0243                 if (i + 1 < nargs && argv[i + 1][0] != '-') {
0244                     options.collection_query = argv[i + 1];
0245                     i += 1;
0246                 } 
0247                 break;
0248 
0249             case InspectComponent:
0250                 options.flags[InspectComponent] = true;
0251                 if (i + 1 < nargs && argv[i + 1][0] != '-') {
0252                     options.component_query = argv[i + 1];
0253                     i += 1;
0254                 } 
0255                 break;
0256 
0257             case Interactive:
0258                 options.flags[Interactive] = true;
0259                 break;
0260 
0261             case Unknown:
0262                 if (argv[i][0] == '-' && argv[i][1] == 'P') {
0263 
0264                     size_t pos = arg.find("=");
0265                     if ((pos != std::string::npos) && (pos > 2)) {
0266                         std::string key = arg.substr(2, pos - 2);
0267                         std::string val = arg.substr(pos + 1);
0268                         options.params.insert({key, val});
0269                     } else {
0270                         std::cout << "Invalid JANA parameter '" << arg
0271                                   << "': Expected format -Pkey=value" << std::endl;
0272                         options.flags[ShowConfigs] = true;
0273                     }
0274                 } else {
0275                     if (!expect_extra) {
0276                         std::cout << "Invalid command line flag '" << arg << "'" << std::endl;
0277                         options.flags[ShowUsage] = true;
0278                     }
0279                 }
0280         }
0281     }
0282     return options;
0283 }
0284 }