Jpp  15.0.5
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
daq_parser.cpp
Go to the documentation of this file.
3 #include <iostream>
4 #include <iomanip>
5 #include <fstream>
6 #include <string>
7 #include <cstring>
8 #include <sys/ioctl.h>
9 #include <signal.h>
10 #include <unistd.h>
11 #include <vector>
12 #include <cassert>
13 
14 /**
15  * \author cpellegrino
16  */
17 
18 const static unsigned int ttdc = 1414808643;
19 const static unsigned int taes = 1413563731;
20 
21 static int terminal_width;
22 
23 void sig_term_change(int /*signum*/)
24 {
25  static bool const is_a_tty = isatty(1);
26 
27  if (!is_a_tty) {
28  terminal_width = 80;
29  } else {
30  struct winsize sz;
31 
32  ioctl(1, TIOCGWINSZ, &sz);
33  terminal_width = sz.ws_col;
34  }
35 }
36 
37 struct __attribute__((packed)) hit_t
38 {
39  uint8_t channel;
40  uint32_t timestamp;
41  uint8_t ToT;
42 };
43 
44 inline std::ostream& operator <<(std::ostream& stream, const hit_t& hit)
45 {
46  return stream << "C: "
47  << std::setfill(' ') << std::setw(2)
48  << (unsigned int) hit.channel
49 
50  << ", T: "
51  << std::setfill(' ') << std::setw(6)
52  << ntohl(hit.timestamp)
53 
54  << ", ToT: "
55  << std::setfill(' ') << std::setw(6)
56  << (unsigned int) hit.ToT;
57 }
58 
59 void print_acoustic_data(const char* const buffer, ssize_t buffer_size)
60 {
61  if (is_infoword(buffer))
62  {
63  std::cout << "InfoWord: yes\n"
64  << *static_cast<const InfoWord* const>(static_cast<const void* const>(
65  buffer))
66  << '\n';
67  }
68  else
69  {
70  std::cout << "InfoWord: no\n";
71  }
72 }
73 
74 void print_summary(hit_t const* const hits, std::size_t nhits)
75 {
76  int wrong = 0;
77  std::vector<int> summary(31, 0);
78  for (unsigned i = 0; i < nhits; ++i) {
79  if (hits[i].channel < 0 || hits[i].channel > 30) {
80  ++wrong;
81  } else {
82  ++summary[hits[i].channel];
83  }
84  }
85 
86  int const n = terminal_width > 11 ? terminal_width / 11 : 1;
87 
88  for (unsigned i = 0; i < summary.size(); ++i) {
89  std::cout << "CH" << std::setfill('0') << std::setw(2) << i
90  << ": " << std::setfill(' ') << std::setw(4) << summary[i] << ' ';
91 
92  if ((i + 1) % n == 0) {
93  std::cout << '\n';
94  }
95  }
96 
97  std::cout << '\n';
98 
99  if (wrong) {
100  std::cout << "wrong channels: " << wrong << '\n';
101  }
102 }
103 
104 void print_optical_data(const char* const buffer, ssize_t buffer_size)
105 {
106  const unsigned int nhits = buffer_size / sizeof(hit_t);
107 
108  std::cout << "Number of hits: " << nhits << '\n';
109 
110  const hit_t* const hits = static_cast<const hit_t* const>(
111  static_cast<const void* const>(buffer)
112  );
113 
114  if (nhits) {
115  const int printing = 20 > nhits ? nhits : 20;
116  const unsigned int n = terminal_width > 37 ? terminal_width / 37 : 1;
117 
118  for (int i = 0; i < printing; ++i)
119  {
120  std::cout << "Hit"
121  << std::setfill('0') << std::setw(2)
122  << i
123  << ": "
124  << hits[i] << ' ';
125 
126  if ((i + 1) % n == 0)
127  {
128  std::cout << '\n';
129  }
130  else
131  {
132  std::cout << "| ";
133  }
134  }
135  }
136  std::cout << '\n';
137 
138  print_summary(hits, nhits);
139 }
140 
141 void parseData(std::istream& stream)
142 {
143  int count = 0;
144  std::vector<char> payload;
145 
146  while (stream)
147  {
148  DAQCommonHeader header;
149  stream.read((char*) &header, sizeof(header));
150 
151  if (stream.gcount() != sizeof(header))
152  {
153  return;
154  }
155 
156  std::cout << "Counter: " << ++count << '\n';
157  std::cout << DAQHeaderPrinter(&header) << '\n';
158 
159  assert(header.FrameLength - sizeof(header) >= 0 && "Wrong frame length.");
160 
161  std::size_t const payload_size = header.FrameLength - sizeof(header);
162 
163  if (payload.capacity() < payload_size)
164  {
165  payload.resize(payload_size);
166  }
167 
168  stream.read((char*) payload.data(), payload_size);
169 
170  if (static_cast<std::size_t>(stream.gcount()) != payload_size)
171  {
172  return;
173  }
174 
175  if (header.DataType == ttdc) {
176  print_optical_data(payload.data(), payload_size);
177  } else if (header.DataType == taes) {
178  print_acoustic_data(payload.data(), payload_size);
179  } else {
180  std::cout << "Unknown data type\n";
181  }
182 
183  std::cout << ' ' << std::string((terminal_width > 3 ? terminal_width - 2 : 1), '=') << " \n";
184  }
185 }
186 
187 int main(int argc, char* argv[])
188 {
189  if (argc > 1)
190  {
191  if (strcmp(argv[1], "-h") == 0)
192  {
193  std::cout << "Usage: " << argv[0] << " [-h] [filename]\n"
194  << "Options:\n"
195  << "-h shows this help\n"
196  << "filename: if specified reads from file, otherwise stdin is used\n";
197  return 0;
198  }
199  }
200 
201  // Initialise the terminal_width global variable
202  sig_term_change(0);
203 
204  // Set the signal callback funciton for signal 28 (SIGWINCH, window changed)
205  signal(SIGWINCH, sig_term_change);
206 
207  if (argc == 1)
208  {
209  parseData(std::cin);
210  }
211  else
212  {
213  std::ifstream input_file(argv[1], std::ios::binary);
214  parseData(input_file);
215  }
216 }
static int terminal_width
Definition: daq_parser.cpp:21
void print_summary(hit_t const *const hits, std::size_t nhits)
Definition: daq_parser.cpp:74
struct __attribute__((__packed__)) InfoWord
Definition: infoword.hh:18
int main(int argc, char *argv[])
Definition: Main.cc:15
void parseData(std::istream &stream)
Definition: daq_parser.cpp:141
bool is_infoword(const void *const data)
Definition: infoword.hh:93
const int n
Definition: JPolint.hh:660
static const size_t buffer_size
static const unsigned int ttdc
Definition: datatypespec.hh:8
void sig_term_change(int)
Definition: daq_parser.cpp:23
std::vector< int > count
Definition: JAlgorithm.hh:180
const char *const hit_t
Definition: io_ascii.hh:24
static const unsigned int taes
Definition: datatypespec.hh:9
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)