Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:32

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 << "   -i   --interactive                 Run in interactive mode" << std::endl;
0044     std::cout << "        --inspect-collection <name>   Inspect a collection" << std::endl;
0045     std::cout << "        --inspect-component <name>    Inspect a component" << std::endl;
0046 }
0047 
0048 
0049 JApplication* CreateJApplication(UserOptions& options) {
0050 
0051     auto params = new JParameterManager(); // JApplication owns params_copy, does not own eventSources
0052     for (auto pair : options.params) {
0053         params->SetParameter(pair.first, pair.second);
0054     }
0055 
0056     if (options.flags[LoadConfigs]) {
0057         // If the user specified an external config file, we should definitely use that
0058         try {
0059             params->ReadConfigFile(options.load_config_file);
0060         }
0061         catch (JException &e) {
0062             std::cout << "Problem loading config file '" << options.load_config_file << "'. Exiting." << std::endl
0063                       << std::endl;
0064             exit(-1);
0065         }
0066         std::cout << "Loaded config file '" << options.load_config_file << "'." << std::endl << std::endl;
0067     }
0068 
0069     auto app = new JApplication(params);
0070 
0071     for (auto event_src : options.eventSources) {
0072         app->Add(event_src);
0073     }
0074     return app;
0075 }
0076 
0077 int Execute(JApplication* app, UserOptions &options) {
0078 
0079     JSignalHandler::register_handlers(app);
0080 
0081     if (options.flags[ShowConfigs]) {
0082         // Load all plugins, collect all parameters, exit without running anything
0083         app->Initialize();
0084         if (options.flags[Benchmark]) {
0085             JBenchmarker benchmarker(app);  // Show benchmarking configs only if benchmarking mode specified
0086         }
0087         app->GetJParameterManager()->PrintParameters(2, 1);
0088     }
0089     else if (options.flags[DumpConfigs]) {
0090         // Load all plugins, dump parameters to file, exit without running anything
0091         app->Initialize();
0092         std::cout << std::endl << "Writing configuration options to file: " << options.dump_config_file
0093                   << std::endl;
0094         app->GetJParameterManager()->WriteConfigFile(options.dump_config_file);
0095     }
0096     else if (options.flags[InspectCollection]) {
0097         app->Initialize();
0098         const auto& summary = app->GetComponentSummary();
0099         std::cout << "----------------------------------------------------------" << std::endl;
0100         if (options.collection_query.empty()) {
0101             PrintCollectionTable(std::cout, summary);
0102         }
0103         else {
0104             auto lookup = summary.FindCollections(options.collection_query);
0105             std::cout << "Collection query: '" << options.collection_query << "'" << std::endl;
0106             if (lookup.empty()) {
0107                 std::cout << "Collection not found!" << std::endl;
0108             }
0109             else {
0110                 std::cout << "----------------------------------------------------------" << std::endl;
0111                 for (auto* item : lookup) {
0112                     std::cout << *item;
0113                     std::cout << "----------------------------------------------------------" << std::endl;
0114                 }
0115             }
0116         }
0117     }
0118     else if (options.flags[InspectComponent]) {
0119         app->Initialize();
0120         const auto& summary = app->GetComponentSummary();
0121         std::cout << "----------------------------------------------------------" << std::endl;
0122         if (options.component_query.empty()) {
0123             PrintComponentTable(std::cout, summary);
0124         }
0125         else {
0126             auto lookup = summary.FindComponents(options.component_query);
0127             std::cout << "Component query: '" << options.component_query << "'" << std::endl;
0128             if (lookup.empty()) {
0129                 std::cout << "Component not found!" << std::endl;
0130             }
0131             else {
0132                 std::cout << "----------------------------------------------------------" << std::endl;
0133                 for (auto* item : lookup) {
0134                     std::cout << *item;
0135                     std::cout << "----------------------------------------------------------" << std::endl;
0136                 }
0137             }
0138         }
0139     }
0140     else if (options.flags[Interactive]) {
0141         app->Initialize();
0142         app->Inspect();
0143         // TODO: Resume and Scale won't work because Inspector calls nonblocking Run()
0144         //       Another thing we could do is app->RequestInspection(); app->Run(true);
0145         //       as long as we rejigger app->Run() to jump straight to Inspect() when m_inspecting is set
0146         //       Or we could wait until we factor out Run() into JSupervisor
0147     }
0148     else if (options.flags[Benchmark]) {
0149         // Run JANA in benchmark mode
0150         JBenchmarker benchmarker(app); // Benchmarking params override default params
0151         benchmarker.RunUntilFinished(); // Benchmarker will control JApp Run/Stop
0152     }
0153     else {
0154         // Run JANA in normal mode
0155         try {
0156             app->Run(true, true);
0157         }
0158         catch (JException& e) {
0159             std::cout << "----------------------------------------------------------" << std::endl;
0160             std::cout << e << std::endl;
0161             app->SetExitCode((int) JApplication::ExitCode::UnhandledException);
0162         }
0163         catch (std::exception& e) {
0164             std::cout << "----------------------------------------------------------" << std::endl;
0165             std::cout << "Exception: " << e.what() << std::endl;
0166             app->SetExitCode((int) JApplication::ExitCode::UnhandledException);
0167         }
0168         catch (...) {
0169             std::cout << "----------------------------------------------------------" << std::endl;
0170             std::cout << "Unknown exception" << std::endl;
0171             app->SetExitCode((int) JApplication::ExitCode::UnhandledException);
0172         }
0173     }
0174     return (int) app->GetExitCode();
0175 }
0176 
0177 
0178 UserOptions ParseCommandLineOptions(int nargs, char *argv[], bool expect_extra) {
0179 
0180     UserOptions options;
0181 
0182     std::map<std::string, Flag> tokenizer;
0183     tokenizer["-h"] = ShowUsage;
0184     tokenizer["--help"] = ShowUsage;
0185     tokenizer["-v"] = ShowVersion;
0186     tokenizer["--version"] = ShowVersion;
0187     tokenizer["-c"] = ShowConfigs;
0188     tokenizer["--configs"] = ShowConfigs;
0189     tokenizer["-l"] = LoadConfigs;
0190     tokenizer["--loadconfigs"] = LoadConfigs;
0191     tokenizer["-d"] = DumpConfigs;
0192     tokenizer["--dumpconfigs"] = DumpConfigs;
0193     tokenizer["-b"] = Benchmark;
0194     tokenizer["--benchmark"] = Benchmark;
0195     tokenizer["-i"] = Interactive;
0196     tokenizer["--interactive"] = Interactive;
0197     tokenizer["--inspect-collection"] = InspectCollection;
0198     tokenizer["--inspect-component"] = InspectComponent;
0199 
0200     if (nargs == 1) {
0201         options.flags[ShowUsage] = true;
0202     }
0203 
0204     for (int i = 1; i < nargs; i++) {
0205 
0206         std::string arg = argv[i];
0207         //std::cout << "Found arg " << arg << std::endl;
0208 
0209         if (argv[i][0] != '-') {
0210             options.eventSources.push_back(arg);
0211             continue;
0212         }
0213 
0214         switch (tokenizer[arg]) {
0215 
0216             case Benchmark:
0217                 options.flags[Benchmark] = true;
0218                 break;
0219 
0220             case ShowUsage:
0221                 options.flags[ShowUsage] = true;
0222                 break;
0223 
0224             case ShowVersion:
0225                 options.flags[ShowVersion] = true;
0226                 break;
0227 
0228             case ShowConfigs:
0229                 options.flags[ShowConfigs] = true;
0230                 break;
0231 
0232             case LoadConfigs:
0233                 options.flags[LoadConfigs] = true;
0234                 if (i + 1 < nargs && argv[i + 1][0] != '-') {
0235                     options.load_config_file = argv[i + 1];
0236                     i += 1;
0237                 } else {
0238                     options.load_config_file = "jana.config";
0239                 }
0240                 break;
0241 
0242             case DumpConfigs:
0243                 options.flags[DumpConfigs] = true;
0244                 if (i + 1 < nargs && argv[i + 1][0] != '-') {
0245                     options.dump_config_file = argv[i + 1];
0246                     i += 1;
0247                 } else {
0248                     options.dump_config_file = "jana.config";
0249                 }
0250                 break;
0251  
0252             case InspectCollection:
0253                 options.flags[InspectCollection] = true;
0254                 if (i + 1 < nargs && argv[i + 1][0] != '-') {
0255                     options.collection_query = argv[i + 1];
0256                     i += 1;
0257                 } 
0258                 break;
0259 
0260             case InspectComponent:
0261                 options.flags[InspectComponent] = true;
0262                 if (i + 1 < nargs && argv[i + 1][0] != '-') {
0263                     options.component_query = argv[i + 1];
0264                     i += 1;
0265                 } 
0266                 break;
0267 
0268             case Interactive:
0269                 options.flags[Interactive] = true;
0270                 break;
0271 
0272             case Unknown:
0273                 if (argv[i][0] == '-' && argv[i][1] == 'P') {
0274 
0275                     size_t pos = arg.find("=");
0276                     if ((pos != std::string::npos) && (pos > 2)) {
0277                         std::string key = arg.substr(2, pos - 2);
0278                         std::string val = arg.substr(pos + 1);
0279                         options.params.insert({key, val});
0280                     } else {
0281                         std::cout << "Invalid JANA parameter '" << arg
0282                                   << "': Expected format -Pkey=value" << std::endl;
0283                         options.flags[ShowConfigs] = true;
0284                     }
0285                 } else {
0286                     if (!expect_extra) {
0287                         std::cout << "Invalid command line flag '" << arg << "'" << std::endl;
0288                         options.flags[ShowUsage] = true;
0289                     }
0290                 }
0291         }
0292     }
0293     return options;
0294 }
0295 }