extractEvent.cc
Go to the documentation of this file.
1 /*
2  extract events from IoAuger file via
3  - SD ID
4  - Auger ID
5  - Events in ADST file (using Auger IDs)
6 
7  Authors:
8  Michael.Unger@kit.edu
9  Fabian.Schuessler@ik.fzk.de
10  Ralf.Ulrich@kit.edu
11  Hans.Dembinski@kit.edu
12  darko.veberic@kit.edu
13 */
14 
15 #include <RecEvent.h>
16 #include <RecEventFile.h>
17 
18 #include <IoAuger.h>
19 #include <IoSdData.h>
20 #include <AugerEvent.h>
21 
22 #include <boost/algorithm/string/trim.hpp>
23 #include <boost/lexical_cast.hpp>
24 #include <boost/program_options.hpp>
25 #include <boost/filesystem/operations.hpp>
26 
27 #include <iostream>
28 #include <sstream>
29 #include <string>
30 #include <fstream>
31 #include <algorithm>
32 
33 using namespace std;
34 
35 
36 typedef unsigned long ulong;
37 
38 
39 namespace Global {
40  bool gDebug = false;
41 }
42 
43 
44 set<ulong>
45 ParseIds(const string& file)
46 {
47  ifstream ifs(file);
48  if (!ifs.is_open()) {
49  cerr << "cannot open file '" << file << "'!" << endl;
50  exit(EXIT_FAILURE);
51  }
52  string line;
53  ostringstream oss;
54  int lineno = 0;
55  set<ulong> ids;
56  while (getline(ifs, line)) {
57  ++lineno;
58  if (Global::gDebug)
59  cerr << "line " << lineno << ": \"" << line << "\"\n";
60  try {
61  boost::algorithm::trim(line);
62  const auto id = boost::lexical_cast<ulong>(line);
63  ids.insert(id);
64  if (Global::gDebug)
65  cerr << "got " << id << '\n';
66  } catch (const boost::bad_lexical_cast& e) {
67  cerr << "line " << lineno << " of the file '" << file << "' could not be converted to an ID" << endl;
68  throw e;
69  }
70  }
71  return ids;
72 }
73 
74 
75 void
76 DumpIds(const set<ulong>& ids)
77 {
78  for (const auto& id : ids)
79  cerr << id << '\n';
80 }
81 
82 
83 void
84 DumpKeys(const vector<string>& files)
85 {
86  for (const auto& file : files) {
87  const unique_ptr<TFile> f{TFile::Open(file.c_str(), "READ")};
88  if (!f) {
89  cerr << "cannot read file '" << file << "'" << endl;
90  continue;
91  }
92  const auto* const keys = f->GetListOfKeys();
93  const auto nKeys = keys->GetEntries();
94  if (!nKeys) {
95  cerr << "warning: file '" << file << "' has no keys!" << endl;
96  continue;
97  }
98  for (int i = 0; i < nKeys; ++i) {
99  const auto key = (TKey* const)keys->At(i);
100  if (!key) {
101  if (Global::gDebug)
102  cerr << "key " << i << " is a nullptr!";
103  continue;
104  }
105  const char* const name = key->GetName();
106  if (!name || !('0' <= *name && *name <= '9')) {
107  if (Global::gDebug)
108  cerr << "could not convert key \"" << name << '"' << endl;
109  continue;
110  }
111  cout << stoul(name) << endl;
112  }
113  }
114 }
115 
116 
117 int
118 main(int argc, char* argv[])
119 {
120  namespace bpo = boost::program_options;
121  bpo::options_description optionSwitches("Options");
122  optionSwitches.add_options()
123  ("help,h",
124  "Output this help.")
125  ("debug",
126  "Output some debug information.")
127  ("ids,i",
128  bpo::value<string>(),
129  "File containing event IDs to select.")
130  ("dump,d",
131  "Dump all IDs in input IoAuger ROOT files.")
132  ("native,n",
133  "Search for events through native IoAuger interface (instead using faster ROOT keys).")
134  ("output,o",
135  bpo::value<string>(),
136  "Output IoAuger ROOT file containing all selected events.")
137  ;
138  bpo::options_description optionHidden;
139  optionHidden.add_options()
140  ("input",
141  bpo::value<vector<string>>()->required(),
142  "Input ROOT file(s).");
143  bpo::positional_options_description positional;
144  positional.add("input", -1);
145  bpo::options_description options;
146  options.add(optionSwitches).add(optionHidden);
147  bpo::variables_map vm;
148  try {
149  bpo::store(bpo::command_line_parser(argc, argv).options(options).positional(positional).run(), vm);
150  if (vm.count("help")) {
151  cerr << optionSwitches << endl;
152  return EXIT_SUCCESS;
153  }
154  } catch (bpo::error& err) {
155  cerr << "Command line error : " << err.what() << '\n'
156  << optionSwitches << endl;
157  return EXIT_FAILURE;
158  }
159 
160  Global::gDebug = vm.count("debug");
161 
162  const bool native = vm.count("native");
163 
164  if (!vm.count("input")) {
165  cerr << "no input files specified!" << endl;
166  return EXIT_FAILURE;
167  }
168 
169  const auto inputFiles = vm["input"].as<vector<string>>();
170 
171  if (vm.count("dump")) {
172  DumpKeys(inputFiles);
173  return EXIT_SUCCESS;
174  }
175 
176  if (!vm.count("output")) {
177  cerr << "no output file specified!" << endl;
178  return EXIT_FAILURE;
179  }
180 
181  const auto outputFile = vm["output"].as<string>();
182 
183  if (boost::filesystem::exists(outputFile)) {
184  cerr << "not overwriting exisiting output file '" << outputFile << '\'' << endl;
185  return EXIT_FAILURE;
186  }
187 
188  if (!vm.count("ids")) {
189  cerr << "no ID file specified!" << endl;
190  return EXIT_FAILURE;
191  }
192 
193  auto ids = ParseIds(vm["ids"].as<string>());
194 
195  const size_t nSearched = ids.size();
196 
197  if (!nSearched) {
198  cerr << "no events to extract; IDs file is empty!" << endl;
199  return EXIT_FAILURE;
200  }
201 
202  if (Global::gDebug) {
203  cerr << "IDs to find:\n";
204  DumpIds(ids);
205  }
206 
207  cout << "Events to extract: " << nSearched << "\n"
208  "Using " << (native ? "native " : "key ") << "interface" << endl;
209 
210  AugerEvent event;
211 
212  unique_ptr<TFile> outputRootFile;
213  unique_ptr<AugerFile> outputAugerFile;
214  size_t nFound = 0;
215 
216  if (native) {
217 
218  // slow method: read each file and look for ID inside AugerEvent
219 
220  for (const auto& inFile : inputFiles) {
221  cout << "Opening " << inFile << " ... [" << nFound << '/' << nSearched << ']' << endl;
222  AugerFile auFile(inFile.c_str());
223  while (auFile.ReadNext(event) != AugerFile::eEOF && nFound != nSearched) {
224  auto it = ids.find(event.Id());
225  if (it == ids.end() && event.HasSd())
226  it = ids.find(event.Sd().Id);
227  if (it != ids.end()) {
228  ++nFound;
229  if (!outputAugerFile)
230  outputAugerFile = make_unique<AugerFile>(outputFile.c_str(), AugerFile::eWrite);
231  outputAugerFile->Write(event);
232  if (Global::gDebug)
233  cout << "found ID " << *it << endl;
234  ids.erase(it);
235  if (ids.empty())
236  break;
237  }
238  }
239  }
240 
241  } else {
242 
243  // fast method: ID is encoded in the key name, just browse keys
244 
245  for (const auto& inFile : inputFiles) {
246 
247  cout << "Opening " << inFile << " ... [" << nFound << '/' << nSearched << ']' << endl;
248 
249  const unique_ptr<TFile> f{TFile::Open(inFile.c_str(), "READ")};
250  if (!f) {
251  cerr << "Error: cannot read file '" << inFile << '\'' << endl;
252  continue;
253  }
254 
255  const auto* const keys = f->GetListOfKeys();
256  const auto nKeys = keys->GetEntries();
257  if (!nKeys) {
258  cerr << "warning: file '" << inFile << "' has no keys!" << endl;
259  continue;
260  }
261  if (Global::gDebug)
262  cerr << "file '" << inFile << "' has " << nKeys << " keys" << endl;
263  for (int i = 0; i < nKeys; ++i) {
264  const auto key = (TKey* const)keys->At(i);
265  if (!key) {
266  cerr << "key " << i << " is a nullptr!";
267  continue;
268  }
269  const char* const name = key->GetName();
270  if (!name || !('0' <= *name && *name <= '9')) {
271  cerr << "key " << i << " is malformed: \"" << (name ? name : "nullptr") << '\"' << endl;
272  continue;
273  }
274  const ulong id = stoul(name);
275  if (Global::gDebug)
276  cout << "id from key " << i << " \"" << name << "\" is " << id << endl;
277  const auto it = ids.find(id);
278  if (it != ids.end()) {
279  ++nFound;
280  if (Global::gDebug)
281  cout << "found ID " << id << endl;
282  if (!outputRootFile)
283  outputRootFile.reset(TFile::Open(outputFile.c_str(), "RECREATE"));
284  auto* const obj = key->ReadObj();
285  outputRootFile->cd();
286  obj->Write(name);
287  ids.erase(it);
288  if (ids.empty())
289  break;
290  }
291  }
292 
293  }
294 
295  }
296 
297  if (Global::gDebug) {
298  cerr << "IDs not found:\n";
299  DumpIds(ids);
300  }
301 
302  cout << "Events extracted: [" << nFound << "/" << nSearched << "]" << endl;
303 
304  return EXIT_SUCCESS;
305 }
bool gDebug
Definition: extractEvent.cc:40
void DumpIds(const set< ulong > &ids)
Definition: extractEvent.cc:76
Read Only access.
Definition: IoCodes.h:18
int exit
Definition: dump1090.h:237
char * exists
Definition: XbArray.cc:12
int main(int argc, char *argv[])
Definition: DBSync.cc:58
void DumpKeys(const vector< string > &files)
Definition: extractEvent.cc:84
const string file
fwk::VModule::ResultFlag(fwk::VModule::* run)(evt::Event &)
Definition: fwkPython.cc:59
unsigned long ulong
Definition: extractEvent.cc:36
set< ulong > ParseIds(const string &file)
Definition: extractEvent.cc:45

, generated on Tue Sep 26 2023.