LDMX Software
rogue_extract.cxx
1
5#include <iostream>
6
7#include "Packing/LDMXRoRHeader.h"
8#include "Packing/RogueFrameHeader.h"
9#include "Packing/Utility/Reader.h"
10
11static void usage() {
12 std::cout << "\n"
13 " USAGE:\n"
14 " rogue-extract [options] input_file.dat\n"
15 "\n"
16 " OPTIONS:\n"
17 " -h,--help : print this help and exit\n"
18 " -n,--nevent : maximum number of events to unpack\n"
19 " -s,--subsystem : which subsystem\n "
20 "('ecal','hcal','ts','tdaq', 'tracker', or integer)\n"
21 << std::endl;
22}
23
24int main(int argc, char* argv[]) {
25 if (argc == 1) {
26 // can't do anything without any arguments
27 usage();
28 return 1;
29 }
30
31 int nevents{-1};
32 std::string in_file;
33 int subsystem{-1}, contributor{-1};
34 for (int i_arg{1}; i_arg < argc; i_arg++) {
35 std::string arg{argv[i_arg]};
36 if (arg[0] == '-') {
37 // option
38 if (arg == "-h" or arg == "--help") {
39 usage();
40 return 0;
41 } else if (arg == "-n" or arg == "--nevent") {
42 if (i_arg + 1 == argc or argv[i_arg + 1][0] == '-') {
43 std::cerr << "The " << arg
44 << " parameter requires an argument after it.\n";
45 return 1;
46 }
47 i_arg++;
48 try {
49 nevents = std::stoi(argv[i_arg]);
50 } catch (const std::invalid_argument& e) {
51 std::cerr << "The argument to " << arg << " '" << argv[i_arg]
52 << "' is not an integer.\n";
53 return 1;
54 }
55 } else if (arg == "-s" or arg == "--subsystem") {
56 if (i_arg + 1 == argc or argv[i_arg + 1][0] == '-') {
57 std::cerr << "The " << arg
58 << " parameter requires an argument after it.\n";
59 return 1;
60 }
61 i_arg++;
62 std::string subsys_arg{argv[i_arg]};
63 auto [subsys, contrib] = packing::LDMXRoRHeader::subsystem(subsys_arg);
64 if (subsys == -1) {
65 try {
66 subsystem = std::stoi(subsys_arg.c_str());
67 } catch (const std::invalid_argument& e) {
68 std::cerr << "The argument to " << arg << " '" << subsys_arg
69 << "' is not 'ecal', 'hcal', 'ts', 'tdaq', 'tracker'"
70 << " or a positive integer.\n";
71 return 1;
72 }
73 } else {
74 subsystem = subsys;
75 contributor = contrib;
76 }
77 } else {
78 std::cerr << "Unrecognized option " << arg << std::endl;
79 return 1;
80 }
81 } else {
82 if (not in_file.empty()) {
83 std::cerr << "Can only decode one file at a time.\n";
84 return 1;
85 } else {
86 in_file = arg;
87 }
88 }
89 }
90
91 if (in_file.empty()) {
92 std::cerr << "Need to provide a file to decode.\n";
93 usage();
94 return 1;
95 }
96
97 packing::utility::Reader r(in_file);
98 if (not r) {
99 std::cerr << "Unable to open file '" << in_file << "'.\n";
100 return 1;
101 }
102
103 packing::RogueFrameHeader frame_header;
104 packing::LDMXRoRHeader ror_header;
105 std::vector<uint8_t> bytes;
106 int frame_count{0};
107 int event_count{0};
108 try {
109 while (r) {
110 r >> frame_header;
111 frame_count++;
112 const int frame_end =
113 r.tell() + static_cast<std::streamoff>(frame_header.size());
114 if (frame_header.channel() != 0) {
115 // non-data channel in StreamWriter, skip
116 r.seek(frame_end);
117 continue;
118 }
119
120 if (frame_header.probablyYaml()) {
121 // non-data channel in StreamWriter, skip
122 r.seek(frame_end);
123 continue;
124 }
125
126 r >> ror_header;
127 if (ror_header.subsystem() != subsystem) {
128 // wrong subsystem ID number
129 r.seek(frame_end);
130 continue;
131 }
132
133 if (contributor >= 0 and ror_header.contributor() != contributor) {
134 // wrong contributor ID number
135 r.seek(frame_end);
136 continue;
137 }
138
139 // correct subsystem and contributor channel
140 event_count++;
141 printf("frame %d\n", frame_count);
142 printf(" channel = %d, size = %d, trailer = 0x%02x\n",
143 frame_header.channel(), frame_header.size(),
144 frame_header.trailer());
145 printf(" vers = %d, subsys = %d, contrib = %d\n", ror_header.version(),
146 ror_header.subsystem(), ror_header.contributor());
147
148 r.read(bytes, (frame_header.size() - packing::LDMXRoRHeader::SIZE));
149
150 // print similar to hexdump -C
151 for (std::size_t i_row{0}; i_row < bytes.size() / 16; i_row++) {
152 printf("%8lu ", i_row);
153 for (std::size_t i_byte{0}; i_byte < 16; i_byte++) {
154 printf("%02x ", bytes[16 * i_row + i_byte]);
155 }
156 printf("\n");
157 }
158
159 // leave early if reached number of events
160 if (nevents > 0 and event_count >= nevents) {
161 return 0;
162 }
163 }
164 } catch (const std::runtime_error& e) {
165 std::cerr << e.what() << "\n";
166 return 1;
167 }
168
169 return 0;
170}
the header that the LDMX DAQ Firmware block includes in the output data stream at the beginning of ea...
uint8_t subsystem() const
ID number for subsystem originating data (compiled into firmware)
static const unsigned int SIZE
size of this header in bytes
the header that the Rogue StreamWriter puts includes at the beginning of each frame.
Reading a raw data file.
Definition Reader.h:20