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 = r.tell() + frame_header.size();
113 if (frame_header.channel() != 0) {
114 // non-data channel in StreamWriter, skip
115 r.seek(frame_end);
116 continue;
117 }
118
119 if (frame_header.probablyYaml()) {
120 // non-data channel in StreamWriter, skip
121 r.seek(frame_end);
122 continue;
123 }
124
125 r >> ror_header;
126 if (ror_header.subsystem() != subsystem) {
127 // wrong subsystem ID number
128 r.seek(frame_end);
129 continue;
130 }
131
132 if (contributor >= 0 and ror_header.contributor() != contributor) {
133 // wrong contributor ID number
134 r.seek(frame_end);
135 continue;
136 }
137
138 // correct subsystem and contributor channel
139 event_count++;
140 printf("frame %d\n", frame_count);
141 printf(" channel = %d, size = %d, trailer = 0x%02x\n",
142 frame_header.channel(), frame_header.size(),
143 frame_header.trailer());
144 printf(" vers = %d, subsys = %d, contrib = %d\n", ror_header.version(),
145 ror_header.subsystem(), ror_header.contributor());
146
147 r.read(bytes, (frame_header.size() - packing::LDMXRoRHeader::SIZE));
148
149 // print similar to hexdump -C
150 for (std::size_t i_row{0}; i_row < bytes.size() / 16; i_row++) {
151 printf("%8lu ", i_row);
152 for (std::size_t i_byte{0}; i_byte < 16; i_byte++) {
153 printf("%02x ", bytes[16 * i_row + i_byte]);
154 }
155 printf("\n");
156 }
157
158 // leave early if reached number of events
159 if (nevents > 0 and event_count >= nevents) {
160 return 0;
161 }
162 }
163 } catch (const std::runtime_error& e) {
164 std::cerr << e.what() << "\n";
165 return 1;
166 }
167
168 return 0;
169}
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.
unsigned int size() const
get the size of the frame not including this header
Reading a raw data file.
Definition Reader.h:20