otsdaq-mu2e-stm  5.02.01
formEvents.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/formEvents.hh"
15 
16 // Instance of dataVars class
17 dataVars dva;
18 
19 // Standard constructor - shouldn't be used
20 formEvents::formEvents(uint64_t buffer_len)
21 {
22  // Initialise buffers
23  for(int i = 0; i < CHNUM; i++)
24  {
25  event_data[i] = new int16_t[buffer_len];
26  }
27 }
28 
29 // Form data into events
30 uint64_t formEvents::get_events(int chan,
31  uint64_t data_len,
32  int16_t*& data,
33  queue_buffer* pushq)
34 {
35  // First check packet sizes are correct
36  if(data_len % MAX_PACKET_LEN != 0)
37  {
38  Logger::Instance()->write(
39  0,
40  "formEvents::get_events : Packet sizes incorrect! Channel = " +
41  std::to_string(chan) + ". Data size = " + std::to_string(data_len) +
42  " % MAX_PACKET_LEN = " + std::to_string(data_len % MAX_PACKET_LEN));
43  }
44 
45  // Reinitialise variables and buffers
46  event_counter[chan] = 0; // event counter
47  acc_event_size[chan] = 0;
48 
49  // Loop through all elements
50  uint64_t count = 0;
51 
52  while(count < data_len)
53  {
54  // Get the packet start location
55  uint64_t packet_start = count;
56 
57  // Calculate how much left in packet after packet header
58  uint16_t leftInPacket = MAX_PACKET_LEN - fw_pHdr_Len;
59  // While leftinPacket is more than a trigger header length
60  while(leftInPacket > fw_tHdr_Len)
61  {
62  // Get header start index location
63  uint64_t hdr_start_loc = packet_start + MAX_PACKET_LEN - leftInPacket;
64 
65  // Check for 0xDEADBEEF signalling last packet
66  if((uint16_t)(data[hdr_start_loc] & 0xFFFF) == BEEF and
67  (uint16_t)(data[hdr_start_loc + 1] & 0xFFFF) == DEAD and
68  (uint16_t)(data[hdr_start_loc + 2] & 0xFFFF) == BEEF and
69  (uint16_t)(data[hdr_start_loc + 3] & 0xFFFF) == DEAD)
70  {
71  // Check rest of packet
72  leftInPacket = dva.check_dead_beef(data, packet_start, leftInPacket);
73 
74  // Store the last event
75  store_event(chan);
76 
77  // Push events to the queue
78  pushq->push(
79  chan, event_data[chan], acc_event_size[chan] / sizeof(int16_t));
80 
81  // Exit loop through packet
82  return event_counter[chan];
83  }
84 
85  // Get event in packet length index location
86  uint64_t event_len_loc = hdr_start_loc + fw_tHdr::EvInPacket;
87 
88  // Get event length
89  uint16_t event_len = data[event_len_loc];
90 
91  // Get total event length
92  uint16_t tot_event_len = data[hdr_start_loc + fw_tHdr::EvLen];
93 
94  // Get event number
95  uint64_t event_num = dva.get_event_number(data, hdr_start_loc);
96 
97  // Get EWT
98  uint64_t EWT = dva.get_event_number(data, hdr_start_loc);
99 
100  // std::cout << "Event number = " << event_num << ", EWT = " << EWT << ", total event length = " << tot_event_len << ", event portion = " << event_len << std::endl;
101 
102  // Store the event number
103  if(chan == 0)
104  event_number = event_num;
105 
106  // If this is the first event of the data run, set first event
107  if(first_event[chan])
108  {
109  // Store the current event number
110  current_event_num[chan] = event_num;
111 
112  // memcpy first trigger header
113  memcpy(current_event_data[chan], &data[hdr_start_loc], fw_tHdr_Size);
114 
115  // Increase current event sizes
116  current_event_size[chan] += fw_tHdr_Size;
117 
118  // Set first event boolean to false
119  first_event[chan] = false;
120  }
121 
122  // Recalculate left in packet
123  leftInPacket -= fw_tHdr_Len;
124  // If a new event
125  if(event_num != current_event_num[chan])
126  {
127  // // Check we haven't skipped any EWTs
128  // if (event_num != current_event_num[chan]+1){
129  // Logger::Instance()->write(2,
130  // "ERROR! EWT skipped "
131  // + std::to_string(event_num-current_event_num[chan])
132  // + " events from "
133  // + std::to_string(current_event_num[chan])
134  // + " to "
135  // + std::to_string(event_num));
136  // }
137 
138  // Store the current event
139  store_event(chan);
140 
141  // Start copying the new event...
142 
143  // Get the size of the header + data portion
144  uint32_t size_to_copy = fw_tHdr_Size + event_len * sizeof(int16_t);
145 
146  // memcpy first trigger header and data
147  memcpy(current_event_data[chan], &data[hdr_start_loc], size_to_copy);
148 
149  // Increase event size buffer variables
150  current_event_size[chan] += size_to_copy;
151 
152  // Increase event length
153  current_event_len[chan] += event_len;
154 
155  // Store the current event number
156  current_event_num[chan] = event_num;
157  }
158 
159  // If event number is the same
160  else
161  {
162  // Get the size of the data portion only
163  uint32_t size_to_copy = event_len * sizeof(int16_t);
164 
165  // Copy ONLY data
166  memcpy(&current_event_data[chan][fw_tHdr_Len + current_event_len[chan]],
167  &data[hdr_start_loc + fw_tHdr_Len],
168  size_to_copy);
169 
170  // Increase event size buffer variables
171  current_event_size[chan] += size_to_copy;
172 
173  // Increase event length
174  current_event_len[chan] += event_len;
175  }
176 
177  // Recalculate left in packet
178  leftInPacket -= event_len;
179 
180  } // End while(leftInPacket > fw_tHdr_Len)
181 
182  // Increase count by packet length
183  count += MAX_PACKET_LEN;
184 
185  } // End i-loop over packets
186 
187  // If we've stored any complete events
188  if(event_counter[chan] > 0)
189  {
190  // Push events to the queue
191  pushq->push(chan, event_data[chan], acc_event_size[chan] / sizeof(int16_t));
192  }
193 
194  return event_counter[chan];
195 }
196 
197 // Store the complete event into the buffer
198 void formEvents::store_event(int chan)
199 {
200  // Get the stored event length from the summed event size
201  uint16_t event_len_check =
202  (current_event_size[chan] - fw_tHdr_Size) / sizeof(int16_t);
203 
204  // Check the stored event length corresponds to the given event length
205  if(event_len_check != current_event_len[chan])
206  {
207  Logger::Instance()->write(
208  0,
209  "ERROR in formEvents::get_events! Chan = " + std::to_string(chan) +
210  ". Event number = " + std::to_string(current_event_num[chan]) +
211  ". Stored event length = " + std::to_string(event_len_check) +
212  ". Given event length = " + std::to_string(current_event_len[chan]) +
213  ".");
214  }
215 
216  // Check the stored event length corresponds to the header total event length
217  uint16_t hdr_event_len = current_event_data[chan][fw_tHdr::EvLen];
218  if(hdr_event_len != current_event_len[chan])
219  {
220  Logger::Instance()->write(
221  0,
222  "ERROR in formEvents::get_events! Chan = " + std::to_string(chan) +
223  ". Event number = " + std::to_string(current_event_num[chan]) +
224  ". Stored event length = " + std::to_string(event_len_check) +
225  ". Given event length = " + std::to_string(hdr_event_len) + ".");
226  }
227 
228  // Ensure event start offset in header is zero
229  current_event_data[chan][fw_tHdr::EvStart] = 0;
230 
231  // Update event in packet length in header to total event length
232  current_event_data[chan][fw_tHdr::EvInPacket] = current_event_len[chan];
233 
234  // // Store the event number
235  // if (chan == 0){
236 
237  // // Get the DTC clock (200 MHz)
238  // int16_t DTCclock_0 = (current_event_data[chan][tHdr_vars.Ch_DTCclk_0] >> 8 ) & 0x00FF;
239  // uint64_t DTCclock = dva.make_uint64_t(DTCclock_0,
240  // current_event_data[chan][tHdr_vars.DTCclk_1],
241  // current_event_data[chan][tHdr_vars.DTCclk_2],
242  // current_event_data[chan][tHdr_vars.DTCclk_3]);
243 
244  // // Get the DTC clock (75 MHz)
245  // uint64_t ADCclock = dva.make_uint64_t(current_event_data[chan][tHdr_vars.ADCclk_0],
246  // current_event_data[chan][tHdr_vars.ADCclk_1],
247  // current_event_data[chan][tHdr_vars.ADCclk_2],
248  // current_event_data[chan][tHdr_vars.ADCclk_3]);
249 
250  // std::cout << "Event number = " << current_event_num[chan] << ", event length = " << current_event_len[chan] << ", DTC clock = " << DTCclock << ", ADC clock = " << ADCclock << std::endl;
251  // }
252 
253  // Store whether on-spill or off-spill event
254  if(chan == 0)
255  {
256  event_number = current_event_num[chan];
257  }
258  int16_t on_spill_flag = current_event_data[chan][tHdr_vars.EM_2_DRTDC] & 0x1;
259  //if (current_event_data[chan][tHdr_vars.EM_2_DRTDC] != 0) std::cout << current_event_data[chan][tHdr_vars.EM_2_DRTDC] << " " << on_spill_flag << std::endl;
260  //std::cout << current_event_data[chan][tHdr_vars.EM_2_DRTDC] << ", " << on_spill_flag << ", " << current_event_len[chan] << std::endl;
261  event_count[chan] += 1;
262  if(on_spill_flag == 1 or current_event_len[chan] < 20000)
263  {
264  on_spill_count[chan] += 1;
265  }
266  else
267  {
268  off_spill_count[chan] += 1;
269  }
270 
271  // Accumulate event size
272  acc_event_size[chan] += current_event_size[chan];
273 
274  // Get the location in the event buffer to copy to
275  uint64_t copy_loc =
276  (acc_event_size[chan] - current_event_size[chan]) / sizeof(int16_t);
277  // memcpy current event array to all event array
278  memcpy(
279  &event_data[chan][copy_loc], current_event_data[chan], current_event_size[chan]);
280 
281  // Increment event_counter
282  event_counter[chan]++;
283 
284  // Reinitalise current event variables
285  current_event_len[chan] = 0;
286  current_event_size[chan] = 0;
287 }
Definition: data.hh:4