1 | |
2 | #include <unistd.h> |
3 | #include <stdlib.h> |
4 | #include <stdint.h> |
5 | #include <time.h> |
6 | |
7 | #include <iostream> |
8 | #include <string> |
9 | #include <vector> |
10 | #include <stack> |
11 | #include <thread> |
12 | using namespace std; |
13 | |
14 | #include <TFile.h> |
15 | |
16 | #include "DMapEVIOWords.h" |
17 | |
18 | #include <DAQ/HDEVIO.h> |
19 | |
20 | |
21 | void Usage(string mess); |
22 | void ParseCommandLineArguments(int narg, char *argv[]); |
23 | void PrintSummary(void); |
24 | void MapEVIOWords(void); |
25 | |
26 | |
27 | vector<string> filenames; |
28 | bool PRINT_SUMMARY = true; |
29 | bool SAVE_FILE_MAP = false; |
30 | bool SKIP_EVENT_MAPPING = false; |
31 | bool MAP_WORDS = false; |
32 | bool GENERATE_ERROR_REPORT = false; |
33 | string ROOT_FILENAME = "hdevio_scan.root"; |
34 | string MAP_FILENAME = ""; |
35 | uint64_t MAX_EVIO_EVENTS = 20000; |
36 | uint64_t SKIP_EVIO_EVENTS = 0; |
37 | uint32_t BLOCK_SIZE = 20; |
38 | uint32_t MAX_HISTORY_BUFF_SIZE = 400; |
39 | int32_t RUNNUMBER = (1<<30); |
40 | |
41 | |
42 | |
43 | |
44 | int main(int narg, char *argv[]) |
45 | { |
46 | |
47 | ParseCommandLineArguments(narg, argv); |
48 | |
49 | if(PRINT_SUMMARY) PrintSummary(); |
50 | |
51 | if(MAP_WORDS ) MapEVIOWords(); |
52 | |
53 | return 0; |
54 | } |
55 | |
56 | |
57 | |
58 | |
59 | void Usage(string mess="") |
60 | { |
61 | cout << endl; |
62 | cout << "Usage:" << endl; |
63 | cout << endl; |
64 | cout <<" hdevio [options] file.evio [file2.evio ...]" << endl; |
65 | cout << endl; |
66 | cout << "options:" << endl; |
67 | cout << " -h, --help Print this usage statement" << endl; |
68 | cout << " -w Make histogram of population by word type" << endl; |
69 | cout << " -r file.root Set name of ROOT file to save histo to. " << endl; |
70 | cout << " (implies -w)" << endl; |
71 | cout << " -m max_events Max. EVIO events (not physics events) to process." << endl; |
72 | cout << " -i ignore_events Num. EVIO events (not physics events) to ignore at start." << endl; |
73 | cout << " -b block_size EVIO events to add for daq_block_size histo." << endl; |
74 | cout << " -e Write details of bad event tag location to file" << endl; |
75 | cout << " -n max_buff Max. events to keep timing info for (only valid)" << endl; |
76 | cout << " with -w option)" << endl; |
77 | cout << " -s Save file block/event map" << endl; |
78 | cout << " -blocksonly Save only block map not events. (Only use with -s)" << endl; |
79 | cout << " -f file.map Set name of file to save block/event to. " << endl; |
80 | cout << " (implies -s)" << endl; |
81 | cout << " -R RUNNUMBER Set the run number used to access the TTAB in the CCDB" << endl; |
82 | cout << endl; |
83 | cout << "n.b. When using the -i (ignore) flag, the total number of events" << endl; |
84 | cout << " read in will be the sum of how many are ignored and the \"max\"" << endl; |
85 | cout << " events with only the last max_events being processed." << endl; |
86 | cout << endl; |
87 | |
88 | if(mess != "") cout << endl << mess << endl << endl; |
89 | |
90 | exit(0); |
91 | } |
92 | |
93 | |
94 | |
95 | |
96 | void ParseCommandLineArguments(int narg, char *argv[]) |
97 | { |
98 | |
99 | if(narg<2) Usage("You must supply a filename!"); |
100 | |
101 | for(int i=1; i<narg; i++){ |
102 | string arg = argv[i]; |
103 | string next = (i+1)<narg ? argv[i+1]:""; |
104 | |
105 | if(arg == "-h" || arg == "--help") Usage(); |
106 | else if(arg == "-w"){ MAP_WORDS = true; PRINT_SUMMARY = false; } |
107 | else if(arg == "-r"){ MAP_WORDS = true; PRINT_SUMMARY = false; ROOT_FILENAME = next; i++;} |
108 | else if(arg == "-i"){ SKIP_EVIO_EVENTS = atoi(next.c_str()); i++;} |
109 | else if(arg == "-m"){ MAX_EVIO_EVENTS = atoi(next.c_str()); i++;} |
110 | else if(arg == "-b"){ BLOCK_SIZE = atoi(next.c_str()); i++;} |
111 | else if(arg == "-e"){ GENERATE_ERROR_REPORT = true; } |
112 | else if(arg == "-n"){ MAX_HISTORY_BUFF_SIZE = atoi(next.c_str()); i++;} |
113 | else if(arg == "-s"){ SAVE_FILE_MAP = true;} |
114 | else if(arg == "-f"){ SAVE_FILE_MAP = true; MAP_FILENAME = next; i++;} |
115 | else if(arg == "-R"){ RUNNUMBER = atoi(next.c_str()); i++;} |
116 | else if(arg == "-blocksonly") { SKIP_EVENT_MAPPING = true;} |
117 | else if(arg[0] == '-') {cout << "Unknown option \""<<arg<<"\" !" << endl; exit(-1);} |
118 | else filenames.push_back(arg); |
119 | } |
120 | |
121 | |
122 | if(RUNNUMBER >= (1<<30)){ |
123 | if(!filenames.empty()){ |
124 | cout << "No run number given, trying to extract from filename: " << filenames[0] << endl; |
125 | auto pos = filenames[0].find("hd_rawdata_"); |
126 | if(pos != string::npos ){ |
127 | auto runstr = filenames[0].substr( pos+11, 6); |
128 | RUNNUMBER = atoi( runstr.c_str() ); |
129 | } |
130 | } |
131 | } |
132 | } |
133 | |
134 | |
135 | |
136 | |
137 | void PrintSummary(void) |
138 | { |
139 | |
140 | for(uint32_t i=0; i<filenames.size(); i++){ |
141 | string &filename = filenames[i]; |
142 | cout << "Processing file " << (i+1) << "/" << filenames.size() << " : " << filename << endl; |
143 | |
144 | HDEVIO *hdevio = new HDEVIO(filename); |
145 | if(!hdevio->is_open){ |
146 | cout << hdevio->err_mess.str() << endl; |
147 | continue; |
148 | } |
149 | |
150 | if(SKIP_EVENT_MAPPING) hdevio->SKIP_EVENT_MAPPING = true; |
151 | |
152 | time_t start_time = time(NULL__null); |
153 | hdevio->PrintFileSummary(); |
154 | time_t end_time = time(NULL__null); |
155 | |
156 | if(GENERATE_ERROR_REPORT){ |
157 | ofstream ofs("hdevio_scan.err"); |
158 | ofs << "#"; |
159 | ofs << "# hdevio_scan report for " << filename << endl; |
160 | ofs << "#"; |
161 | ofs << "# The following list is for each EVIO event that contained an" << endl; |
162 | ofs << "# unknown top-level bank tag. Since any corruption may have" << endl; |
163 | ofs << "# started in the previous event, locations for that are also" << endl; |
164 | ofs << "# provided (when available)." <<endl; |
165 | ofs << "# columns are:" << endl; |
166 | ofs << "# 1 block number in file (starting from 0)" << endl; |
167 | ofs << "# 2 block offset in file (hex)" <<endl; |
168 | ofs << "# 3 block number of previous event" << endl; |
169 | ofs << "# 4 block offset of previous event" <<endl; |
170 | ofs << "# 5 event number in block (starting from 1)" << endl; |
171 | ofs << "# 6 number of events in block" << endl; |
172 | ofs << "# 7 event offset in file (hex)" <<endl; |
173 | ofs << "# 8 event length (inclusive)" <<endl; |
174 | ofs << "# 9 event header (hex) <-- This value is what indicates a corrupt event" <<endl; |
175 | ofs << "# 10 event number of previous event" << endl; |
176 | ofs << "# 11 event offset of previous event" <<endl; |
177 | ofs << "# 12 event length of previous event" <<endl; |
178 | ofs << "# 13 event header of previous event" <<endl; |
179 | ofs << "#" << endl; |
180 | ofs << "# 1 2 3 4 5 6 7 8 9 10 11 12 13" <<endl; |
181 | |
182 | vector<HDEVIO::EVIOBlockRecord> brs = hdevio->GetEVIOBlockRecords(); |
183 | |
184 | HDEVIO::EVIOBlockRecord *br_prev = NULL__null; |
185 | HDEVIO::EVIOEventRecord *er_prev = NULL__null; |
186 | int32_t ibr = 0; |
187 | for(HDEVIO::EVIOBlockRecord &br : brs){ |
188 | int32_t ier = 1; |
189 | for(HDEVIO::EVIOEventRecord &er : br.evio_events){ |
190 | if(er.event_type == HDEVIO::kBT_UNKNOWN){ |
191 | char str[512]; |
192 | |
193 | sprintf(str, "%04u 0x%08x %04d 0x%08x %3u/%3u 0x%08x %10u 0x%08x %03d 0x%08x %10u 0x%08x" |
194 | , ibr |
195 | , (unsigned int)br.pos |
196 | , ibr-1 |
197 | , br_prev!=NULL__null ? (unsigned int)br_prev->pos:0 |
198 | , ier |
199 | , (unsigned int)br.evio_events.size() |
200 | , (unsigned int)er.pos |
201 | , (unsigned int)er.event_len |
202 | , (unsigned int)er.event_header |
203 | , ier-1 |
204 | , er_prev!=NULL__null ? (unsigned int)er_prev->pos:0 |
205 | , er_prev!=NULL__null ? (unsigned int)er_prev->event_len:0 |
206 | , er_prev!=NULL__null ? (unsigned int)er_prev->event_header:0); |
207 | ofs << str << endl; |
208 | } |
209 | |
210 | er_prev = &er; |
211 | ier++; |
212 | } |
213 | |
214 | br_prev = &br; |
215 | ibr++; |
216 | } |
217 | |
218 | ofs.close(); |
219 | } |
220 | |
221 | if(SAVE_FILE_MAP) hdevio->SaveFileMap(MAP_FILENAME); |
222 | |
223 | delete hdevio; |
224 | |
225 | cout << (end_time - start_time) << " sec " << endl; |
226 | } |
227 | } |
228 | |
229 | |
230 | |
231 | |
232 | void MapEVIOWords(void) |
233 | { |
234 | cout << endl; |
235 | cout << "Mapping will be limited to first " << MAX_EVIO_EVENTS << " events per input file" << endl; |
236 | |
237 | |
238 | TFile *rootfile = new TFile(ROOT_FILENAME.c_str(), "RECREATE"); |
239 | |
240 | DMapEVIOWords mapevio; |
241 | mapevio.max_history_buff_size = MAX_HISTORY_BUFF_SIZE; |
242 | |
243 | |
244 | uint64_t Nevents = 0; |
245 | for(uint32_t i=0; i<filenames.size(); i++){ |
| 1 | Loop condition is true. Entering loop body | |
|
| 9 | | Loop condition is true. Entering loop body | |
|
| 17 | | Loop condition is true. Entering loop body | |
|
246 | |
247 | |
248 | string &filename = filenames[i]; |
249 | cout << "Processing file " << (i+1) << "/" << filenames.size() << " : " << filename << endl; |
250 | HDEVIO *hdevio = new HDEVIO(filename); |
| |
251 | if(!hdevio->is_open){ |
| |
| |
| |
252 | cout << hdevio->err_mess.str() << endl; |
| 20 | | Potential leak of memory pointed to by 'hdevio' |
|
253 | continue; |
254 | } |
255 | |
256 | |
257 | uint32_t buff_len = 1000; |
258 | uint32_t *buff = new uint32_t[buff_len]; |
259 | bool done = false; |
260 | while(!done){ |
| 3 | | Loop condition is true. Entering loop body | |
|
| 8 | | Loop condition is false. Execution continues on line 289 | |
|
| 11 | | Loop condition is true. Entering loop body | |
|
261 | hdevio->readNoFileBuff(buff, buff_len); |
262 | switch(hdevio->err_code){ |
| 4 | | Control jumps to the 'default' case at line 275 | |
|
| 12 | | Control jumps to the 'default' case at line 275 | |
|
263 | case HDEVIO::HDEVIO_OK: |
264 | if( Nevents>= SKIP_EVIO_EVENTS ) mapevio.ParseEvent(buff); |
265 | break; |
266 | case HDEVIO::HDEVIO_USER_BUFFER_TOO_SMALL: |
267 | buff_len = hdevio->last_event_len; |
268 | delete[] buff; |
269 | buff = new uint32_t[buff_len]; |
270 | break; |
271 | case HDEVIO::HDEVIO_EOF: |
272 | cout << endl << " end of file" << endl; |
273 | done = true; |
274 | break; |
275 | default: |
276 | cout << endl; |
277 | cout << hdevio->err_mess.str() << endl; |
278 | done = true; |
279 | break; |
| 5 | | Execution continues on line 283 | |
|
| 13 | | Execution continues on line 283 | |
|
280 | |
281 | } |
282 | |
283 | if((++Nevents % 1000) == 0) { |
| |
| |
284 | int percent_done = (100*Nevents)/MAX_EVIO_EVENTS; |
285 | cout << " " << Nevents << "/" << MAX_EVIO_EVENTS << " (" << percent_done << "%) processed \r"; cout.flush(); |
286 | } |
287 | if( Nevents > (SKIP_EVIO_EVENTS+MAX_EVIO_EVENTS) ) break; |
| |
| |
| 16 | | Execution continues on line 289 | |
|
288 | } |
289 | cout << endl; |
290 | |
291 | |
292 | delete hdevio; |
293 | } |
294 | |
295 | |
296 | mapevio.Finish(); |
297 | |
298 | |
299 | rootfile->Write(); |
300 | rootfile->Close(); |
301 | delete rootfile; |
302 | } |
303 | |
304 | |
305 | |