count_events.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // count_events
3 //
4 // Use FileIndex to quickly obtain the number of events (and runs, and
5 // subruns) in the specified files.
6 ////////////////////////////////////////////////////////////////////////
7 
10 
11 #include "boost/program_options.hpp"
12 
13 #include <algorithm>
14 #include <iostream>
15 #include <string>
16 #include <vector>
17 
18 #include "TBranch.h"
19 #include "TError.h"
20 #include "TFile.h"
21 #include "TTree.h"
22 
23 namespace bpo = boost::program_options;
24 
25 namespace {
26  bool want_hr = false;
27 
28  using namespace std::string_literals;
29  struct pluralize {
30  pluralize(std::size_t count,
31  std::string thing,
32  std::string singular = ""s,
33  std::string plural = "s"s)
34  : msg(std::to_string(count) + ' ' + thing +
35  ((count == 1) ? singular : plural))
36  {}
37  std::string msg;
38  };
39 
40  std::ostream&
41  operator<<(std::ostream& os, pluralize p)
42  {
43  os << p.msg;
44  return os;
45  }
46 
47  bool
48  count_events(std::string const& fileName, std::ostream& os, std::ostream& err)
49  {
50  // Ignore less severe warnings for the purposes of opening the file.
51  auto savedErrorLevel = gErrorIgnoreLevel;
52  gErrorIgnoreLevel = kBreak;
53  TFile* tf = TFile::Open(fileName.c_str());
54  gErrorIgnoreLevel = savedErrorLevel;
55  if (tf == nullptr) {
56  err << fileName << "\tCould not be opened by ROOT: skipped.\n";
57  return false;
58  }
59  std::array<std::size_t, art::NumBranchTypes> counters{{0}};
60  art::FileIndex fi;
61  for (int i = art::InEvent; i != art::InResults; ++i) {
62  std::string treeName =
63  art::BranchTypeToProductTreeName(static_cast<art::BranchType>(i));
64  TTree* tree = static_cast<TTree*>(tf->Get(treeName.c_str()));
65  if (!tree) {
66  err << fileName << "\tNot a valid art ROOT-format file: skipped.\n";
67  return false;
68  }
69  counters[i] = tree->GetEntries();
70  }
71  {
72  auto tree = static_cast<TTree*>(
74  if (tree && (tree->GetNbranches() > 1)) {
75  counters[art::InResults] = 1;
76  }
77  }
78  if (want_hr) {
79  os << fileName << "\t" << pluralize(counters[art::InRun], "run") << ", "
80  << pluralize(counters[art::InSubRun], "subrun") << ", "
81  << pluralize(counters[art::InEvent], "event") << ", and "
82  << pluralize(counters[art::InResults], "result") << ".\n";
83  } else {
84  os << fileName << '\t' << counters[art::InRun] << '\t'
85  << counters[art::InSubRun] << '\t' << counters[art::InEvent] << '\t'
86  << counters[art::InResults] << '\n';
87  }
88  return true;
89  }
90 } // namespace
91 
92 int
93 main(int argc, char** argv)
94 {
95  using stringvec = std::vector<std::string>;
96  int result = 1;
97  std::ostringstream descstr;
98  descstr << argv[0] << "Usage: count_events [<options>] <filename>+\n";
99  bpo::options_description desc(descstr.str());
100  desc.add_options()("hr", "Human-readable output")(
101  "help,h", "this help message.")("source,s",
102  bpo::value<stringvec>()->composing(),
103  "source data file (multiple OK).");
104  bpo::options_description all_opts("All Options.");
105  all_opts.add(desc);
106  // Each non-option argument is interpreted as the name of a file to be
107  // processed. Any number of filenames is allowed.
108  bpo::positional_options_description pd;
109  pd.add("source", -1);
110  // The variables_map contains the actual program options.
111  bpo::variables_map vm;
112  try {
113  bpo::store(bpo::command_line_parser(argc, argv)
114  .options(all_opts)
115  .positional(pd)
116  .run(),
117  vm);
118  bpo::notify(vm);
119  }
120  catch (bpo::error const& e) {
121  std::cerr << "Exception from command line processing in " << argv[0] << ": "
122  << e.what() << "\n";
123  return 2;
124  }
125  if (vm.count("help")) {
126  std::cerr << desc << std::endl;
127  return 1;
128  } else if (vm.count("hr")) {
129  want_hr = true;
130  }
131  if (vm.count("source") == 0) {
132  std::cerr << "Require at least one source file.\n";
133  std::cerr << desc << "\n";
134  return 1;
135  }
136  auto const& sources = vm["source"].as<stringvec>();
137  auto const expected = sources.size();
138  auto succeeded = std::count_if(sources.cbegin(),
139  sources.cend(),
140  std::bind(&count_events,
141  std::placeholders::_1,
142  std::ref(std::cout),
143  std::ref(std::cerr)));
144  if (expected == static_cast<size_t>(succeeded)) {
145  std::cout << "Counted events successfully for " << expected
146  << " specified files." << std::endl;
147  result = 0;
148  } else {
149  result = 1;
150  std::cout << "Failed to count events for " << expected - succeeded << " of "
151  << expected << " specified files." << std::endl;
152  }
153  return result & 0xff;
154 }
std::string const & BranchTypeToProductTreeName(BranchType const bt)
Definition: BranchType.cc:71
const char expected[]
Definition: Exception_t.cc:22
std::string string
Definition: nybbler.cc:12
STL namespace.
Definition: tf_graph.h:23
std::vector< std::string > stringvec
def count_events(folder, key)
Definition: utils.py:9
error
Definition: includer.cc:31
const double e
std::ostream & operator<<(std::ostream &os, Analyzer::Table< T > const &t)
Definition: Analyzer.h:138
p
Definition: test.py:228
int main(int argc, char **argv)
Definition: count_events.cc:93
static const double s
Definition: Units.h:99
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
unsigned int run