Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
packet_iddigitizerv3.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file packet_iddigitizerv3.cc
1 #include "packet_iddigitizerv3.h"
2 
3 #include <string.h>
4 
5 using namespace std;
6 
7 
8 #define coutfl std::cout << __FILE__<< " " << __LINE__ << " "
9 #define cerrfl std::cerr << __FILE__<< " " << __LINE__ << " "
10 
11 
13  :Packet_w4 (data)
14 {
15 
16  _broken = 0;
17 
18  if ( getHitFormat() > 160 && getHitFormat() <= 190)
19  {
20  _nsamples = getHitFormat() - 160;
21  }
22  _nchannels = 0;
23  _nr_modules = 0;
24 
25  _evtnr = 0;
26  _flagword = 0;
27  _detid = 0;
28  _module_address = 0;
29  _xmit_clock = 0;
30  _AnyChannelisSuppressed = false; // we use this later to see if the checksum can be calculated
31 
32  for ( int i = 0; i < NR_FEMS; i++)
33  {
34  _fem_slot[i] = 0;
35  _fem_evtnr[i] = 0;
36  _fem_clock[i] = 0;
37  _fem_checksum_MSB[i] = 0;
38  _fem_checksum_LSB[i] = 0;
41 
42  }
43 
44  _is_decoded = 0;
45 
46 }
47 
48 
50 {
51 
52 }
53 
55 {
56 
57  if (_is_decoded ) return 0;
58  _is_decoded = 1;
59 
60  unsigned int *k;
61 
62 
63  // check later int dlength = ( getLength()-4) - getPadding();
64 
65  unsigned int *SubeventData = (unsigned int *) findPacketDataStart(packet);
66 
67  int dlength = getDataLength();
68 
69  k = SubeventData; // we make a shorter variale for less typing..
70 
71 
72  for (int i = 0; i < 32; i++)
73  {
74  for (int j = 0; j < 4*64; j++)
75  {
76  adc[i][j] = 0;
77  }
78  }
79 
80  if ( dlength < 6 )
81  {
82  _broken = 1;
83  return 0; //safety belt
84  }
85 
86  // we have here -
87  // [0] 0x8000xxxx with xxxx = evt nr
88  // [1] 0x9000xxxx with xxxx = flag word
89  // [2] 0x9000xxxx with xxxx = det id
90  // [3] 0x9000xxxx with xxxx = module address
91  // [4] 0x9000xxxx with xxxx = xmit clock nr
92 
93  if ( (k[0] >> 28) != 0x8) return 1;
94  if ( (k[1] >> 28) != 0x9) return 1;
95  if ( (k[2] >> 28) != 0x9) return 1;
96  if ( (k[3] >> 28) != 0x9) return 1;
97  if ( (k[4] >> 28) != 0x9) return 1;
98 
99  _evtnr = (k[0] & 0xffff);
100  _flagword = (k[1] & 0xffff);
101  _detid = (k[2] & 0xffff);
102  _module_address = (k[3] & 0xffff);
103  _xmit_clock = (k[4] & 0xffff);
104 
105 
106  int fem_nr = 0;
107 
108  for (int fem_index = 5; fem_index < dlength ; ) // we hop from FEM to FEM here
109  {
110 
111  if ( k[fem_index] == 0xa000ffff)
112  {
113  // coutfl << " FEM_ start at " << fem_index << " " << hex << k[fem_index] << dec << endl;
114 
115  unsigned int i = decode_FEM ( &k[fem_index], fem_nr, dlength - fem_index); // we make "i" so we can debug
116  if ( i == 0)
117  {
118  //coutfl << " strange return " << i << endl;
119  _broken = 2;
120  break; // no endless loops...
121  }
122  fem_nr++;
123  if ( fem_nr >= NR_FEMS)
124  {
125  _broken = 3;
126  return 1;
127  }
128  fem_index += i;
129  //coutfl << " fem_index now " << fem_index << " " << hex << k[fem_index] << dec << endl;
130  }
131  }
132 
133 
134  return 0;
135 }
136 
137 
138 unsigned int Packet_iddigitizerv3::decode_FEM ( unsigned int *k, const int fem_nr, const int len)
139 {
140  int NFEM = fem_nr;
141  int CHNL = 0;
142  int index_channel = NFEM*64;
143  int index_sample = 0;
144  int index_parity = 0;
145 
146  // coutfl << " calling decode_FEM for fem " << fem_nr << endl << endl;
147 
148 
149  // should have been checked but let's be sure
150  if ( k[0] != 0xa000ffff) return 0;
151 
152  _fem_slot[fem_nr] = k[1] & 0xffff;
153  _fem_evtnr[fem_nr] = k[2] & 0xffff;
154  _fem_clock[fem_nr] = k[3] & 0xffff;
155 
156  _nr_modules++;
157  _nchannels += 64;
158 
159  int index;
160  int corrected_index_channel;
161  // for ( index = 1; index < 4; index++)
162  // {
163  // _fem_calculated_checksum_MSB[NFEM] ^= ((k[index] >> 16 ) & 0xffff);
164  // _fem_calculated_checksum_LSB[NFEM] ^= (k[index] & 0xffff);
165  // }
166 
167 
168 
169  for ( index = 4; index < len;)
170  {
171  int word_classifier = k[index] >> 28;
172 
173  if ( (k[index] >> 28) == 0xe) // ah! another "0xe" channel
174  {
175  corrected_index_channel = index_channel^1;
176  isZeroSuppressed[corrected_index_channel] = true;
178  pre_post[0][corrected_index_channel] = (k[index] & 0x3fff);
179  pre_post[1][corrected_index_channel] = ((k[index]>>14) & 0x3fff);
180  // coutfl << " found a zp-word " << hex << "0x" << k[index] << dec << " at index " << index
181  // << " for channel " << index_channel << " " << isZeroSuppressed[index_channel] << " **** zero-suppressed " << endl;
182  index++;
183  index_channel++;
184  }
185 
186  else if ( word_classifier == 0x1) // FEM/Ch address
187  {
188  // _fem_calculated_checksum_MSB[NFEM] ^= ((k[index] >> 16 ) & 0xffff);
189  // _fem_calculated_checksum_LSB[NFEM] ^= (k[index] & 0xffff);
190 
191  NFEM = (k[index] >> 6) & 0x7;
192  CHNL = k[index] & 0x3f;
193  // coutfl << "new NFEM and channel - " << NFEM << " " << CHNL << " " << hex << k[index] << dec << endl;
194  if (NFEM != fem_nr || NFEM >= NR_FEMS)
195  {
196  coutfl << "NFEM and fem_nr differ - " << NFEM << " " << fem_nr << " " << hex << k[index] << dec << endl;
197  }
198  // we have a new channel. reset the sample and parity index, and set the channel index
199  index_sample = 0;
200  index_parity = 0;
201  index_channel = NFEM*64+CHNL;
202  corrected_index_channel = index_channel^1;
203  // we assume we are zero-suppressed and reset this if we find later that we are not
204  // isZeroSuppressed[index_channel] = true;
205 
206  if ( (k[index+1] >> 28) == 0x3) // we have a full waveform
207  {
208  index++; //move on to that word
209  for ( int c = 0; c < ( _nsamples/2 + 1) ; c++) // like for 12 samples we expect 7 words
210  {
211  if ( (k[index] >> 28) == 0x3) // normal word
212  {
213  // coutfl << " found a normal word " << hex << "0x" << k[index] << dec << " at index " << index
214  // << " for channel " << index_channel << " and " << index_sample << endl;
215  adc[index_sample++][corrected_index_channel] = k[index] & 0x3fff;
216  adc[index_sample++][corrected_index_channel] = (k[index] >> 14) & 0x3fff;
217  isZeroSuppressed[corrected_index_channel] = false; // we are ot zero-sppressed
218  // coutfl << " setting not zp for channel " << index_channel << " " << isZeroSuppressed[index_channel] << endl;
219 
220  }
221  else if ( (k[index] >> 28) == 0xe) // here is our regular pre-post word
222  {
223  pre_post[0][corrected_index_channel] = (k[index] & 0x3fff);
224  pre_post[1][corrected_index_channel] = ((k[index]>>14) & 0x3fff);
225  // coutfl << " found a regular zp-word " << hex << "0x" << k[index] << dec << " at index " << index
226  // << " for channel " << index_channel << endl;
227  }
228  else
229  {
230  // scream if that's not 0x3 nor 0xe
231  coutfl << "wrong tag! " << hex << (k[index] >> 28) << dec << " at index " << index << endl;
232  }
233  index++;
234  }
235  }
236 
237  // just in case we get a zero-suppressed word, step the index_channel
238  index_channel++;
239  }
240 
241  else if ( word_classifier == 0xb) // parity info
242  {
243  if ( index_parity == 0)
244  {
245  _fem_checksum_MSB[NFEM] = (k[index] & 0xffff);
246  index_parity++;
247  index++;
248  }
249  else
250  {
251  _fem_checksum_LSB[NFEM] = (k[index] & 0xffff);
252  index++;
253  break;
254  }
255  if ( index >= len) break;
256  }
257  }
258  return index;
259 }
260 
261 
262 int Packet_iddigitizerv3::iValue(const int sample, const int ch)
263 {
264  decode();
265 
266 
267  if ( sample >= _nsamples || sample < 0
268  || ch >= _nchannels || ch < 0 ) return 0;
269 
270  return adc[sample][ch];
271  return 0;
272 }
273 
274 int Packet_iddigitizerv3::iValue(const int n, const char *what)
275 {
276 
277  decode();
278 
279  if ( strcmp(what,"CLOCK") == 0 )
280  {
281  return _xmit_clock;
282  }
283 
284  if ( strcmp(what,"EVTNR") == 0 )
285  {
286  return _evtnr;
287  }
288 
289  if ( strcmp(what,"SAMPLES") == 0 )
290  {
291  return _nsamples;
292  }
293 
294  if ( strcmp(what,"NRMODULES") == 0 )
295  {
296  return _nr_modules;
297  }
298 
299 
300  if ( strcmp(what,"CHANNELS") == 0 )
301  {
302  return _nchannels;
303  }
304 
305  if ( strcmp(what,"DETID") == 0 )
306  {
307  return _detid;
308  }
309 
310  if ( strcmp(what,"MODULEADDRESS") == 0 )
311  {
312  return _module_address;
313  }
314 
315 
316  if ( strcmp(what,"FEMSLOT") == 0 )
317  {
318  if ( n < 0 || n >= _nr_modules) return 0;
319  return _fem_slot[n];
320  }
321 
322  if ( strcmp(what,"FEMEVTNR") == 0 )
323  {
324  if ( n < 0 || n >= _nr_modules) return 0;
325  return _fem_evtnr[n];
326  }
327 
328  if ( strcmp(what,"FEMCLOCK") == 0 )
329  {
330  if ( n < 0 || n >= _nr_modules) return 0;
331  return _fem_clock[n];
332  }
333 
334  if ( strcmp(what,"CHECKSUMMSB") == 0 )
335  {
336  if ( n < 0 || n >= _nr_modules) return 0;
337  return _fem_checksum_MSB[n];
338  }
339 
340  if ( strcmp(what,"CHECKSUMLSB") == 0 )
341  {
342  if ( n < 0 || n >= _nr_modules) return 0;
343  return _fem_checksum_LSB[n];
344  }
345 
346  if ( strcmp(what,"CALCCHECKSUMMSB") == 0 )
347  {
348  if ( n < 0 || n >= _nr_modules) return 0;
350  }
351 
352  if ( strcmp(what,"CALCCHECKSUMLSB") == 0 )
353  {
354  if ( n < 0 || n >= _nr_modules) return 0;
356  }
357 
358  // to maintain compatibility with v2, we provide those interfaces
359  // but we return -1 for "cannot be determined"
360  if ( strcmp(what,"EVENCHECKSUMOK") == 0 )
361  {
362  return -1;
363  }
364 
365  if ( strcmp(what,"ODDCHECKSUMOK") == 0 )
366  {
367  return -1;
368  }
369 
370  if ( strcmp(what,"CHECKSUMOK") == 0 )
371  {
372  return -1;
373  }
374 
375  if ( strcmp(what,"PRE") == 0 )
376  {
377  if ( n < 0 || n >= _nchannels ) return 0;
378  return pre_post[0][n];
379  }
380 
381  if ( strcmp(what,"POST") == 0 )
382  {
383  if ( n < 0 || n >= _nchannels ) return 0;
384  return pre_post[1][n];
385  }
386 
387  if ( strcmp(what,"SUPPRESSED") == 0 )
388  {
389  if ( n < 0 || n >= _nchannels ) return 0;
390  if ( isZeroSuppressed[n] ) return 1;
391  return 0;
392  }
393 
394 
395  return 0;
396 
397 }
398 
400 {
401  identify(os);
402 
403  if ( _broken)
404  {
405  os << " *** Corrupt packet " << std::endl;
406  return;
407  }
408 
409  os << "Evt Nr: " << iValue(0,"EVTNR") << std::endl;
410  os << "Clock: " << iValue(0,"CLOCK") << std::endl;
411  os << "Nr Modules: " << iValue(0,"NRMODULES") << std::endl;
412  os << "Channels: " << iValue(0,"CHANNELS") << std::endl;
413  os << "Samples: " << iValue(0,"SAMPLES") << std::endl;
414  os << "Det. ID: " << hex << "0x" << iValue(0,"DETID") << dec << std::endl;
415  os << "Mod. Addr: " << hex << "0x" << iValue(0,"MODULEADDRESS") << dec << std::endl;
416 
417  os << "FEM Slot: ";
418  for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << setw(8) << iValue(i,"FEMSLOT");
419  os << std::endl;
420 
421  os << "FEM Evt nr: ";
422  for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << setw(8) << iValue(i,"FEMEVTNR");
423  os << std::endl;
424 
425  os << "FEM Clock: ";
426  for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << setw(8) << iValue(i,"FEMCLOCK");
427  os << std::endl;
428 
429  char oldFill=os.fill('0');
430 
431  os << "FEM Checksum LSB: ";
432  for ( int i = 0; i < iValue(0,"NRMODULES"); i++)
433  {
434  os << "0x" << hex << setw(4) << iValue(i,"CHECKSUMLSB") << " " << dec;
435  }
436  os << std::endl;
437 
438  // os << "Calculated Checksum LSB: ";
439  // for ( int i = 0; i < iValue(0,"NRMODULES"); i++)
440  // {
441  // os << "0x" << hex << setw(4) << iValue(i,"CALCCHECKSUMLSB") << " " << dec;
442  // }
443  // os << std::endl;
444 
445  os << "FEM Checksum MSB: ";
446  for ( int i = 0; i < iValue(0,"NRMODULES"); i++)
447  {
448  os << "0x" << hex << setw(4) << iValue(i,"CHECKSUMMSB") << " "<< dec;
449  }
450  os << std::endl;
451 
452  // os << "Calculated Checksum MSB: ";
453  // for ( int i = 0; i < iValue(0,"NRMODULES"); i++)
454  // {
455  // os << "0x" << hex << setw(4) << iValue(i,"CALCCHECKSUMMSB") << " " << dec;
456  // }
457  // os << std::endl;
458 
459  os.fill(oldFill);
460  os << endl;
461 
462  for ( int c = 0; c < _nchannels; c++)
463  {
464  if ( iValue(c,"SUPPRESSED") )
465  {
466  os << setw(4) << c << " |-";
467  }
468  else
469  {
470  os << setw(4) << c << " | ";
471  }
472 
473 
474  os << hex;
475 
476  os << setw(6) << iValue(c, "PRE");
477  os << setw(6) << iValue(c, "POST") << " | " ;
478 
479  if ( ! iValue(c,"SUPPRESSED") )
480  {
481  for ( int s = 0; s < _nsamples; s++)
482  {
483  os << setw(6) << iValue(s,c);
484  }
485  }
486  os << dec << endl;
487  }
488 
489 }