EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
packet_iddigitizerv2.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file packet_iddigitizerv2.cc
1 #include "packet_iddigitizerv2.h"
2 
3 #include <string.h>
4 
5 using namespace std;
6 
8  :Packet_w4 (data)
9 {
10 
11  _nsamples = 0;
12 
13  _evtnr = 0;
14  _detid = 0;
15  _module_address = 0;
16  _clock = 0;
17  for ( int i = 0; i < 4; i++)
18  {
19  _fem_slot[i] = 0;
20  _fem_evtnr[i] = 0;
21  _fem_clock[i] = 0;
22  }
23 
24  _even_checksum = 0;
25  _odd_checksum = 0;
26 
29 
30  _even_checksum_ok = -1; // -1 convention: "cannot be evaluated", typically for 0-supp. data
31  _odd_checksum_ok = -1; // else ok =1, not ok 0.
32 
33  _nchannels = 0;
34  _is_decoded = 0;
35 
36 
37 }
38 
39 
41 {
42  // if (array) delete [][] array;
43 }
44 
45 
46 
47 const int offset=9;
48 // const int samples=12;
49 // const int channels=64;
50 
51 
53 {
54 
55  if (_is_decoded ) return 0;
56  _is_decoded = 1;
57 
58 
59  int *k;
60 
61 
62  // check later int dlength = ( getLength()-4) - getPadding();
63 
64  int *SubeventData = (int *) findPacketDataStart(packet);
65 
66  switch ( getHitFormat() )
67  {
68  case IDDIGITIZER_12S:
69  _nsamples = 12;
70  break;
71 
72  case IDDIGITIZER_16S:
73  _nsamples = 16;
74  break;
75 
76  default:
77  _nsamples = 31;
78  break;
79  }
80 
81 
82  _evtnr = SubeventData[0] & 0xffff;
83  _detid = SubeventData[2] & 0xffff;
84 
85  _module_address = SubeventData[3] & 0xffff;
86  _clock = SubeventData[4] & 0xffff;
87 
88  _fem_slot[0] = SubeventData[6] & 0xffff;
89  _fem_evtnr[0] = SubeventData[7] & 0xffff;
90  _fem_clock[0] = SubeventData[8] & 0xffff;
91 
92  // _l1_delay = (SubeventData[0] >> 16 ) & 0xff;
93  _nr_modules = 0;
94 
95 
96  int index = getDataLength() -2;
97  _even_checksum = SubeventData[index] & 0xffff;
98  // cout << __FILE__ << " " << __LINE__
99  // << hex << SubeventData[index]
100  // << " " << _even_checksum
101  // << dec << endl;
102 
103  index = getDataLength() -1;
104  _odd_checksum = SubeventData[index] & 0xffff;
105 
106  // cout << __FILE__ << " " << __LINE__
107  // << hex << SubeventData[index]
108  // << " " << _odd_checksum
109  // << dec << endl;
110 
111  k = &SubeventData[offset];
112 
113  int dlength = getDataLength() - 9 -2; // 9 header words and 2 checksums + 1 more word at the end
114 
115  for ( int index = 0; index < dlength ; index++)
116  {
117 
118  int rawtag = ((k[index] >> 16) & 0x3fff); // just so we can print it...
119  int realtag = rawtag -9;
120 
121  // now we are getting into some kludginess...
122  // if we have more than one card, he xmit injects 6 header words at the beginning.
123  // so we are skipping that header here.
124 
125  int module = 0;
126  for ( module = 0; module < 4; module++)
127  {
128  if ( realtag < (module+1) * 64 * _nsamples + 6*module ) break;
129  }
130 
131  if ( module +1 > _nr_modules)
132  {
133  _nr_modules = module +1;
134  _nchannels = _nr_modules * 64;
135  }
136 
137  // from now on, we now have to subtract those, too
138  // so for module 0, we substract 0, module 1, 6 and module 2, 12, ...
139  int tag = realtag - 6*module;
140 
141  int value = k[index] & 0x3fff;
142 
143  //no quite done... we now have to cut out the extra header words
144  // so if we have one of those 6 words, we skip
145 
146  if ( module > 0 && realtag < ( module*64*_nsamples + 6*module ) )
147  {
148 
149  if ( realtag == module*64*_nsamples +2 + 6*(module -1) ) // leftover FEM header word
150  {
151  _fem_slot[module] = k[index+1] & 0xff; // slot number
152  _fem_evtnr[module] = k[index+2] & 0xffff; // fem event nr
153  _fem_clock[module] = k[index+3] & 0xffff; // fem clock
154 
155  }
156 
157  // cout << __FILE__ << " " << __LINE__ << " skipping module " << module << " realtag: " << realtag << " " << module*64*_nsamples + 6*module << " " << hex << value << dec << endl;
158 
159  continue;
160  }
161 
162 
163  int channelpair = (tag / _nsamples) & 0xfffe;
164  int ch = channelpair; // even tag -> lower channel
165  if ( tag & 1) ch++; // odd tag -> 2nd channel
166 
167  int sample = (tag/2) % _nsamples;
168 
169  // cout << __FILE__ << " " << __LINE__
170  // << " rawtag " << hex << rawtag
171  // << " realtag " << dec << realtag
172  // << " tagword " << dec << tag
173  // << " module " << dec << module
174  // << " channel " << dec << " " << ch
175  // << " sample " << sample
176  // << " value " << hex << " " << value << dec << endl;
177 
178  array[sample][ch] = value;
179 
180  }
181 
182 
183  for ( index = 5; index < getDataLength()-3; index+=2) // -3 to spare the CS fields out
184  {
185  _calculated_even_checksum ^= SubeventData[index] & 0xffff;
186  _calculated_odd_checksum ^= SubeventData[index+1] & 0xffff;
187  }
188 
189  return 0;
190 }
191 
192 
193 int Packet_iddigitizerv2::iValue(const int sample, const int ch)
194 {
195  decode();
196 
197  if ( sample >= _nsamples || sample < 0
198  || ch >= _nchannels || ch < 0 ) return 0;
199 
200  return array[sample][ch];
201 
202 }
203 
204 int Packet_iddigitizerv2::iValue(const int n, const char *what)
205 {
206 
207  decode();
208 
209  if ( strcmp(what,"CLOCK") == 0 )
210  {
211  return _clock;
212  }
213 
214  if ( strcmp(what,"EVTNR") == 0 )
215  {
216  return _evtnr;
217  }
218 
219  if ( strcmp(what,"SAMPLES") == 0 )
220  {
221  return _nsamples;
222  }
223 
224  if ( strcmp(what,"NRMODULES") == 0 )
225  {
226  return _nr_modules;
227  }
228 
229 
230  if ( strcmp(what,"CHANNELS") == 0 )
231  {
232  return _nchannels;
233  }
234 
235  if ( strcmp(what,"DETID") == 0 )
236  {
237  return _detid;
238  }
239 
240  if ( strcmp(what,"MODULEADDRESS") == 0 )
241  {
242  return _module_address;
243  }
244 
245 
246  if ( strcmp(what,"FEMSLOT") == 0 )
247  {
248  if ( n < 0 || n >= _nr_modules) return 0;
249  return _fem_slot[n];
250  }
251 
252  if ( strcmp(what,"FEMEVTNR") == 0 )
253  {
254  if ( n < 0 || n >= _nr_modules) return 0;
255  return _fem_evtnr[n];
256  }
257 
258  if ( strcmp(what,"FEMCLOCK") == 0 )
259  {
260  if ( n < 0 || n >= _nr_modules) return 0;
261  return _fem_clock[n];
262  }
263 
264  if ( strcmp(what,"EVENCHECKSUM") == 0 )
265  {
266  return _even_checksum;
267  }
268 
269  if ( strcmp(what,"ODDCHECKSUM") == 0 )
270  {
271  return _odd_checksum;
272  }
273 
274  if ( strcmp(what,"CALCEVENCHECKSUM") == 0 )
275  {
277  }
278 
279  if ( strcmp(what,"CALCODDCHECKSUM") == 0 )
280  {
282  }
283 
284  if ( strcmp(what,"EVENCHECKSUMOK") == 0 )
285  {
286  if ( _calculated_even_checksum < 0 ) return -1; // cannot evaluate
287  if ( _even_checksum == _calculated_even_checksum) return 1;
288  return 0;
289  }
290 
291  if ( strcmp(what,"ODDCHECKSUMOK") == 0 )
292  {
293  if ( _calculated_odd_checksum < 0 ) return -1; // cannot evaluate
294  if ( _odd_checksum == _calculated_odd_checksum) return 1;
295  return 0;
296  }
297 
298  return 0;
299 
300 }
301 
303 {
304  identify(os);
305 
306  os << "Evt Nr: " << iValue(0,"EVTNR") << std::endl;
307  os << "Clock: " << iValue(0,"CLOCK") << std::endl;
308  os << "Nr Modules: " << iValue(0,"NRMODULES") << std::endl;
309  os << "Channels: " << iValue(0,"CHANNELS") << std::endl;
310  os << "Samples: " << iValue(0,"SAMPLES") << std::endl;
311  os << "Det. ID: " << hex << "0x" << iValue(0,"DETID") << dec << std::endl;
312  os << "Mod. Addr: " << hex << "0x" << iValue(0,"MODULEADDRESS") << dec << std::endl;
313 
314  os << "FEM Slot: ";
315  for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << setw(8) << iValue(i,"FEMSLOT");
316  os << std::endl;
317 
318  os << "FEM Evt nr: ";
319  for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << setw(8) << iValue(i,"FEMEVTNR");
320  os << std::endl;
321 
322  os << "FEM Clock: ";
323  for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << setw(8) << iValue(i,"FEMCLOCK");
324  os << std::endl;
325 
326  os << "Even chksum: 0x" << hex << iValue(0,"EVENCHECKSUM") << " calculated: 0x" << iValue(0,"CALCEVENCHECKSUM");
327  if ( iValue(0,"EVENCHECKSUMOK") == 1) os << " ok" << endl;
328  else if ( iValue(0,"EVENCHECKSUMOK") == 0) os << " **wrong" << endl;
329 
330  os << "Odd chksum: 0x" << hex << iValue(0,"ODDCHECKSUM") << " calculated: 0x" << iValue(0,"CALCODDCHECKSUM");
331  if ( iValue(0,"ODDCHECKSUMOK") == 1) os << " ok" << endl;
332  else if ( iValue(0,"ODDCHECKSUMOK") == 0) os << " **wrong" << endl;
333  os << dec << endl;
334 
335  for ( int c = 0; c < _nchannels; c++)
336  {
337  os << setw(4) << c << " | ";
338 
339  os << hex;
340  for ( int s = 0; s < _nsamples; s++)
341  {
342  os << setw(6) << iValue(s,c);
343  }
344  os << dec << endl;
345  }
346 
347 }