187 bpo::variables_map vm;
188 bpo::options_description opt_general(
"Usage:\n " + std::string(argv[0]) +
190 " Tool will decode the DDLx data for EMCAL 0\n"
191 "Commands / Options");
192 bpo::options_description opt_hidden(
"");
193 bpo::options_description opt_all;
194 bpo::positional_options_description opt_pos;
197 auto add_option = opt_general.add_options();
198 add_option(
"help,h",
"Print this help message");
199 add_option(
"verbose,v", bpo::value<uint32_t>()->default_value(0),
"Select verbosity level [0 = no output]");
200 add_option(
"version",
"Print version information");
201 add_option(
"input-file,i", bpo::value<std::string>()->required(),
"Specifies input file. Multiple files can be parsed separated by ,");
202 add_option(
"output-file,o", bpo::value<std::string>()->default_value(
"FOCALPadData.root"),
"Output file for rootified data");
203 add_option(
"readout,r", bpo::value<std::string>()->default_value(
"RORC"),
"Readout mode (RORC or CRU)");
204 add_option(
"debug,d", bpo::value<uint32_t>()->default_value(0),
"Select debug output level [0 = no debug output]");
206 opt_all.add(opt_general).add(opt_hidden);
207 bpo::store(bpo::command_line_parser(argc, argv).options(opt_all).positional(opt_pos).run(), vm);
209 if (vm.count(
"help") || argc == 1) {
210 std::cout << opt_general << std::endl;
214 if (vm.count(
"version")) {
220 }
catch (bpo::error& e) {
221 std::cerr <<
"ERROR: " << e.what() << std::endl
223 std::cerr << opt_general << std::endl;
225 }
catch (std::exception& e) {
226 std::cerr << e.what() <<
", application will now exit" << std::endl;
230 auto rawfilename = vm[
"input-file"].as<std::string>();
231 auto rootfilename = vm[
"output-file"].as<std::string>();
232 auto readoutmode = vm[
"readout"].as<std::string>();
234 std::vector<std::string> inputfiles;
235 if (rawfilename.find(
",") != std::string::npos) {
237 std::stringstream parser(rawfilename);
239 while (std::getline(parser,
buffer,
',')) {
241 inputfiles.push_back(
buffer);
243 LOG(info) <<
"Found " << inputfiles.size() <<
" input files to process";
246 LOG(info) <<
"Adding " << rawfilename;
247 inputfiles.push_back(rawfilename);
251 if (readoutmode !=
"RORC" && readoutmode !=
"CRU") {
252 LOG(error) <<
"Unknown readout mode - select RORC or CRU";
254 }
else if (readoutmode ==
"RORC") {
255 LOG(info) <<
"Reconstructing in C-RORC mode";
258 LOG(info) <<
"Reconstructing in CRU mode";
266 for (
auto rawfile : inputfiles) {
267 LOG(
debug) <<
"Adding " << rawfile <<
" to raw reader";
272 std::unique_ptr<TFile> rootfilewriter(TFile::Open(rootfilename.data(),
"RECREATE"));
273 rootfilewriter->cd();
274 TTree* padtree =
new TTree(
"PadData",
"PadData");
278 int nHBFprocessed = 0, nTFprocessed = 0, nEventsProcessed = 0;
279 std::map<int, int> nEvnetsHBF;
283 LOG(info) <<
"nothing left to read after " << tfID <<
" TFs read";
286 std::vector<char> rawtf;
287 for (
int il = 0; il < reader.
getNLinks(); il++) {
288 auto& link = reader.
getLink(il);
292 link.readNextTF(rawtf.data());
293 gsl::span<char> dataBuffer(rawtf);
296 std::vector<char> hbfbuffer;
299 while (currentpos < dataBuffer.size()) {
300 auto rdh =
reinterpret_cast<const o2::header::RDHAny*
>(dataBuffer.data() + currentpos);
302 if (o2::raw::RDHUtils::getMemorySize(rdh) == o2::raw::RDHUtils::getHeaderSize(rdh)) {
303 auto trigger = o2::raw::RDHUtils::getTriggerType(rdh);
305 if (o2::raw::RDHUtils::getStop(rdh)) {
306 LOG(
debug) <<
"Stop bit received - processing payload";
310 nEventsProcessed += nevents;
311 auto found = nEvnetsHBF.find(nevents);
312 if (found == nEvnetsHBF.end()) {
313 nEvnetsHBF[nevents] = 1;
318 LOG(
debug) <<
"New HBF or Timeframe";
320 currentir.
bc = o2::raw::RDHUtils::getTriggerBC(rdh);
321 currentir.
orbit = o2::raw::RDHUtils::getTriggerOrbit(rdh);
324 LOG(error) <<
"Found unknown trigger" << std::bitset<32>(trigger);
326 currentpos += o2::raw::RDHUtils::getOffsetToNext(rdh);
329 if (o2::raw::RDHUtils::getStop(rdh)) {
330 LOG(error) <<
"Unexpected stop";
334 auto payloadsize = o2::raw::RDHUtils::getMemorySize(rdh) - o2::raw::RDHUtils::getHeaderSize(rdh);
335 int endpoint =
static_cast<int>(o2::raw::RDHUtils::getEndPointID(rdh));
338 LOG(
debug) <<
"Found trigger BC: " << o2::raw::RDHUtils::getTriggerBC(rdh);
339 LOG(
debug) <<
"Found trigger Oribt: " << o2::raw::RDHUtils::getTriggerOrbit(rdh);
340 LOG(
debug) <<
"Found payload size: " << payloadsize;
341 LOG(
debug) <<
"Found offset to next: " << o2::raw::RDHUtils::getOffsetToNext(rdh);
342 LOG(
debug) <<
"Stop bit: " << (o2::raw::RDHUtils::getStop(rdh) ?
"yes" :
"no");
344 auto page_payload = dataBuffer.subspan(currentpos + o2::raw::RDHUtils::getHeaderSize(rdh), payloadsize);
345 std::copy(page_payload.begin(), page_payload.end(), std::back_inserter(hbfbuffer));
346 currentpos += o2::raw::RDHUtils::getOffsetToNext(rdh);
352 rootfilewriter->Write();
353 LOG(info) <<
"Processed " << nTFprocessed <<
" timeframes, " << nHBFprocessed <<
" HBFs";
354 LOG(info) <<
"Analyzed " << nEventsProcessed <<
" events:";
355 LOG(info) <<
"=============================================================";
356 for (
auto& [nevents, nHBF] : nEvnetsHBF) {
357 LOG(info) <<
" " << nevents <<
" event(s)/HBF: " << nHBF <<
" HBFs ...";