|
15 | 15 | #include "TFile.h" |
16 | 16 | #include "TKey.h" |
17 | 17 | #include <iostream> |
| 18 | +#include <boost/program_options.hpp> |
18 | 19 |
|
19 | | -// a simple tool to inspect/print metadata content of ROOT files containing CCDB entries |
| 20 | +namespace bpo = boost::program_options; |
| 21 | + |
| 22 | +bool initOptionsAndParse(bpo::options_description& options, int argc, char* argv[], bpo::variables_map& vm) |
| 23 | +{ |
| 24 | + options.add_options()( |
| 25 | + "files,f", bpo::value<std::vector<std::string>>()->multitoken(), "Space separated list of ROOT files holding (downloaded) CCDB object")( |
| 26 | + "check-timestamp,t", bpo::value<long>()->default_value(-1), "Checks that validity of objects is compatible with this timestamp. In millisecond")( |
| 27 | + "help,h", "Produce help message."); |
| 28 | + |
| 29 | + try { |
| 30 | + bpo::store(parse_command_line(argc, argv, options), vm); |
| 31 | + // help |
| 32 | + if (vm.count("help")) { |
| 33 | + std::cout << options << std::endl; |
| 34 | + return false; |
| 35 | + } |
| 36 | + bpo::notify(vm); |
| 37 | + } catch (const bpo::error& e) { |
| 38 | + std::cerr << e.what() << "\n\n"; |
| 39 | + std::cerr << "Error parsing command line arguments; Available options:\n"; |
| 40 | + |
| 41 | + std::cerr << options << std::endl; |
| 42 | + return false; |
| 43 | + } |
| 44 | + return true; |
| 45 | +} |
| 46 | + |
| 47 | +// A simple tool to inspect/print metadata content of ROOT files containing CCDB entries |
20 | 48 | // TODO: optionally print as JSON |
21 | 49 | int main(int argc, char* argv[]) |
22 | 50 | { |
23 | | - if (argc < 2) { |
24 | | - std::cerr << "Usage: " << argv[0] << " CCDBFile.root \n"; |
| 51 | + bpo::options_description options("Tool to inspect meta-data content of downloaded CCDB objects. Allowed options:"); |
| 52 | + bpo::variables_map vm; |
| 53 | + if (!initOptionsAndParse(options, argc, argv, vm)) { |
| 54 | + return 1; |
25 | 55 | } |
26 | | - TFile file(argv[1]); |
27 | | - |
28 | | - // query the list of objects |
29 | | - auto keys = file.GetListOfKeys(); |
30 | | - if (keys) { |
31 | | - std::cout << "--- found the following objects -----\n"; |
32 | | - for (int i = 0; i < keys->GetEntries(); ++i) { |
33 | | - auto key = static_cast<TKey*>(keys->At(i)); |
34 | | - if (key) { |
35 | | - std::cout << key->GetName() << " of type " << key->GetClassName() << "\n"; |
| 56 | + auto filenames = vm["files"].as<std::vector<std::string>>(); |
| 57 | + auto timestamp2bchecked = vm["check-timestamp"].as<long>(); |
| 58 | + std::vector<std::string> filesWrongValidity; // record files failing validity check |
| 59 | + |
| 60 | + for (auto& f : filenames) { |
| 61 | + std::cout << "### Loading file : " << f << "\n"; |
| 62 | + TFile file(f.c_str()); |
| 63 | + |
| 64 | + // query the list of objects |
| 65 | + auto keys = file.GetListOfKeys(); |
| 66 | + if (keys) { |
| 67 | + std::cout << "--- found the following objects -----\n"; |
| 68 | + for (int i = 0; i < keys->GetEntries(); ++i) { |
| 69 | + auto key = static_cast<TKey*>(keys->At(i)); |
| 70 | + if (key) { |
| 71 | + std::cout << key->GetName() << " of type " << key->GetClassName() << "\n"; |
| 72 | + } |
36 | 73 | } |
| 74 | + } else { |
| 75 | + std::cout << "--- no objects found -----\n"; |
37 | 76 | } |
38 | | - } else { |
39 | | - std::cout << "--- no objects found -----\n"; |
40 | | - } |
41 | 77 |
|
42 | | - auto queryinfo = o2::ccdb::CcdbApi::retrieveQueryInfo(file); |
43 | | - if (queryinfo) { |
44 | | - std::cout << "---found query info -----\n"; |
45 | | - queryinfo->print(); |
46 | | - } else { |
47 | | - std::cout << "--- no query information found ------\n"; |
48 | | - } |
| 78 | + auto queryinfo = o2::ccdb::CcdbApi::retrieveQueryInfo(file); |
| 79 | + if (queryinfo) { |
| 80 | + std::cout << "---found query info -----\n"; |
| 81 | + queryinfo->print(); |
| 82 | + } else { |
| 83 | + std::cout << "--- no query information found ------\n"; |
| 84 | + } |
49 | 85 |
|
50 | | - auto meta = o2::ccdb::CcdbApi::retrieveMetaInfo(file); |
51 | | - if (meta) { |
52 | | - std::cout << "---found meta info -----\n"; |
53 | | - for (auto keyvalue : *meta) { |
54 | | - std::cout << keyvalue.first << " : " << keyvalue.second << "\n"; |
| 86 | + auto meta = o2::ccdb::CcdbApi::retrieveMetaInfo(file); |
| 87 | + if (meta) { |
| 88 | + std::cout << "---found meta info -----\n"; |
| 89 | + for (auto keyvalue : *meta) { |
| 90 | + std::cout << keyvalue.first << " : " << keyvalue.second << "\n"; |
| 91 | + } |
| 92 | + if (timestamp2bchecked > 0) { |
| 93 | + // retrieve Valid-From and Valid-To headers |
| 94 | + try { |
| 95 | + auto valid_from = std::stol((*meta)["Valid-From"]); |
| 96 | + auto valid_to = std::stol((*meta)["Valid-Until"]); |
| 97 | + if (!(valid_from <= timestamp2bchecked) && (timestamp2bchecked <= valid_to)) { |
| 98 | + std::cerr << "### ERROR: failed validity check for timestamp " << timestamp2bchecked << " not in [" << valid_from << ":" << valid_to << "]\n"; |
| 99 | + filesWrongValidity.push_back(f); |
| 100 | + } |
| 101 | + } catch (std::exception e) { |
| 102 | + // no validity could be extracted; |
| 103 | + filesWrongValidity.push_back(f); |
| 104 | + } |
| 105 | + } |
| 106 | + } else { |
| 107 | + std::cout << "--- no meta information found ---\n"; |
55 | 108 | } |
56 | | - } else { |
57 | | - std::cout << "--- no meta information found ---\n"; |
58 | 109 | } |
59 | 110 |
|
| 111 | + if (filesWrongValidity.size() > 0) { |
| 112 | + std::cerr << "### ERROR: Validity checks failed for:\n"; |
| 113 | + for (auto& f : filesWrongValidity) { |
| 114 | + std::cerr << "### " << f << "\n"; |
| 115 | + } |
| 116 | + return 1; |
| 117 | + } |
60 | 118 | return 0; |
61 | 119 | } |
0 commit comments