EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
oncsSub_iddreamv0.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file oncsSub_iddreamv0.cc
1 #include "oncsSub_iddreamv0.h"
2 #include <string.h>
3 #include <iostream>
4 #include <iomanip>
5 #include <vector>
6 
7 #include <arpa/inet.h> // for htons
8 
9 
10 using namespace std;
11 
13  :oncsSubevent_w4 (data)
14 {
15 
16  _is_decoded = 0;
17 
18 
19  swapped_array = 0;
20 }
21 
23 {
24 
25  if (swapped_array) delete [] swapped_array;
26 
27  std::map <int, FEU_decoded_data *>::iterator it;
28 
29  for ( it=feu_map.begin() ; it != feu_map.end(); ++it)
30  {
31  FEU_decoded_data *fd = it->second;
32  delete fd;
33  }
34 }
35 
36 
37 int oncsSub_iddreamv0::iValue ( const int i,const char * what)
38 {
39  int nw;
40  decode (&nw);
41 
42 
43  if ( strcmp(what,"NR_FEU") == 0 )
44  {
45  return feu_map.size();
46  }
47 
48  if ( strcmp(what,"FEU_ID") == 0 )
49  {
50  unsigned ii = i;
51  if ( ii >= feu_map.size() ) return 0;
52 
53  std::map <int, FEU_decoded_data *>::const_iterator it = feu_map.begin();
54 
55  for ( int k =0; k < i; k++) ++it;
56 
57  FEU_decoded_data *fd = it->second;
58 
59  // cout << __FILE__ << " " << __LINE__ << " returning feu_id= " << fd->_feu_id << endl;
60 
61  return fd->_feu_id;
62  }
63 
64 
66  if ( !fd ) return 0;
67 
68  if ( strcmp(what,"SAMPLES") == 0 )
69  {
70  return fd->_nr_samples+1;
71  }
72 
73  if ( strcmp(what,"NR_DREAM") == 0 )
74  {
75  return fd->_nr_dreams;
76  }
77 
78  if ( strcmp(what,"PEDSUBTRACTED") == 0 )
79  {
80  return fd->_feu_P;
81  }
82 
83  if ( strcmp(what,"COMMONNOISE") == 0 )
84  {
85  return fd->_feu_C;
86  }
87 
88  if ( strcmp(what,"ZEROSUPPRESSED") == 0 )
89  {
90  return fd->_feu_Z;
91  }
92 
93 
94 
95  return 0;
96 }
97 
98 
99 int oncsSub_iddreamv0::iValue(const int feu_id, const int dreamchip, const char *what)
100 {
101 
102 
103  if ( dreamchip < 0 || dreamchip > 7) return 0;
104 
105  FEU_decoded_data * fd = feu_map[feu_id];
106  if ( !fd ) return 0;
107 
108 
109  if ( strcmp(what,"DREAM_ENABLED") == 0 )
110  {
111  return fd->_dream_enabled[dreamchip];
112  }
113 
114 
115  return 0;
116 }
117 
118 
119 int oncsSub_iddreamv0::iValue(const int channel, const int sample)
120 {
121  // int dream = channel/64;
122  //int ch = channel%64;
123  //return iValue(dream,ch,sample);
124  return 0;
125 }
126 
127 
128 int oncsSub_iddreamv0::iValue(const int feu_id, const int channel, const int sample)
129 {
130 
131  int nw;
132  decode (&nw);
133 
134  FEU_decoded_data * fd = feu_map[feu_id];
135  if ( !fd ) return 0;
136 
137  int dreamchip = channel/64;
138  int ch = channel%64;
139 
140 
141  if (! fd->_dream_enabled[dreamchip]) return 0;
142 
143  if ( dreamchip < 0 || dreamchip >=8 ) return 0;
144  if ( sample < 0 || sample > 254) return 0;
145 
146  return fd->samples[dreamchip][ch][sample];
147 }
148 
149 
151 {
152  identify(os);
153  int i;
154  int nw;
155  decode (&nw);
156 
157  os << "Nr of FEUs: " << setw(4) << iValue(0,"NR_FEU") <<endl;
158  for ( i = 0; i < iValue(0,"NR_FEU"); i++)
159  {
160  int id = iValue(i,"FEU_ID");
161  os << "FEU_ID: " << setw(4) << i << setw(4) << id << endl;
162  os << " DreamChips: " << setw(4) << iValue(id,"NR_DREAM") << " enabled: ";
163  for (int dream = 0; dream < 8; dream++)
164  {
165  if ( iValue(id, dream,"DREAM_ENABLED") )
166  {
167  os << " 1 ";
168  }
169  else
170  {
171  os << " X ";
172  }
173  }
174  os << endl;
175  os << " Nr of samples: " << setw(4) << iValue(id,"SAMPLES") <<endl;
176  os << " Pedestal subtracted " << setw(4) << iValue(id,"PEDSUBTRACTED") <<endl;
177  os << " Zero suppressed " << setw(4) << iValue(id,"ZEROSUPPRESSED") <<endl;
178  os << " Common Noise supp. " << setw(4) << iValue(id,"COMMONNOISE") <<endl;
179 
180 
181  for (int dream = 0; dream < 8; dream++)
182  {
183  if ( iValue(id,dream,"DREAM_ENABLED") )
184  {
185  os << " ---- Dream chip " << dream << " ---- " << endl;
186  os << " ch-> " ;
187  for (int channel = 0; channel < 32; channel ++)
188  {
189  os << setw(5) << channel;
190  }
191  os << endl;
192  os << "smple|" ;
193  for (int channel = 32; channel < 64; channel ++)
194  {
195  os << setw(5) << channel;
196  }
197  os << endl;
198 
199  os << "-----+-" ;
200  for (int channel = 0; channel < 32; channel ++)
201  {
202  os << "----+";
203  }
204  os << endl;
205 
206  for (int sample = 0; sample < iValue(id,"SAMPLES"); sample ++)
207  {
208  os << setw(4) << sample << " |";
209 
210  for (int channel = 0; channel < 32; channel ++)
211  {
212  int xx = iValue(id, dream*64 + channel, sample);
213  os << setw(5) << xx;
214  }
215  os << endl;
216  os << " - ";
217  for (int channel = 32; channel < 64; channel ++)
218  {
219  os << setw(5) << iValue(id, dream*64 +channel, sample);
220  }
221  os << endl;
222  }
223  os << endl;
224  }
225  }
226 
227  }
228 }
229 
230 int *oncsSub_iddreamv0::decode ( int *nwout)
231 {
232  if ( _is_decoded) return 0;
233  _is_decoded = 1; // mark this as done already
234 
235 
236 
237  unsigned short *d = (unsigned short *) &SubeventHdr->data; // here begins the payload
238  int dlength = 2 * (getLength()-4 - getPadding() );
239 
240  swapped_array = new unsigned short[dlength];
241 
242  int array_position = 0;
243  for ( int i = 0; i < dlength; i++)
244  {
245  if ( d[i] == 0xaabb && d[i+1] == 0xccdd )
246  {
247  int len = ntohs(d[i+3]) /2;
248  // cout << __FILE__ << " " << __LINE__ << " new packet, feu_id= " << feu_id << " len = " << len << endl;
249  i+=4;
250  for ( int k = 0; k < len; k++)
251  {
252  swapped_array[array_position++] = ntohs(d[i+k]);
253  }
254  i+= len-1;
255  }
256  }
257 
258  int arraylength = array_position;
259 
260  int status = decode_payload(swapped_array, arraylength);
261  if (status) cerr << __FILE__ << " " << __LINE__ << " error status from decode_payload " << status << endl;
262 
263  *nwout = 0;
264  return 0;
265 }
266 
267 
268 int oncsSub_iddreamv0::decode_payload ( unsigned short *d, const int size)
269 {
270 
271  FEU_decoded_data *fd = 0;
272 
273  int nwpacket_index = 0; // this is supposed to point to the network packet start
274  int index = 0;
275  int feu_index = 0;
276  int dream_index = 0;
277  int dream_data_length = 0;
278 
279 
280  int event_id;
281  int time_stamp;
282 
283  int sample_id =-1;
284  int fine_tstp;
285  int old_eventid = -1;
286 
287  int dream_id;
288  int feu_id;
289 
290  while ( nwpacket_index + 4 < size)
291  {
292 
293  feu_index = nwpacket_index;
294 
295  // skip leading 0's
296  while ( d[feu_index] == 0 ) feu_index++;
297 
298  // FEU header
299  index = feu_index;
300  if ( (d[index] & 0x7000) == 0x6000) // word 0
301  {
302  feu_id = d[index] & 0xff;
303 
304  // do we know this FEU?
305  if ( ! feu_map.count(feu_id) )
306  {
307  // cout << __FILE__ << " " << __LINE__ << " new feu_id= " << feu_id << " added" << endl;
308  feu_map[feu_id] = fd = new FEU_decoded_data;
309  fd->_feu_id = feu_id;
310  fd->_feu_P = 0;
311  fd->_feu_C = 0;
312  fd->_feu_Z = 0;
313  fd->_nr_samples = 0;
314  fd->_nr_dreams = 0;
315  memset (fd->samples, 0, 8*64*255*sizeof(int) );
316  memset (fd->cellids, 0, 8*64*sizeof(unsigned long long) );
317  }
318  else
319  {
320  fd = feu_map[feu_id];
321  }
322 
323  fd->_feu_P = ( d[index] >> 8) & 0x1;
324  fd->_feu_C = ( d[index] >> 9) & 0x1;
325  fd->_feu_Z = ( d[index] >> 10) & 0x1;
326 
327  } // word 0
328 
329  index = feu_index+1; // word 1
330  if ( (d[index] & 0x7000) == 0x6000)
331  {
332  event_id = d[index] & 0xfff;
333  if ( old_eventid < 0)
334  {
335  old_eventid = event_id;
336  }
337  else
338  {
339  if (old_eventid != event_id) cerr << __FILE__ << " " << __LINE__ << " feu eventid= " << event_id << " others " << old_eventid << endl;
340  }
341  }
342 
343  index = feu_index+2; // word 2
344  if ( (d[index] & 0x7000) == 0x6000)
345  {
346  time_stamp = d[index] & 0xfff;
347  }
348 
349  index = feu_index+3; // word 3
350  if ( (d[index] & 0x7000) == 0x6000)
351  {
352  sample_id = ( d[index]>> 3) & 0x1ff;
353  if ( sample_id > fd->_nr_samples) fd->_nr_samples = sample_id; // and update the max sample nr as needed
354  fine_tstp = ( d[index]) & 0x7;
355  }
356  // cout << __FILE__ << " " << __LINE__ << " FEU id " << feu_id << " event id " << event_id << " sample id " << sample_id << " maxsample " << fd->_nr_samples << endl;
357 
358  time_stamp = ( time_stamp<<3) | fine_tstp;
359 
360  index = feu_index+4 ;
361  if ( (d[index] & 0x6000) == 0x6000 ) // do we have the optional header?
362  {
363  // cout << __FILE__ << " " << __LINE__ << " skipping opt header event id " << event_id << " sample id " << sample_id << endl;
364  index += 4; // skip if so
365  }
366 
367  // done with FEU hdr -----
368 
369 
370  // We will maintain dream_index as the index to the deam chip data start
371 
372 
373  dream_index = index;
374  int done_with_this_feu = 0;
375 
376  if ( fd->_feu_Z ) // zero_suppressed data
377  {
378  // cout << __FILE__ << " " << __LINE__ << " " << hex << (d[index] & 0x7fff) << dec << endl;
379  while( ( d[index] & 0x6000) != 0x6000 ) // test if x11x == end marker
380  {
381  dream_id = ( d[index] >> 6 ) & 0x7;
382  int channel_id = d[index] & 0x3f;
383  int channel_value = d[index+1] & 0xfff;
384 
385  // cout << __FILE__ << " " << __LINE__ << " " << hex << (d[index] & 0x7fff) << dec
386  // << " dreamchip " << setw(5) << dream_id
387  // << " channel id " << setw(5) << channel_id
388  // << " channel val " << setw(5) << channel_value << endl;
389 
390  fd->samples[dream_id][channel_id][sample_id] = channel_value;
391 
392  if ( ! fd->_dream_enabled[dream_id] ) fd->_nr_dreams++; // this is a dream id we hadn't seen before
393  fd->_dream_enabled[dream_id] = 1; // mark it as "seen"
394  index += 2;
395  }
396  // cout << __FILE__ << " " << __LINE__ << " " << hex << (d[index] & 0x7fff) << dec << endl;
397  index += 2;
398 
399  nwpacket_index = dream_index = index;
400  }
401 
402  else // not Zero-suppressed data
403  {
404 
405  while( ! done_with_this_feu)
406  {
407  // first, we figure out where it ends. It should end 74 words in, but we better check.
408  // we first check that dream_index + 68 has a dream header tag, and that +73 shows the same
409  // dream id as our header here.
410 
411  if ( ( d[dream_index + 68 ] & 0x6000) == 0x4000 )
412  {
413  dream_id = (d[dream_index+3] >> 9) & 0x7;
414  int trailer_dream_id = (d[dream_index+73] >> 9) & 0x7;
415  // cout << __FILE__ << " " << __LINE__ << " dream_id= " << dream_id << " trailer_dream_id= " << trailer_dream_id << endl;
416 
417  if ( dream_id == trailer_dream_id ) // all ok
418  {
419  dream_data_length = 74;
420  }
421  else
422  {
423  return -1;
424  }
425 
426  if ( ! fd->_dream_enabled[dream_id] ) fd->_nr_dreams++; // this is a dream id we hadn't seen before
427  fd->_dream_enabled[dream_id] = 1; // mark it as "seen"
428  if ( sample_id > fd->_nr_samples) fd->_nr_samples = sample_id; // and update the max sample nr as needed
429 
430  decode_dream( fd, &d[dream_index], dream_data_length, sample_id);
431 
432  dream_index += dream_data_length;
433 
434  }
435  else
436  {
437  // cout << __FILE__ << " " << __LINE__ << " FEU trailer reached " << endl;
438  nwpacket_index = dream_index + 2;
439  // cout << __FILE__ << " " << __LINE__ << " EoE " << (( d[dream_index] >> 11) & 1) << " length " << (d[dream_index] & 0x7ff) <<dec << endl;
440  done_with_this_feu = 1;
441  }
442  }
443  }
444  }
445  return 0;
446 }
447 
448 int oncsSub_iddreamv0::decode_dream( FEU_decoded_data *fd, unsigned short *d, const int size, const unsigned int sample_nr)
449 {
450  unsigned long long cell_id;
451  unsigned long long trigger_id;
452 
453  unsigned int dream_id;
454 
455 
456  dream_id = (d[3] >> 9) & 0x7;
457 
458  if ( dream_id >=8) return -1; // can have only 0...7
459  if ( sample_nr >= 254 ) return -2; // sample id 0...255 max
460 
461  trigger_id = (d[0] & 0xfff) << 24;
462  trigger_id |= (d[1] & 0xfff) << 12;
463  trigger_id |= (d[2] & 0xfff);
464 
465  cell_id = (d[70] & 0xfff) << 24;
466  cell_id |= (d[71] & 0xfff) << 12;
467  cell_id |= (d[72] & 0xfff);
468 
469 
470  fd->cellids [dream_id][sample_nr] = cell_id;
471 
472 
473  for ( int i = 0; i < 64; i++)
474  {
475  fd->samples[dream_id][i][sample_nr] = d[4+i] & 0xfff;
476  }
477 
478  return 0;
479 }
480