PAASS
Software suite to Acquire and Analyze Data from Pixie16
monitor.cpp
Go to the documentation of this file.
1 
12 #include <stdlib.h>
13 #include <iostream>
14 #include <string.h>
15 #include <sstream>
16 #include <iomanip>
17 #include <cmath>
18 
19 #include "poll2_socket.h"
20 
21 #define KILOBYTE 1024 // bytes
22 #define MEGABYTE 1048576 // bytes
23 #define GIGABYTE 1073741824 // bytes
24 
25 // Return the order of magnitude of a number
26 double GetOrder(unsigned int input_, unsigned int &power){
27  double test = 1;
28  for(unsigned int i = 0; i < 100; i++){
29  if(input_/test <= 1){
30  power = i;
31  return test;
32  }
33  test *= 10.0;
34  }
35  return 1;
36 }
37 
38 // Expects input rate in Hz
39 std::string GetChanRateString(double input_){
40  if(input_ < 0.0){ input_ *= -1; }
41  int power = std::log10(input_);
42 
43  std::stringstream stream;
44  stream << std::setprecision(2) << std::fixed;
45  if(power >= 6){ stream << input_/1E6 << "M"; } // MHz
46  else if(power >= 3){ stream << input_/1E3 << "k"; } // kHz
47  else if (input_ == 0) {
48  stream << " 0 ";
49  }
50  else {
51  stream << input_ << " ";
52  } // Hz
53 
54  std::string output = stream.str();
55  output = output.substr(0,output.find_last_not_of(".",3)+1) + output.substr(output.length()-1,1);
56 
57  return output;
58 }
59 
60 std::string GetChanTotalString(unsigned int input_){
61  std::stringstream stream;
62  unsigned int power = 0;
63  double order = GetOrder(input_, power);
64 
65  if(power >= 4){ stream << 10*input_/order; }
66  else{ stream << input_; }
67 
68  // Limit to 2 decimal place due to space constraints
69  std::string output = stream.str();
70  size_t find_index = output.find('.');
71  if(find_index != std::string::npos){
72  std::string temp;
73  temp = output.substr(0, find_index);
74  temp += output.substr(find_index, 3);
75  output = temp;
76  }
77 
78  if(power >= 4){
79  std::stringstream stream2;
80  stream2 << output << "E" << power-1;
81  output = stream2.str();
82  }
83 
84  return output;
85 }
86 
87 // Expects input rate in B/s
88 std::string GetRateString(double input_){
89  if(input_ < 0.0){ input_ *= -1; }
90 
91  std::stringstream stream;
92  if(input_/GIGABYTE > 1){ stream << input_/GIGABYTE << " GB/s\n"; } // GB/s
93  else if(input_/MEGABYTE > 1){ stream << input_/MEGABYTE << " MB/s\n"; } // MB/s
94  else if(input_/KILOBYTE > 1){ stream << input_/KILOBYTE << " kB/s\n"; } // kB/s
95  else{ stream << input_ << " B/s\n"; } // B/s
96 
97  return stream.str();
98 }
99 
100 // Expects input time in seconds
101 std::string GetTimeString(double input_){
102  if(input_ < 0.0){ input_ *= -1; }
103 
104  long long time = (long long)input_;
105  int hr = time/3600;
106  int min = (time%3600)/60;
107  int sec = (time%3600)%60;
108  int rem = (int)(100*(input_ - time));
109 
110  std::stringstream stream;
111  if(hr < 10){ stream << "0" << hr; }
112  else{ stream << hr; }
113  stream << ":";
114  if(min < 10){ stream << "0" << min; }
115  else{ stream << min; }
116  stream << ":";
117  if(sec < 10){ stream << "0" << sec; }
118  else{ stream << sec; }
119  stream << ".";
120  if(rem < 10){ stream << "0" << rem; }
121  else{ stream << rem; }
122 
123  return stream.str();
124 }
125 
126 int main(){
127  const size_t msg_size = 5844;// 5.8 kB of stats data max
128  const int modColumnWidth = 25;
129  char buffer[msg_size];
130  Server poll_server;
131 
132  int num_modules;
133  double time_in_sec;
134  double data_rate;
135  double **rates = NULL;
136  double **inputCountRate = NULL;
137  double **outputCountRate = NULL;
138  unsigned int **totals = NULL;
139 
140  bool first_packet = true;
141  if(poll_server.Init(5556)){
142  std::cout << " Waiting for first stats packet...\n";
143 
144  while(true){
145  std::cout << std::setprecision(2);
146 
147  poll_server.RecvMessage(buffer, msg_size);
148  char *ptr = buffer;
149 
150  if(strcmp(buffer, "$KILL_SOCKET") == 0){
151  std::cout << " Received KILL_SOCKET flag...\n\n";
152  break;
153  }
154 
155  system("clear");
156 
157  //std::cout << " Received:\t" << recv_bytes << " bytes\n";
158 
159  // Below is the stats packet structure (for N modules)
160  // ---------------------------------------------------
161  // 4 byte total number of pixie modules (N)
162  // 8 byte total time of run (in seconds)
163  // 8 byte total data rate (in B/s)
164  // channel 0, 0 rate
165  // channel 0, 0 total
166  // channel 0, 1 rate
167  // channel 0, 1 total
168  // ...
169  // channel 0, 15 rate
170  // channel 0, 15 total
171  // channel 1, 0 rate
172  // channel 1, 0 total
173  // ...
174  // channel N-1, 15 rate
175  // channel N-1, 15 total
176  memcpy(&num_modules, ptr, 4); ptr += 4;
177 
178  if(first_packet){
179  rates = new double*[num_modules];
180  inputCountRate = new double*[num_modules];
181  outputCountRate = new double*[num_modules];
182  totals = new unsigned int*[num_modules];
183  for(int i = 0; i < num_modules; i++){
184  rates[i] = new double[16];
185  inputCountRate[i] = new double[16];
186  outputCountRate[i] = new double[16];
187  totals[i] = new unsigned int[16];
188  }
189  first_packet = false;
190  }
191 
192  memcpy(&time_in_sec, ptr, 8); ptr += 8;
193  memcpy(&data_rate, ptr, 8); ptr += 8;
194  for(int i = 0; i < num_modules; i++){
195  for(int j = 0; j < 16; j++){
196  memcpy(&inputCountRate[i][j], ptr, 8); ptr += 8;
197  memcpy(&outputCountRate[i][j], ptr, 8); ptr += 8;
198  memcpy(&rates[i][j], ptr, 8); ptr += 8;
199  memcpy(&totals[i][j], ptr, 4); ptr += 4;
200  }
201  }
202 
203  // Display the rate information
204  std::cout << "Run Time: " << GetTimeString(time_in_sec);
205  if (num_modules > 1) std::cout << "\t";
206  else std::cout << "\n";
207  std::cout << "Data Rate: " << GetRateString(data_rate) << std::endl;
208  std::cout << " ";
209  for(unsigned int i = 0; i < (unsigned int)num_modules; i++){
210  std::cout << "|" << std::setw((int)((modColumnWidth-1.+0.5) / 2))
211  << std::setfill('-') << "M" << std::setw(2)
212  << std::setfill('0') << i
213  << std::setw((int)((modColumnWidth-2.+0.5) / 2))
214  << std::setfill('-') << "";
215  }
216  std::cout << "|\n";
217 
218  for(unsigned int i = 0; i < 16; i++){
219  std::cout << "C" << std::setw(2) << std:: setfill('0') << i << "|";
220  for(unsigned int j = 0; j < (unsigned int)num_modules; j++){
221  std::cout << std::setw(5) << std::setfill(' ') << GetChanRateString(inputCountRate[j][i]) << " ";
222  std::cout << std::setw(5) << std::setfill(' ') << GetChanRateString(outputCountRate[j][i]) << " ";
223  std::cout << std::setw(5) << std::setfill(' ') << GetChanRateString(rates[j][i]) << " ";
224  std::cout << std::setw(6) << GetChanTotalString(totals[j][i]) << " ";
225  std::cout << "|";
226  }
227  std::cout << "\n";
228  }
229  }
230  }
231  else{
232  std::cout << " Error: Failed to open poll socket 5556!\n";
233  return 1;
234  }
235  poll_server.Close();
236 
237  if(rates){ delete[] rates; }
238  if(inputCountRate){ delete[] inputCountRate; }
239  if(outputCountRate){ delete[] outputCountRate; }
240  if(totals){ delete[] totals; }
241 
242  return 0;
243 }
std::string GetChanRateString(double input_)
Definition: monitor.cpp:39
#define MEGABYTE
Definition: monitor.cpp:22
void Close()
Close the socket.
int order(double input_)
Find the order of magnitude of an input double.
Definition: listener.cpp:23
Provides network connectivity for poll2.
int RecvMessage(char *message_, size_t length_)
#define GIGABYTE
Definition: monitor.cpp:23
std::string GetChanTotalString(unsigned int input_)
Definition: monitor.cpp:60
std::string GetTimeString(double input_)
Definition: monitor.cpp:101
bool Init(int port_, int sec_=10, int usec_=0)
Initialize the serv object and open a specified port. Returns false if the socket fails to open or th...
#define KILOBYTE
Definition: monitor.cpp:21
int main()
Definition: monitor.cpp:126
std::string GetRateString(double input_)
Definition: monitor.cpp:88
double GetOrder(unsigned int input_, unsigned int &power)
Definition: monitor.cpp:26