Jpp  master_rocky-43-ge265d140c
the software that should make you happy
JEvtMerge.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <string>
4 #include <vector>
5 #include <deque>
6 #include <queue>
7 #include <algorithm>
8 
12 
13 #include "JLang/JException.hh"
14 
15 #include "JSupport/JMeta.hh"
16 #include "JSupport/JSupport.hh"
20 #include "JSupport/JTreeScanner.hh"
22 
23 #include "Jeep/JParser.hh"
24 #include "Jeep/JMessage.hh"
25 
26 
27 namespace {
28 
29  /**
30  * Auxiliary data structure for priority queue / heap.
31  */
32  struct entry_type {
33  /**
34  * Prioritise two entries.
35  *
36  * \param first first entry
37  * \param second second entry
38  * \return true if first entry higher priority than second; else false
39  */
40  friend inline bool operator<(const entry_type& first, const entry_type& second)
41  {
42  return first.evt.mc_event_time.AsDouble() > second.evt.mc_event_time.AsDouble();
43  }
44 
45  size_t index;
46  Evt evt;
47  };
48 }
49 
50 
51 /**
52  * \file
53  * Auxiliary program for time sorting of Monte-Carlo events.
54  *
55  * \author mdejong
56  */
57 int main(int argc, char **argv)
58 {
59  using namespace std;
60  using namespace JPP;
61 
62  typedef typename JTYPELIST<Head, MultiHead, Evt, JMeta>::typelist typelist;
63 
64  vector<string> inputFile;
66  int debug;
67 
68  try {
69 
70  JParser<> zap("Auxiliary program for time sorting of Monte-Carlo events.");
71 
72  zap['f'] = make_field(inputFile, "Input file (produced with JEvtSplit)");
73  zap['o'] = make_field(outputFile);
74  zap['d'] = make_field(debug) = 2;
75 
76  zap(argc, argv);
77  }
78  catch(const exception& error) {
79  FATAL(error.what() << endl);
80  }
81 
82 
83  outputFile.open();
84 
85  outputFile.put(JMeta(argc, argv));
86 
87  const size_t N = inputFile.size();
88 
89  typedef JTreeScanner <Evt> JScanner_t;
90  //typedef JSingleFileScanner<Evt> JScanner_t;
91 
92  counter_type number_of_events = JTreeScanner<Evt>(inputFile).getEntries();
93 
94  vector<JScanner_t> in(N);
95 
96  for (size_t i = 0; i != N; ++i) {
97 
98  in[i].configure(inputFile[i]);
99 
100  STATUS("Processing " << inputFile[i] << endl);
101  }
102 
103 #ifdef PRIORITY_QUEUE
104 
105  priority_queue<entry_type, deque<entry_type> > buffer; // multiplex
106 
107  for (size_t i = 0; i != N; ++i) {
108 
109  if (in[i].hasNext()) {
110 
111  buffer.push({i, *in[i].next()});
112 
113  --number_of_events;
114  }
115  }
116 
117  while (number_of_events != 0) { // process
118 
119  STATUS("event: " << setw(10) << number_of_events << '\r'); DEBUG(endl);
120 
121  const entry_type& top = buffer.top();
122 
123  outputFile.put(top.evt);
124 
125  if (in[top.index].hasNext()) {
126 
127  buffer.push({top.index, *in[top.index].next()});
128 
129  --number_of_events;
130  }
131 
132  buffer.pop();
133  }
134 
135  while (!buffer.empty()) { // flush
136 
137  const entry_type& top = buffer.top();
138 
139  outputFile.put(top.evt);
140 
141  buffer.pop();
142  }
143 
144 #else
145 
146  vector<entry_type> buffer; // multiplex
147 
148  for (size_t i = 0; i != N; ++i) {
149 
150  if (in[i].hasNext()) {
151 
152  buffer.push_back({i, *in[i].next()});
153 
154  --number_of_events;
155  }
156  }
157 
158  make_heap(buffer.begin(), buffer.end());
159 
160  while (number_of_events != 0) { // process
161 
162  STATUS("event: " << setw(10) << number_of_events << '\r'); DEBUG(endl);
163 
164  const size_t index = buffer[0].index;
165 
166  outputFile.put(buffer[0].evt);
167 
168  pop_heap(buffer.begin(), buffer.end());
169 
170  buffer.pop_back();
171 
172  if (in[index].hasNext()) {
173 
174  buffer.push_back({index, *in[index].next()});
175 
176  push_heap(buffer.begin(), buffer.end());
177 
178  --number_of_events;
179  }
180  }
181 
182  sort_heap(buffer.begin(), buffer.end()); // flush
183 
184  for (vector<entry_type>::const_reverse_iterator top = buffer.rbegin(); top != buffer.rend(); ++top) {
185  outputFile.put(top->evt);
186  }
187 #endif
188  STATUS(endl);
189 
190  int counter = 0;
191 
192  Head h0;
193  MultiHead m0;
194 
195  for (size_t i = 0; i != N; ++i) {
196 
197  try {
198 
199  const Head h1 = getHeader (inputFile[i]);
200  const MultiHead m1 = getMultiHeader(inputFile[i]);
201 
202  if (counter == 0) {
203 
204  outputFile.put(h1);
205  outputFile.put(m1);
206 
207  } else {
208 
209  if (h0 != h1) { FATAL("Inconsistent header " << endl << h1 << endl << "!=" << endl << h0 << endl); }
210  if (m0 != m1) { FATAL("Inconsistent multi header " << endl << m1 << endl << "!=" << endl << m0 << endl); }
211  }
212 
213  counter += 1;
214 
215  h0 = h1;
216  m0 = m1;
217  }
218  catch (const exception&) {}
219  }
220 
221  if (counter == 0) {
222  FATAL("Missing header." << endl);
223  }
224 
225  for (size_t i = 0; i != N; ++i) {
226 
227  JSingleFileScanner<JMeta> io(inputFile[i]);
228 
229  io >> outputFile;
230  }
231 
232  outputFile.close();
233 
234  return 0;
235 }
string outputFile
int main(int argc, char **argv)
Definition: JEvtMerge.cc:57
Exceptions.
Recording of objects on file according a format that follows from the file name extension.
General purpose messaging.
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
#define STATUS(A)
Definition: JMessage.hh:63
#define FATAL(A)
Definition: JMessage.hh:67
int debug
debug level
Definition: JSirene.cc:69
ROOT I/O of application specific meta data.
Scanning of objects from multiple files according a format that follows from the extension of each fi...
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2142
Scanning of objects from a single file according a format that follows from the extension of each fil...
ROOT TTree parameter settings of various packages.
Utility class to parse command line options.
Definition: JParser.hh:1698
Object writing to file.
Object reading from a list of files.
bool operator<(const Head &first, const Head &second)
Less than operator.
Definition: JHead.hh:1817
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Long64_t counter_type
Type definition for counter.
JMultiHead getMultiHeader(const JMultipleFileScanner_t &file_list)
Get multi-header corresponding to a given file list.
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
Definition: JSTDTypes.hh:14
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition: Evt.hh:21
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Definition: Head.hh:65
Type list.
Definition: JTypeList.hh:23
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:72