ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
oncsSub_idfnalmwpcv2.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file oncsSub_idfnalmwpcv2.cc
1 #include "oncsSub_idfnalmwpcv2.h"
2 
3 // for ntohl and ntohs
4 #include <arpa/inet.h>
5 #include <cstring>
6 
7 
8 using namespace std;
9 
11  :oncsSubevent_w4 (data)
12 {
13  n_tdcs = 0;
14  length= 0;
15  _decoded = 0;
16 
17  // initialize all to 0
18  memset (&spillinfo, 0 , sizeof(spillinfo) );
19  memset (tsh, 0 , MAXNROFTDCS * sizeof(TDCspillheader) );
20 
21 }
22 
24 
25 
26 int *oncsSub_idfnalmwpcv2::decode ( int *nwout)
27 {
28 
29  if ( _decoded) return 0;
30 
31  _decoded = 1;
32 
33  int i;
34 
35  int *d = (int *) &SubeventHdr->data; // here begins the payload
36 
37  tdcmask = d[0];
38 
39  // count the number of "on" bits = number of TDCs
40  n_tdcs=0;
41  for ( i = 0; i < MAXNROFTDCS; i++)
42  {
43  if ( (1<< i) & tdcmask ) n_tdcs++;
44  }
45 
46 
47  int length = ntohl ( d[1] );
48  spillinfo.spillwords = length; // in 16bit units
49  // cout << __FILE__ << " " << __LINE__ << "Spillwords " << length << endl;
50 
51  //we now subtract 2 to remove the header length
52  length -= 2;
53 
54  // dlength is the remaining payload length without the
55  // length word in 16bit units - we subtract 8 bytes for the mask and length
56  int dlength = 2 * ( getLength()-getPadding() ) -8 ;
57 
58  // length is the length of the entire spill stucture without the length
59  // in 16bit words; we do a consistency check
60  if (length > dlength ) return 0;
61 
62  unsigned short *s = ( unsigned short *) &d[1];
63 
64  //pre-swap the payload
65  for ( i = 0; i < length; i++)
66  {
67  *s = ntohs(*s);
68  s++;
69  }
70 
71  // s = ( unsigned short *) &d[1];
72  // for ( i = 100; i < 200; i++)
73  // {
74  // cout << setw(4) << i << " " << hex << s[i] << dec << endl;
75  // }
76 
77 
78 
79  //and reset the "s" pointer
80  // we make it so that "pos" point to the position in the payload
81  // so we can think in terms of the counts in teh docs
82  s = ( unsigned short *) &d[1];
83  int pos = 2; // we have digested 0 and 1
84 
85  short v;
86 
87  spillinfo.spillcounter = s[pos++];
88  //cout << __FILE__ << " " << __LINE__ << "spillinfo.spillcounter " << spillinfo.spillcounter << endl;
89 
90  v = s[pos++];
91  spillinfo.year = ( v>> 8 ) & 0xff;
92  spillinfo.month = v & 0xff;
93 
94  v = s[pos++];
95  spillinfo.day = ( v>> 8 ) & 0xff;
96  spillinfo.hour = v & 0xff;
97 
98  v = s[pos++];
99  spillinfo.minute = ( v>> 8 ) & 0xff;
100  spillinfo.second = v & 0xff;
101 
102  // Spill trigger count 32bits
103  int x = s[pos++]; //MSB
104  x <<=16;
105  spillinfo.triggercount = x + s[pos++]; //LSB
106 
107  // cout << __FILE__ << " " << __LINE__ << " spillinfo.triggercount " << spillinfo.triggercount << endl;
108 
109  spillinfo.TDC_Status_Bits = s[pos++];
111 
112  //cout << __FILE__ << " " << __LINE__ << " spillinfo.TDC_Status_Bits " << spillinfo.TDC_Status_Bits << endl;
113  //cout << __FILE__ << " " << __LINE__ << " spillinfo.Spill_Link_Status_Bits " << spillinfo.Spill_Link_Status_Bits << endl;
114 
115 
116  TDCEvent *te;
117 
118 
119  // we now push, up front, one event structure on the vector
120  // for each trigger so we know that we have one for each event
121  for ( i = 0; i< spillinfo.triggercount; i++)
122  {
123  te = new TDCEvent;
124  memset ( te, 0, sizeof(TDCEvent) );
125  TDCEventVector.push_back ( te);
126  }
127 
128  // fill the WireChamberTdcSpillHeader (per TDC)
129  for ( i = 0; i< n_tdcs; i++)
130  {
131 
132  // cout << __FILE__ << " " << __LINE__ << " pos, value " << setw(4) << pos << " " << hex << s[pos] << dec << endl;
133  tsh[i].spillwords = s[pos++] << 16; // we get a 32bit value
134  tsh[i].spillwords += s[pos++] ;
135  //cout << __FILE__ << " " << __LINE__ << " i, spillwords, " << i << " " << tsh[i].spillwords << endl;
136 
137  tsh[i].TDC = s[pos++] -1;
138 
139  //cout << __FILE__ << " " << __LINE__ << " i, TDC " << i << " " << tsh[i].TDC << endl;
140 
141  tsh[i].spilltriggercount = pos++ << 16;
142  tsh[i].spilltriggercount += pos++;
143  //cout << __FILE__ << " " << __LINE__ << " spilltriggercount " << tsh[i].spilltriggercount << endl;
144 
145  tsh[i].spillstatus = s[pos++];
146  }
147 
148  int old_trigger_number = -1;
149 
150 
151  // here we keep the pos at the same value for a while
152  while (pos < length)
153  {
154  // cout << __FILE__ << " " << __LINE__ << " Event hdr: pos, value, length " << setw(4) << pos << " " << hex << s[pos] << dec << " " << length << endl;
155  int EventWordCount = s[pos];
156  // cout << __FILE__ << " " << __LINE__ << " EventWordCount " << EventWordCount << endl;
157 
158  short tdcindex = s[pos+1] - 1; // the controller counts like fortran
159  //cout << __FILE__ << " " << __LINE__ << " tdcindex " << tdcindex << endl;
160  if ( tdcindex >= MAXNROFTDCS ) // sanity check
161  {
162  cout << __LINE__ << " " << __FILE__
163  << " wrong TDC index " << tdcindex << " pos= " << pos-1 << endl;
164  }
165 
166 
167  //cout << __FILE__ << " " << __LINE__ << " pos, value " << setw(4) << pos << " " << hex << s[pos] << dec << endl;
168  int SpillTriggerCount = s[pos+3]<<16; // we get a 32bit value
169  SpillTriggerCount += s[pos+4] -1;
170 
171  if ( SpillTriggerCount <0 || SpillTriggerCount >= spillinfo.triggercount )
172  {
173  cout << __LINE__ << " " << __FILE__
174  << " wrong Trigger number " << SpillTriggerCount << " pos= " << pos << endl;
175  return 0;
176  }
177 
178  //cout << __FILE__ << " " << __LINE__ << " SpillTriggerCount " << SpillTriggerCount << endl;
179 
180  if ( SpillTriggerCount != old_trigger_number ) // ok, new event/trigger, so we get the next TDCEvent
181  {
182  old_trigger_number = SpillTriggerCount;
183  te = TDCEventVector[SpillTriggerCount];
184  te->trigger_nr = SpillTriggerCount;
185  te->evt_timestamp = s[pos+5];
186  te->local_ts_upper = s[pos+6];
187  te->local_ts_lower = s[pos+7];
188 
189  // quick sanity check: bits 3...11 of
190  // the timstamp must be equal to the
191  // 9 lsb's of te->local_ts_lower
192 
193  // cout << " time stamps " << hex
194  // << ( ( te->evt_timestamp>>3) &0x1ff ) << " "
195  // << ( te->local_ts_lower & 0x1ff) << dec << endl;
196 
197 
198  // now we construct the long 35 bit 800MHz time stamp
199  // cout << "time stamps " << hex
200  // << te->evt_timestamp << " "
201  // << te->local_ts_upper << " "
202  // << te->local_ts_lower << dec << endl;
203 
204  te->absolute_time = te->local_ts_upper;
205  te->absolute_time <<= 16;
206  te->absolute_time += te->local_ts_lower;
207  te->absolute_time <<= 3;
208  te->absolute_time += ( te->evt_timestamp &0x3);
209  // and we clear the TDCData structures
210  memset ( te->td, 0, MAXNROFTDCS * sizeof( TDCData) );
211 
212  // we are done with filling in the new event "header" structure
213  // now we fill in the TCDData structure. some of this
214  // is redundant to the header info, that's why we kept "pos" frozen
215  }
216 
217  te->td[tdcindex].words = EventWordCount;
218  te->td[tdcindex].TDC = tdcindex;
219  te->td[tdcindex].EventStatus =s[pos+2];
220  te->td[tdcindex].triggertype =s[pos+5];
221 
222  // this may look redundant with the code above, but is actually
223  // per TDC info - the abve was per event. Should match, and we fill it in
224  // so the user can perform a sanity check
225  te->td[tdcindex].evt_timestamp = s[pos+6];
226  te->td[tdcindex].local_ts_upper = s[pos+7];
227  te->td[tdcindex].local_ts_lower = s[pos+8];
228 
229  // now we construct the long 35 bit 800MHz time stamp
230  te->td[tdcindex].absolute_time = te->td[tdcindex].local_ts_upper;
231  te->td[tdcindex].absolute_time <<= 16;
232  te->td[tdcindex].absolute_time += te->td[tdcindex].local_ts_lower;
233  te->td[tdcindex].absolute_time <<= 3;
234  te->td[tdcindex].absolute_time += ( te->td[tdcindex].evt_timestamp &0x7);
235 
236  // at long last, the business end of this TDC - the TDC hit
237  int xpos = pos+9; // that's where the hits start
238  for ( i = 0; i < te->td[tdcindex].words -9; i++) // so many hits, header is 9 long
239  {
240  te->td[tdcindex].hits++; // this is the same as the TDCHitlist.size()
241 
242  TDC_hit *th = new TDC_hit;
243  te->td[tdcindex].TDCHitlist.push_back ( th );
244 
245  short h = s[xpos+i]; // this is now the TDC word
246  th->wire = ( h >> 10) & 0x3f; // upper bits are "wire"
247  th->timestamp = h & 0x3ff; // lower 10 bits are "timestamp"
248 
249  }
250  pos += EventWordCount; // -1 because we stepped "pos" one position in already
251  }
252 
253 
254 
255  return 0;
256 }
257 
258 int oncsSub_idfnalmwpcv2::iValue(const int ich,const char *what)
259 {
260 
261  decode (0);
262  if ( strcmp(what,"NTDCS") == 0 )
263  {
264  return n_tdcs;
265  }
266 
267  else if ( strcmp(what,"TRIGGERCOUNT") == 0 )
268  {
269  return spillinfo.triggercount;
270  }
271 
272  else if ( strcmp(what,"SPILLCOUNTER") == 0 )
273  {
274  return spillinfo.spillcounter;
275  }
276 
277  else if ( strcmp(what,"TDCSTATUSBITS") == 0 )
278  {
279  return spillinfo.TDC_Status_Bits;
280  }
281 
282  else if ( strcmp(what,"LINKSTATUSBITS") == 0 )
283  {
285  }
286 
287  else if ( strcmp(what,"MONTH") == 0 )
288  {
289  return spillinfo.month;
290  }
291 
292  else if ( strcmp(what,"DAY") == 0 )
293  {
294  return spillinfo.day;
295  }
296 
297  else if ( strcmp(what,"YEAR") == 0 )
298  {
299  return spillinfo.year;
300  }
301 
302  else if ( strcmp(what,"HOUR") == 0 )
303  {
304  return spillinfo.hour;
305  }
306 
307  else if ( strcmp(what,"MINUTE") == 0 )
308  {
309  return spillinfo.minute;
310  }
311 
312  else if ( strcmp(what,"SECOND") == 0 )
313  {
314  return spillinfo.second;
315  }
316 
317  return 0;
318 
319 }
320 
321 
322 int oncsSub_idfnalmwpcv2::iValue(const int trigger ,const int tdc, const int index)
323 {
324  decode (0);
325  if ( trigger < 0 || (unsigned int ) trigger >= TDCEventVector.size()) return 0;
326  if ( tdc < 0 || tdc >= n_tdcs) return 0;
327  if ( index < 0 || index >= TDCEventVector[trigger]->td[tdc].hits) return 0;
328 
329  return TDCEventVector[trigger]->td[tdc].TDCHitlist[index]->wire;
330 }
331 
332 int oncsSub_idfnalmwpcv2::iValue(const int trigger ,const int tdc, const char *what)
333 {
334  decode (0);
335  if ( trigger < 0 || (unsigned int )trigger >= TDCEventVector.size()) return 0;
336  if ( tdc < 0 || tdc >= n_tdcs) return 0;
337 
338 
339  if ( strcmp(what,"HITS") == 0 )
340  {
341  if ( (unsigned int ) trigger >= TDCEventVector.size() )
342  {
343  cout << __LINE__ << " " << __FILE__ << " wrong trigger " << trigger << " max " << TDCEventVector.size() << endl;
344  return 0;
345  }
346 
347  return TDCEventVector[trigger]->td[tdc].hits;
348  }
349  else if ( strcmp(what,"TDC") == 0 )
350  {
351  return TDCEventVector[trigger]->td[tdc].TDC;
352  }
353 
354  return 0;
355 }
356 
357 int oncsSub_idfnalmwpcv2::iValue(const int trigger ,const int tdc, const int index, const char *what)
358 {
359  decode (0);
360  if ( trigger < 0 || (unsigned int )trigger >= TDCEventVector.size()) return 0;
361  if ( tdc < 0 || tdc >= n_tdcs) return 0;
362  if ( index < 0 || index >= TDCEventVector[trigger]->td[tdc].hits) return 0;
363 
364 
365  if ( strcmp(what,"WIRE") == 0 )
366  {
367  return iValue(trigger, tdc, index);
368  }
369 
370  else if ( strcmp(what,"TIMESTAMP") == 0 )
371  {
372  return TDCEventVector[trigger]->td[tdc].TDCHitlist[index]->timestamp;
373  }
374 
375 
376  return 0;
377 }
378 
380 {
381 
382  decode (0);
383  identify(os);
384 
385  int j, k, l;
386 
387 
388  os << " Date " << iValue(0, "MONTH")
389  << "/" << iValue(0,"DAY")
390  << "/20" << iValue(0,"YEAR")
391  << " " << iValue(0,"HOUR")
392  << ":" << iValue(0,"MINUTE")
393  << ":" << iValue(0,"SECOND") << endl;
394 
395  os << " Spill Counter " << iValue(0,"SPILLCOUNTER") << endl;
396 
397  int tc = iValue(0,"TRIGGERCOUNT");
398 
399  os << " Trigger Count " << tc << endl;
400  os << " TDC Status Bits " << hex << iValue(0,"TDCSTATUSBITS") << dec << endl;
401  os << " Link Status bits " << hex << iValue(0,"LINKSTATUSBITS") << dec << endl;
402 
403  for ( k = 0; k < tc; k++)
404  {
405 
406  os << " new event "
407  << " trg# tdc hit wire timestamp" << endl;
408 
409  for ( l = 0; l < iValue(0,"NTDCS"); l++)
410  {
411  int hits =iValue ( k, l, "HITS");
412  if ( hits)
413  {
414  int tdc = iValue(k,l,"TDC");
415 
416  for ( j = 0; j < hits; j++)
417  {
418  os << " " << setw(6) << k
419  << setw(8) << tdc << setw(8) << j
420  << setw (8) << iValue(k,l,j)
421  << setw(8) << iValue(k,l,j,"TIMESTAMP") << endl;
422  }
423  }
424  }
425  }
426  os << endl;
427 
428 
429 
430 }
431