Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
oncsSub_idtpcfeev2.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file oncsSub_idtpcfeev2.cc
1 #include "oncsSub_idtpcfeev2.h"
2 
3 #include <string.h>
4 #include <stdint.h>
5 
6 #define coutfl cout << __FILE__<< " " << __LINE__ << " "
7 #define cerrfl cerr << __FILE__<< " " << __LINE__ << " "
8 
9 using namespace std;
10 
12  :oncsSubevent_w2 (data)
13 {
14 
15  _is_decoded = 0;
16 
17  for ( int i = 0; i < MAX_FEECOUNT; i++)
18  {
19  _max_samples[i] = 0;
20  _lowest_bx[i] = 0;
21  _highest_bx[i] = 0;
22  }
23 }
24 
25 
27 {
28  // for (int fee = 0; fee < MAX_FEECOUNT; fee++)
29  // {
30  // delete fee_data[fee];
31  // }
32 
33 }
34 
35 
36 #define HEADER_LENGTH 9
37 
39 {
40 
41  if (_is_decoded ) return 0;
42  _is_decoded = 1;
43 
44  unsigned int payload_length = 2 * (getLength() - SEVTHEADERLENGTH - getPadding() );
45 
46  unsigned int index = 0;
47 
48 
49  unsigned short *buffer = ( unsigned short *) &SubeventHdr->data;
50 
51 
52 // for (int fee = 0; fee < MAX_FEECOUNT; fee++)
53 // {
54 // fee_data[fee] = new std::vector<unsigned short>();
55 // }
56 
57  while (buffer[index] != 0xfeee && buffer[index+1] != 0xba5e)
58  {
59  index += 2;
60  }
61 
62  unsigned short word_count;
63  unsigned short link_count;
64  unsigned short link_enabled;
65 
66 
67  int locked[16];
68  for (int a = 0; a < 16; a++) locked[a] = 0;
69 
70 
71  while ( index < payload_length)
72  {
73 
74  if (buffer[index] == 0xfeee && buffer[index+1] == 0xba5e)
75  {
76 
77  word_count = (buffer[index+2] >> 4) + 1;
78  link_count = buffer[index+2] & 0xf;
79  link_enabled = buffer[index+3];
80 
81  // cout << __FILE__<< " " << __LINE__ << " feeeba5e index at " << index
82  // << " word2 " << hex << buffer[index+2] << dec
83  // << " wordcount " << word_count
84  // << " link_count " << link_count
85  // << " link_enabled 0x" << hex << link_enabled << dec
86  // << endl;
87 
88  unsigned short offset_table[16] = {0};
89 
90  int offset_idx = 0;
91  for ( int bitcnt = 0 ; bitcnt < 16; bitcnt++)
92  {
93  if ( (link_enabled & (1 << bitcnt)) != 0)
94  {
95  offset_table[offset_idx] = bitcnt;
96  // coutfl << "link_enabled " << hex << link_enabled << dec
97  // << " offset table " << offset_idx << " value " << bitcnt << endl;
98  offset_idx++;
99  }
100  }
101 
102  int idx;
103  int link;
104 
105  // for (idx = index + 4; idx < index + 4 + word_count * link_count ; idx++)
106  for (index += 4, idx=0; idx < word_count * link_count ; idx++, index++)
107  {
108  link = offset_table[idx % link_count];
109  if (locked[link])
110  {
111  //coutfl << "pushing idx " << idx << " value " << hex << buffer[index] << dec << " into " << link << endl;
112  fee_data[link].push_back(buffer[index]);
113  }
114  else if (buffer[index] == 0xfeed)
115  {
116  locked[link] = 1;
117  //coutfl << "pushing idx " << idx << " value " << hex << buffer[index] << dec << " into " << link << " ** locking" << endl;
118  fee_data[link].push_back(buffer[index]);
119  }
120  }
121 
122  // cout << __FILE__<< " " << __LINE__ << " index " << index << " vector sizes " << fee_data[0].size() << " " << fee_data[1].size() << endl;
123 
124  }
125  else
126  {
127  cout << __FILE__<< " " << __LINE__ << " corrupted FEE data missing 0xfeee 0xba5e marker. Stop further decoding "<< endl;
128  break;
129  }
130 
131  }
132 
133  // here we are done unraveling the initil data structure.
134  // We have now MAX_FEECOUNT * MAX_FEECHANNELS per-channel data structures in hand
135 
136  // first pass...
137 
138  for ( int fee = 0; fee < MAX_FEECOUNT; fee++)
139  {
140 
141  unsigned int record_len = 0;
142  //unsigned int packet_type;
143  unsigned int channel;
144  unsigned int sampa_addr;
145  unsigned int bx_count;
146 
147  unsigned int old_bxcount = 0;
148  unsigned int first_bx = 0xffffff;
149  unsigned int rollover_offset = 0;
150 
151  for ( index = 0; index < fee_data[fee].size(); index += record_len + 2 )
152  {
153  if (index >= fee_data[fee].size() - HEADER_LENGTH) continue;
154 
155  if ( fee_data[fee].at(index) != 0xfeed)
156  {
157  // cerr << __FILE__<< " " << __LINE__ << " FEE " << fee << " not starting with feed at " << index << " size " << fee_data[fee].size() << endl;
158  while (index < fee_data[fee].size() - HEADER_LENGTH && fee_data[fee].at(index) != 0xfeed ) index++;
159  }
160 
161  if (index >= fee_data[fee].size() - HEADER_LENGTH) continue;
162 
163  record_len = fee_data[fee].at(index+1);
164  if ( index + record_len + 2 >= fee_data[fee].size()) break;
165 
166  //packet_type = fee_data[fee].at(index+2);
167  channel = fee_data[fee].at(index+3) & 0x1f;
168  sampa_addr = (fee_data[fee].at(index+3) >> 5) & 0xf;
169  bx_count = (fee_data[fee].at(index+4) << 4) | (fee_data[fee].at(index+5) & 0xf);
170 
171 
172  // coutfl << " bx " << bx_count << " delta to previous bx " << bx_count - old_bxcount << endl;
173  if ( bx_count < old_bxcount )
174  {
175  rollover_offset += 0x100000;
176  // coutfl << " bx " << bx_count << " delta to previous bx " << bx_count - old_bxcount << " rollover " << hex << rollover_offset << endl;
177  }
178  old_bxcount = bx_count;
179 
180  if ( first_bx == 0xffffff )
181  {
182  first_bx = bx_count;
183  }
184 
185  // if ( record_len != 0x88)
186  // {
187  // cerrfl << "wrong record length " << record_len << " fee " << fee << " channel " << channel << endl;
188  // //continue;
189  // }
190 
191  unsigned short crc_value = crc16( fee, index, record_len+1);
192  if ( index + record_len +1 >= fee_data[fee].size() )
193  {
194  cerrfl << "index out of range " << index + record_len + 1 << " " << fee_data[fee].size() << " record_len " << record_len << endl;
195  }
196  else
197  {
198  if ( crc_value != fee_data[fee].at(index + record_len +1) )
199  {
200  // cout << __FILE__<< " " << __LINE__ << " FEE " << fee
201  // << " crc mismatch, index = " << index
202  // << " sampa address " << sampa_addr << " channel " << channel
203  // << " crc = " << hex << crc_value << " value " << fee_data[fee].at(index + record_len +1) << dec << endl;
204  continue;
205  }
206  }
207 
208  if ( channel >= 32 || sampa_addr > 7 )
209  {
210  cout << __FILE__<< " " << __LINE__ << " FEE " << fee
211  << " illegal value, sampa address " << sampa_addr << " channel " << channel << endl;
212  continue;
213  }
214 
215  unsigned int fee_channel = sampa_addr * 32 + channel;
216 
217  for ( unsigned int s = HEADER_LENGTH; s < record_len +1; s++)
218  {
219  if ( index +s >= fee_data[fee].size() )
220  {
221  cerrfl << "index out of range " << index +s << " " << fee_data[fee].size() << " record_len " << record_len << endl;
222  }
223  else
224  {
225  tpc_sample x = { bx_count + s -HEADER_LENGTH + rollover_offset - first_bx,
226  bx_count,
227  fee_data[fee].at(index + s ) };
228  fee_samples[fee][fee_channel].push_back(x);
229  }
230  }
231 
232  }
233  }
234 
235 
236 
237 
238  // now, what is the max sample length per FEE?
239  unsigned int maxvectorsize;
240  for ( int fee = 0; fee < MAX_FEECOUNT; fee++)
241  {
242  maxvectorsize = 0;
243  for ( int ch = 0; ch < MAX_FEECHANNELS; ch++)
244  {
245  if ( fee_samples[fee][ch].size() > maxvectorsize ) maxvectorsize = fee_samples[fee][ch].size();
246  unsigned int s = fee_samples[fee][ch].size();
247  if ( s > 0 )
248  {
249  if ( fee_samples[fee][ch].at(0).bx_time < _lowest_bx[fee] ) _lowest_bx[fee] = fee_samples[fee][ch].at(0).bx_time;
250  if ( fee_samples[fee][ch].at(s-1).bx_time > _highest_bx[fee] ) _highest_bx[fee] = fee_samples[fee][ch].at(s-1).bx_time;
251  }
252  }
253  _max_samples[fee] = maxvectorsize;
254  }
255 
256 
257  return 0;
258 }
259 
260 
261 
262 int oncsSub_idtpcfeev2::iValue(const int fee, const int sample)
263 {
264  tpc_decode();
265 
266  return 0;
267 }
268 
269 int oncsSub_idtpcfeev2::iValue(const int fee, const int ch, const int sample)
270 {
271  tpc_decode();
272  if ( fee > MAX_FEECOUNT ||
273  ch < 0 || ch >= MAX_FEECHANNELS ||
274  sample < 0 || (unsigned int) sample >= fee_samples[fee][ch].size() ) return 0;
275 
276  // if ( sample >= fee_samples[fee][ch].size() ) return 0;
277  return fee_samples[fee][ch].at(sample).adc;
278 
279 }
280 
281 int oncsSub_idtpcfeev2::iValue(const int fee, const int ch, const int sample, const char *what)
282 {
283  tpc_decode();
284 
285  if ( fee > MAX_FEECOUNT ||
286  ch < 0 || ch >= MAX_FEECHANNELS ||
287  sample < 0 || (unsigned int) sample >= fee_samples[fee][ch].size() ) return 0;
288 
289 
290  if ( strcmp(what,"BXRAW") == 0 )
291  {
292  return fee_samples[fee][ch].at(sample).bx_time_raw;
293  }
294  else if ( strcmp(what,"BX") == 0 )
295  {
296  return fee_samples[fee][ch].at(sample).bx_time;
297  }
298  return 0;
299 }
300 
301 int oncsSub_idtpcfeev2::iValue(const int fee, const int ch, const char *what)
302 {
303 
304  tpc_decode();
305 
306  if ( strcmp(what,"NR_SAMPLES") == 0 ) // say if a FEE has been seen at all
307  {
308  if ( fee > MAX_FEECOUNT || ch < 0 || ch >= MAX_FEECHANNELS ) return 0;
309  return fee_samples[fee][ch].size();
310 
311  }
312 
313  return 0;
314 }
315 
316 
317 int oncsSub_idtpcfeev2::iValue(const int n, const char *what)
318 {
319 
320  tpc_decode();
321 
322  if ( strcmp(what,"MAX_SAMPLES") == 0 )
323  {
324  if ( n < 0 || n >= MAX_FEECOUNT ) return 0;
325 
326  return _max_samples[n];
327  }
328 
329  else if ( strcmp(what,"IS_PRESENT") == 0 ) // say if a FEE has been seen at all
330  {
331  if ( n < 0 || n >= MAX_FEECOUNT ) return 0;
332 
333  if (_max_samples[n] > 0) return 1;
334  return 0;
335  }
336 
337  else if ( strcmp(what,"LOWEST_BX") == 0 ) // say if a FEE has been seen at all
338  {
339  if ( n < 0 || n >= MAX_FEECOUNT ) return 0;
340 
341  return _lowest_bx[n];
342  }
343 
344  else if ( strcmp(what,"HIGHEST_BX") == 0 ) // say if a FEE has been seen at all
345  {
346  if ( n < 0 || n >= MAX_FEECOUNT ) return 0;
347 
348  return _highest_bx[n];
349  }
350 
351  else if ( strcmp(what,"MAX_FEECOUNT") == 0 )
352  {
353  return MAX_FEECOUNT;
354  }
355 
356 
357  else if ( strcmp(what,"BROKEN") == 0 )
358  {
359  return _broken;
360  }
361 
362 
363  return 0;
364 
365 }
366 
368 {
369  identify(os);
370 
371  os << "Samples: ";
372  for ( int i = 0 ; i < iValue(0,"MAX_FEECOUNT"); i++)
373  {
374  os << setw(9) << iValue(i,"MAX_SAMPLES") << " ";
375  }
376  os << std::endl;
377 
378  os << "Lowest BX: ";
379  for ( int i = 0 ; i < iValue(0,"MAX_FEECOUNT"); i++)
380  {
381  os << setw(9) << (unsigned int) iValue(i,"LOWEST_BX") << " ";
382  }
383  os << std::endl;
384 
385  os << "Highest BX: ";
386  for ( int i = 0 ; i < iValue(0,"MAX_FEECOUNT"); i++)
387  {
388  os << setw(9) << (unsigned int) iValue(i,"HIGHEST_BX") << " ";
389  }
390  os << std::endl;
391 
392 
393  const int dwidth = 16; // how many colums to display
394 
395  for ( int fee = 0; fee < iValue(0,"MAX_FEECOUNT") ; fee++)
396  {
397  for ( int chblock = 0; chblock < MAX_FEECHANNELS ; chblock+=dwidth)
398  {
399  if ( iValue (fee,"IS_PRESENT") )
400  {
401  cout << " +++++++++++++++ FEE " << fee << " channels " << chblock << " through " << chblock + dwidth << " ++++++++" << endl;
402 
403  // print ithe smaple numbers
404  os << setw(3) << "nrs" << " | " ;
405  for ( int ch = chblock; ch < chblock + dwidth; ch++)
406  {
407  os << setw(10) << iValue(fee,ch, "NR_SAMPLES") << " " ;
408  }
409 
410  os << endl;
411 
412 
413  for ( int s = 0; s < iValue(fee, "MAX_SAMPLES"); s++)
414  {
415 
416  os << setw(3) << s << " | " ;
417  for ( int ch = chblock; ch < chblock + dwidth; ch++)
418  {
419  os << setw(6) << hex << iValue(fee,ch,s, "BX") << " " << setw(4) << iValue(fee,ch,s) << dec << " ";
420 
421  }
422 
423  os << endl;
424  }
425  os << endl;
426  }
427  }
428 
429  }
430 }
431 
432 unsigned short oncsSub_idtpcfeev2::reverseBits(const unsigned short x) const
433 {
434  unsigned short n = x;
435  n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
436  n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
437  n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
438  n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
439  //n = (n >> 16) & 0x0000ffff | (n << 16) & 0xffff0000;
440  return n;
441 }
442 
443 
444 
445 unsigned short oncsSub_idtpcfeev2::crc16(const unsigned int fee, const unsigned int index, const int l) const
446 {
447  int len = l;
448  int i = index;
449  unsigned short crc = 0xffff;
450 
451  while (len--)
452  {
453  unsigned short x = fee_data[fee].at(i++);
454  // cout << "in crc " << hex << x << dec << endl;
455  crc ^= reverseBits( x);
456  for (unsigned short k = 0; k < 16; k++)
457  {
458  crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
459  }
460  }
461  crc = reverseBits(crc);
462  return crc;
463 }
464