otsdaq-mu2e-stm  5.02.01
checkData.cc
1 /********************************************************************/
5 
6 #include <fstream>
7 #include <iostream>
8 #include <vector>
9 
10 // Hex reader
11 #include "STMDAQ-TestBeam/utils/Hex.hh"
12 
13 // Process data header
14 #include "STMDAQ-TestBeam/processData/checkData.hh"
15 
16 // Instance of data variables class
17 dataVars dv;
18 
19 // Instance of UDPsocket class
20 UDPsocket udp;
21 
22 // Standard constructor
23 checkData::checkData() {}
24 
25 // Check packet number and for dropped packets
26 //void checkData::check_packets(int chan, int n_packets, uint64_t data_len, int16_t *data){
27 void checkData::check_packets(int chan, uint64_t data_len, int16_t* data)
28 {
29  // First check packet sizes are correct
30  if(data_len % MAX_PACKET_LEN != 0)
31  {
32  Logger::Instance()->write(
33  0,
34  "checkData::check_packets : Packet sizes incorrect! Channel = " +
35  udp.get_channel_name(chan) + ". Data size = " + std::to_string(data_len) +
36  " % MAX_PACKET_LEN = " + std::to_string(data_len % MAX_PACKET_LEN));
37  }
38 
39  // Get the last packet number to be read
40  uint32_t last_packet = getLastPacketNum(chan);
41 
42  // If this is the first packet of the data run
43  if(firstPacket)
44  {
45  // Set the last packet to be the first packet to be read it
46  last_packet = (uint16_t)data[1] << 16 | (uint16_t)data[0];
47  // Set first packet boolean to false
48  firstPacket = false;
49  }
50 
51  // Loop through all elements
52  uint64_t count = 0;
53  while(count < data_len)
54  {
55  // Get the packet start location
56  uint64_t packet_start = count;
57  // Reconstruct the packet number
58  uint32_t packet_num =
59  (uint16_t)data[packet_start + 1] << 16 | (uint16_t)data[packet_start];
60 
61  // Check the packet header checksum
62  check_pHdr(packet_num, data[packet_start + 2]);
63 
64  // Check for dropped packets
65  check_dropped_packets(chan, packet_num, last_packet);
66 
67  // Set the last packet number to the current packet number
68  last_packet = packet_num;
69 
70  // Check the event/trigger headers in a packet
71  //check_tHdrs(chan,data,packet_start);
72 
73  // Increase count by packet length
74  count += MAX_PACKET_LEN;
75  }
76 
77  // Store the last packet number
78  setLastPacketNum(chan, last_packet);
79 }
80 
81 // Check for dropped packets
82 void checkData::check_dropped_packets(int chan, uint32_t packet_num, uint32_t last_packet)
83 {
84  // Find the difference between this packet number and the last
85  int diff = packet_num - last_packet;
86  // Check if the difference between packets is negative
87  if(diff < 0)
88  {
89  Logger::Instance()->write(
90  0,
91  "Packet number mismatch! Channel = " + udp.get_channel_name(chan) +
92  ", previous packet number = " + std::to_string(last_packet) +
93  ", previous packet number = " + std::to_string(packet_num));
94  std::cout << "Packet number mismatch! Channel = " << udp.get_channel_name(chan)
95  << ", previous packet number = " << std::to_string(last_packet)
96  << ", previous packet number = " << std::to_string(packet_num) << "\n";
97  }
98 
99  // If the difference is larger than 1...
100  if(diff > 1)
101  {
102  // Increase the stored number of dropped packets
103  dropped_packet_count[chan] += diff - 1;
104  // Loop over the number of dropped packets
105  for(int j = 1; j < diff; j++)
106  {
107  // Log the dropped packet
108  Logger::Instance()->write(
109  2,
110  "Dropped UDP packet warning: Channel = " + udp.get_channel_name(chan) +
111  ", missing packet number = " + std::to_string(last_packet + j));
112  std::cout << "Dropped UDP packet warning: Channel = "
113  << udp.get_channel_name(chan)
114  << ", missing packet number = " << std::to_string(last_packet + j)
115  << "\n";
116  }
117  }
118 }
119 
120 // Check the packet header pHdrEnd
121 void checkData::check_pHdr(uint32_t packet_num, int16_t pHdr_end)
122 {
123  // If the packet header check sum is incorrect
124  if((uint16_t)pHdr_end != fw_pHdr_end_data)
125  {
126  // Log the dropped packet
127  std::cout << "ERROR! Packet number " << std::to_string(packet_num)
128  << " has pHdrEnd " << std::to_string((uint16_t)pHdr_end)
129  << " instead of 65518 (0xFFEE)"
130  << "\n";
131 
132  Logger::Instance()->write(
133  0,
134  "ERROR! Packet number " + std::to_string(packet_num) + " has pHdrEnd " +
135  std::to_string((uint16_t)pHdr_end) + " instead of 65518 (0xFFEE)");
136  }
137 }
138 
139 // Check headers
140 void checkData::check_tHdrs(int chan, int16_t* data, uint64_t packet_start)
141 {
142  // Get the packet number
143  uint32_t pnum = (uint16_t)data[packet_start + 1] << 16 | (uint16_t)data[packet_start];
144 
145  // Calculate how much left in packet after packet header
146  uint16_t leftInPacket = MAX_PACKET_LEN - fw_pHdr_Len;
147 
148  // While leftinPacket is more than a trigger header length
149  while(leftInPacket > fw_tHdr_Len)
150  {
151  // Get header start index location
152  uint64_t hdr_start_loc = packet_start + MAX_PACKET_LEN - leftInPacket;
153  // Get header end index location
154  uint64_t hdr_end_loc = hdr_start_loc + fw_tHdr_Len - 1;
155 
156  // Get event length index location
157  uint64_t eLen_loc = hdr_start_loc + fw_tHdr::EvLen;
158  // Get event length
159  uint16_t eLen = data[eLen_loc];
160 
161  // Check the trigger header and return event number
162  uint64_t evNum = check_fw_tHdr(chan, data, hdr_start_loc);
163 
164  // Recalculate left in packet
165  leftInPacket -= fw_tHdr_Len;
166 
167  // If packet is filled with deadbeefs, break
168  if(deadbeef[chan])
169  break;
170 
171  // Check end of trigger header is as expected, else throw critical error
172  if(data[hdr_start_loc] != fw_tHdr::HdrStart_data[fw_tHdr::HdrStart_len - 1])
173  {
174  Logger::Instance()->write(
175  0,
176  "ERROR! Event/trigger header mismatch!!\nPacket number = " +
177  std::to_string(pnum) + ". Event number = " + std::to_string(evNum));
178  }
179 
180  // Recalculate left in packet
181  leftInPacket -= eLen;
182  }
183 
184  // Check remainder of packet is filled with 0xDEADBEEF
185  leftInPacket = dv.check_dead_beef(data, packet_start, leftInPacket);
186 }
187 
188 // Check firmware trigger/event header
189 uint64_t checkData::check_fw_tHdr(int chan, int16_t* data, uint64_t hdr_index)
190 {
191  // Get the channel number
192  uint16_t channel = data[hdr_index + tHdr_vars.Ch_DTCclk_0] & 0xFF;
193 
194  // Check that the channel number is correct
195  if(channel != chan)
196  {
197  // Check to see if it is the last packet filled only with 0xDEADBEEFs
198  for(uint i = 0; i < fw_tHdr_Len / 2; i++)
199  {
200  // If end of packet isn't filled with 0xDEADBEEF, throw critical error
201  if((uint16_t)(data[hdr_index + i * 2] & 0xFFFF) == BEEF and
202  (uint16_t)(data[hdr_index + i * 2 + 1] & 0xFFFF) == DEAD)
203  {
204  // is 0xDEADBEEF
205  deadbeef[chan] = true;
206  }
207  else
208  {
209  // is not 0xDEADBEEF
210  deadbeef[chan] = false;
211  }
212  }
213  // If filled with deadbeef, then return
214  if(deadbeef)
215  return 0;
216  Logger::Instance()->write(
217  0,
218  "ERROR! Channel number " + std::to_string(channel) +
219  " in event/trigger header does not match expected channel number " +
220  std::to_string(chan));
221  }
222 
223  // // Get the DTC clock (200 MHz)
224  // int16_t DTCclock_0 = (data[hdr_index+tHdr_vars.Ch_DTCclk_0] >> 8);
225  // // uint64_t DTCclock = dv.make_uint64_t(DTCclock_0.
226  // // data[hdr_index+tHdr_vars.DTCclk_1],
227  // // data[hdr_index+tHdr_vars.DTCclk_2],
228  // // data[hdr_index+tHdr_vars.DTCclk_3]);
229  // uint64_t DTCclock = (uint64_t)data[hdr_index+tHdr_vars.DTCclk_3] << 40 |
230  // (uint64_t)data[hdr_index+tHdr_vars.DTCclk_2] << 24 |
231  // (uint64_t)data[hdr_index+tHdr_vars.DTCclk_1] << 8 |
232  // (uint64_t)DTCclock_0;
233 
234  // // Get the DTC clock (75 MHz)
235  // uint64_t ADCclock = dv.make_uint64_t(data[hdr_index+tHdr_vars.ADCclk_0],
236  // data[hdr_index+tHdr_vars.ADCclk_1],
237  // data[hdr_index+tHdr_vars.ADCclk_2],
238  // data[hdr_index+tHdr_vars.ADCclk_3]);
239 
240  // Get the trigger/event number
241  uint64_t EvNum = dv.make_uint64_t(data[hdr_index + tHdr_vars.EvNum_0],
242  data[hdr_index + tHdr_vars.EvNum_1],
243  data[hdr_index + tHdr_vars.EvNum_2],
244  0);
245 
246  // Get the event window tag
247  uint64_t EWT = dv.make_uint64_t(data[hdr_index + tHdr_vars.EWT_0],
248  data[hdr_index + tHdr_vars.EWT_1],
249  data[hdr_index + tHdr_vars.EWT_2],
250  0);
251 
252  // Check the EvNum and EWT are identical
253  if(EvNum != EWT)
254  {
255  Logger::Instance()->write(0,
256  "ERROR! Event number " + std::to_string(EvNum) +
257  " does not match Event Window Tag " +
258  std::to_string(EWT));
259  }
260 
261  // // Get the event mode
262  // int16_t EM_2 = data[hdr_index+tHdr_vars.EM_2_DRTDC] & 0xFF;
263  // uint64_t EM = dv.make_uint64_t(data[hdr_index+tHdr_vars.EM_0],
264  // data[hdr_index+tHdr_vars.EM_1],
265  // EM_2,
266  // 0);
267 
268  // // Get the Delivery Ring Marker TDC
269  // uint16_t DRM = data[hdr_index+tHdr_vars.EM_2_DRTDC] >> 8 & 0xFF;
270 
271  // // Get the event start offset
272  // uint16_t ESO = data[hdr_index+tHdr_vars.EvStart];
273 
274  // // Get the event length (to read)
275  // uint16_t EvLen = data[hdr_index+tHdr_vars.EvLen];
276 
277  // Check if trigger header end is correct
278  for(uint i = 0; i < tHdr_vars.HdrStart_len; i++)
279  {
280  if(data[hdr_index + tHdr_vars.HdrStart_start + i] != tHdr_vars.HdrStart_data[i])
281  {
282  Logger::Instance()->write(
283  0,
284  "ERROR! Event number " + std::to_string(EvNum) +
285  " has event header end value " +
286  std::to_string(data[hdr_index + tHdr_vars.HdrStart_start + i]) +
287  " instead of " + std::to_string(tHdr_vars.HdrStart_data[i]) +
288  " for header index " + std::to_string(tHdr_vars.HdrStart_start + i));
289  }
290  }
291 
292  // cout << "Channel = " << channel << endl;
293  // cout << "DTC clock = " << DTCclock << endl;
294  // cout << "ADC clock = " << ADCclock << endl;
295  // cout << "Event number = " << EvNum << endl;
296  // cout << "Event window tag = " << EWT << endl;
297  // cout << "Event mode = " << EM << endl;
298  // cout << "Delivery ring marker = " << DRM << endl;
299  // cout << "Event start offset = " << ESO << endl;
300  // cout << "Event length = " << EvLen << endl;
301 
302  return EvNum;
303 }
Definition: data.hh:4