ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
S800.cxx
Go to the documentation of this file.
1 #include "S800.h"
2 
3 #include "S800defs.h"
4 
5 #include <cstdio>
6 
7 int S800::DecodeS800(unsigned short *pevent, unsigned short twords)
8 {
9  long long int n;
10  unsigned short *p = pevent, sublength, plength, ptag, ID;
11  unsigned short nwords, words;
12  //++p;
13  bool found = false;
14 
15  // twords--; // total event length is self-inclusive
16 
17  // Loop over sub-events until the right one is found
18  while (twords > 0) {
19  nwords = *p;
20  ++p;
21  // cout << "nwords: " << nwords << ". twords: " << twords << endl;
22  sublength = nwords;
23  // cout << "sublength: " << sublength << endl;
24  nwords--;
25  if (*p++ != S800_PACKET) {
26  twords -= sublength;
27  p += sublength - 2;
28  } else {
29  nwords--;
30  found = true;
31  // fhasdata = true;
32  break;
33  }
34  }
35  if (!found)
36  return 0;
37 
38  // Unpack S800 data in tree
39  if (*p++ != S800_VERSION) {
40  std::cout << "DecodedEvent: "
41  << "Wrong version of S800 sub-event. Aborting ..." << std::endl;
42  return 1;
43  }
44  nwords--;
45  while (nwords > 0) {
46  plength = *p;
47  ++p;
48  ptag = *p;
49  ++p;
50  switch (ptag) {
52  // cout << "Trigger: " << hex << S800_TRIGGER_PACKET << dec << endl;
53  p = DecodeS800Trigger(p);
54  break;
55 
56  case S800_TOF_PACKET:
57  // cout << "Tofr: " << hex << S800_TOF_PACKET << dec << endl;
59  break;
60 
62  // cout << "FP SCINT: " << hex << S800_FP_SCINT_PACKET << dec << endl;
63  words = plength - 2;
64  while (words > 0) {
65  ID = ((*p) & 0xF000) >> 12;
66  p = DecodeS800Scintillator(p, ID, ID / 2);
67  words -= 2;
68  }
69  break;
70 
72  // cout << "CRDC: " << hex << S800_FP_CRDC_PACKET << dec << endl;
73  ID = *p;
74  ++p;
75  // std::cout << "ID " << ID << std::endl;
76  p = DecodeS800Crdc(p, ID);
77  break;
78 
79  case S800_FP_IC_PACKET:
80  // cout << "FP_IC: " << hex << S800_FP_IC_PACKET << dec << endl;
81  p = DecodeS800IonChamber(p);
82  break;
83 
85  // cout << "TIMESTAMP: " << hex << S800_TIMESTAMP_PACKET << dec << endl;
86  n = *p++;
87  n = (*p++ << 16 | n);
88  n = (*p++ << 16 | n);
89  n = (*p++ << 16 | n);
90  this->SetInternalTS(n);
91  break;
92 
94  // cout << "EVENT_NUMBER: " << hex << S800_EVENT_NUMBER_PACKET << dec << endl;
95  n = *p++;
96  n = (*p++ << 16 | n);
97  n = (*p++ << 16 | n);
98  this->SetEvtNr(n);
99  break;
100 
101  case S800_FP_HODO_PACKET:
102  // cout << "HODO: " << hex << S800_FP_HODO_PACKET << dec << endl;
103  p = DecodeS800HodoScope(p);
104  break;
105  case S800_VME_TDC_PACKET:
106  // cout << "VME_TDC: " << hex << S800_VME_TDC_PACKET << dec << endl;
108  break;
109  default: // S800_II_CRDC_PACKET, S800_II_TRACK_PACKET...
110  p += plength - 2;
111  break;
112  }
113  nwords -= plength;
114  }
115  // this->SetTS(ts);
116  // if(ffirst_ts<1){
117  // ffirst_ts = ts;
118  // }
119 
120  return 0;
121 }
122 
123 unsigned short *S800::DecodeS800TimeOfFlight(unsigned short *p)
124 {
125 
126  UShort_t words = (*(p - 2)) - 2, ch, dum;
127  Short_t rf = -1;
128  Short_t obj = -1;
129  Short_t xfp = -1;
130  Short_t si = -1;
131  Short_t tac_obj = -1;
132  Short_t tac_xfp = -1;
133  while (words > 0) {
134  ch = ((*p) & 0xf000) >> 12;
135  int tmp = *p;
136  ++p;
137  if (ch == 12)
138  rf = (tmp)&0xfff;
139  else if (ch == 13)
140  obj = (tmp)&0xfff;
141  else if (ch == 14)
142  xfp = (tmp)&0xfff;
143  else if (ch == 15)
144  si = (tmp)&0xfff;
145  else if (ch == 5)
146  tac_obj = (tmp)&0xfff;
147  else if (ch == 4)
148  tac_xfp = (tmp)&0xfff;
149  else if (ch > 0 && ch < 8)
150  dum = (tmp)&0xfff; // NOLINT
151  words--;
152  }
153  this->GetTimeOfFlight()->Set(rf, obj, xfp, si);
154  this->GetTimeOfFlight()->SetTAC(tac_obj, tac_xfp);
155  return p;
156 }
157 
158 unsigned short *S800::DecodeS800Trigger(unsigned short *p)
159 {
160  UShort_t words = (*(p - 2)) - 2, ch;
161  int registr = -1;
162  int s800 = -1;
163  int external1 = -1;
164  int external2 = -1;
165  int secondary = -1;
166  registr = *p++;
167  words--;
168  while (words > 0) {
169  ch = ((*p) & 0xf000) >> 12;
170  if (ch == 8)
171  s800 = (*p++) & 0xfff;
172  if (ch == 9)
173  external1 = (*p++) & 0xfff;
174  if (ch == 10)
175  external2 = (*p++) & 0xfff;
176  if (ch == 11)
177  secondary = (*p++) & 0xfff;
178  words--;
179  }
180  this->GetTrigger()->Set(registr, s800, external1, external2, secondary);
181  return p;
182 }
183 
184 unsigned short *S800::DecodeS800Scintillator(unsigned short *p, unsigned short updown, int id)
185 {
186  int de_up = -1;
187  int time_up = -1;
188  int de_down = -1;
189  int time_down = -1;
190 
191  // Even updown: UP channels. Odd ID: DOWN channels
192  if (updown % 2 == 0) {
193  de_up = (*p++) & 0xfff;
194  time_up = (*p++) & 0xfff;
195  } else {
196  de_down = (*p++) & 0xfff;
197  time_down = (*p++) & 0xfff;
198  }
199  this->GetScintillator(id)->SetID(id);
200  this->GetScintillator(id)->Set(de_up, time_up, de_down, time_down);
201  return p;
202 }
203 
204 unsigned short *S800::DecodeS800HodoScope(unsigned short *p)
205 {
206  UShort_t words = (*(p - 2)) - 2;
207  UShort_t id;
208  UShort_t ch;
209  UShort_t energy;
210  while (words > 0) {
211  id = *p;
212  if (id == 0) {
213  p++;
214  words--;
215  while (words > 0) {
216  ch = (((*p) & 0xF000) >> 12);
217  energy = ((*p) & 0x0FFF);
218  this->GetHodoscope(ch)->SetEnergy((Int_t)energy);
219  p++;
220  words--;
221  }
222  } else if (id == 1) {
223  p++;
224  words--;
225  while (words > 0) {
226  ch = (((*p) & 0xF000) >> 12) + 16;
227  energy = ((*p) & 0x0FFF);
228  this->GetHodoscope(ch)->SetEnergy((Int_t)energy);
229  p++;
230  words--;
231  }
232  } else if (id == 2) {
233  p++;
234  words--;
235  while (words > 0) {
236  // coincidence register A (for the first 16 channels)
237  p++;
238  words--;
239  // coincidence register B (for the second 16 channels)
240  p++;
241  words--;
242  // TAC time
243  p++;
244  words--;
245  }
246  } else {
247  p++;
248  words--;
249  }
250  }
251  return p;
252 }
253 
254 unsigned short *S800::DecodeS800Crdc(unsigned short *p, int id)
255 {
256  UShort_t anode = -1;
257  UShort_t tac = -1;
258  this->GetCrdc(id)->SetID(id);
259 
260  Int_t tag;
261  tag = S800_FP_CRDC_PACKET;
262  if (*(p + 1) == tag + 1) {
263  p = DecodeS800CrdcRaw(p, id);
264  }
265  if (*(p + 1) == tag + 5) {
266  anode = *(p + 2);
267  tac = *(p + 3);
268  p += 4;
269  }
270  this->GetCrdc(id)->SetAnodeTAC(anode, tac);
271 
272  return p;
273 }
274 
275 unsigned short *S800::DecodeS800IonChamber(unsigned short *p)
276 {
277  UShort_t ch = -1;
278  UShort_t raw = -1;
279  if (*(p + 1) == S800_FP_IC_ENERGY_PACKET) {
280  // IC packet with times
281  UShort_t length;
282  length = *p++;
283  p++;
284  length -= 2;
285  while (length > 0) {
286  ch = ((*p) & 0xf000) >> 12;
287  raw = (*p++) & 0xfff;
288  length--;
289  this->GetIonChamber()->Set(ch, raw);
290  }
291  } else {
292  // Old style IC packet
293  UShort_t words = (*(p - 2)) - 2;
294  while (words > 0) {
295  ch = ((*p) & 0xf000) >> 12;
296  raw = (*p++) & 0xfff;
297  words--;
298  this->GetIonChamber()->Set(ch, raw);
299  }
300  }
301 
302  return p;
303 }
304 
305 unsigned short *S800::DecodeS800CrdcRaw(unsigned short *p, int id)
306 {
307  static ULong_t total = 0, failed = 0;
308  Short_t sampleBegin = 0, sampleWidth, isample, ichannel, cdata[4], connector, previous_sample = 0, ch, sindex = 0,
309  previous_channel = 0, m_sampleWidth = 0; // Added Simon
310  Short_t maxwidth = S800_CRDC_MAXWIDTH;
311  Short_t channels;
312  channels = S800_FP_CRDC_CHANNELS;
313 
314  unsigned short *pStore = p;
315  bool mes1 = true, mes2 = true, mes3 = true, mes4 = true;
316  bool debug = S800_DEBUG;
317  UShort_t length = *p++;
318  short i = length - 3;
319  p++; // skip packet id
320  UShort_t threshold = *p++;
321 
322  unsigned short data_test[256][32]; // Added Simon
323  memset(data_test, 0, sizeof(data_test)); // Added Simon
324 
325  while (i > 0) {
326  if ((*p) >> 15 != 1) {
327  std::cout << "DecodedEvent: "
328  << "CRDC data is corrupted!" << std::endl;
329  p++;
330  i--;
331  continue;
332  } else {
333  isample = ((*p) & 0x7FC0) >> 6;
334  ichannel = (*p) & 0x003F;
335  if (i == length - 3) {
336  sampleBegin = isample;
337  previous_sample = isample;
338  }
339  if (previous_channel > ichannel)
340  sindex++; // Added Simon
341  previous_channel = ichannel; // Added Simon
342  }
343  p++;
344  i--;
345  memset(cdata, 0, sizeof(cdata));
346  while ((*p) >> 15 == 0) {
347  connector = ((*p) & 0x0C00) >> 10;
348  cdata[connector] = (*p) & 0x3FF;
349  p++;
350  i--;
351  if (i == 0)
352  break;
353  }
354  if (isample < sampleBegin || isample > sampleBegin + maxwidth) {
355  if (debug)
356  printf("Warning in Crdc Unpack: inconsistent sample number: %d (first: %d)\n", isample, sampleBegin);
357  mes1 = false;
358  // continue;//Commented Simon
359  }
360  if (isample < previous_sample) {
361  if (debug)
362  printf("Warning in Crdc Unpack: sample number lower than previous: %d (previous: %d)\n", isample,
363  previous_sample);
364  mes2 = false;
365  // continue;//Commented Simon
366  }
367  previous_sample = isample;
368  for (int j = 0; j < 4; j++) {
369  ch = ichannel + j * 64;
370  if (cdata[j] != 0 && ch < channels) {
371  if (cdata[j] < threshold) {
372  if (debug)
373  printf("Warning in Crdc Unpack: data lower than threshold: %d (threshold: %d)\n", cdata[j],
374  threshold);
375  mes3 = false;
376  } else {
377  // std::cout << "ch " << ch << " cdata[j]" << cdata[j] << " isample " << isample << std::endl;
378  this->GetCrdc(id)->Set(cdata[j], isample, ch);
379  data_test[ch][sindex] = cdata[j]; // Added Simon
380  }
381  } else if (cdata[j] != 0 && ch >= channels) {
382  if (debug) {
383  printf("Warning in Crdc Unpack: channel greater than limit: %d (limit: %d)\n", ch, channels);
384  }
385  mes4 = false;
386  }
387  }
388  m_sampleWidth = sindex + 1; // Added Simon
389  sampleWidth = isample - sampleBegin + 1;
390  this->GetCrdc(id)->SetSampleWidth(sampleWidth);
391  }
392 
394  // Integrate samples into pads (and subtract pedestals)
395  for (int q = 0; q < channels; q++) {
396  this->GetCrdc_test()->Set_raw(id, q, -1);
397  int nsamples = 0; // added to fix bug
398  for (int s = 0; s < m_sampleWidth; s++) {
399  if (data_test[q][s] != 0) {
400  nsamples++; // added to fix bug
401  // raw[q] += (data[q][s] - ped[q]) / sampleWidth;
402  // raw_test[q] += (data[q][s] - ped[q]);
403  this->GetCrdc_test()->Set_raw(
404  id, q, this->GetCrdc_test()->Get_raw(id, q) + (data_test[q][s])); // ! have to remove the pedestals
405  }
406  }
407  if (nsamples > 0) {
408  this->GetCrdc_test()->Set_raw(id, q, (this->GetCrdc_test()->Get_raw(id, q) + 1) / nsamples);
409  std::cout << "raw " << this->GetCrdc_test()->Get_raw(id, q) << " nsamples " << nsamples << std::endl;
410  // raw_test[q] = (raw_test[q] + 1 ) / nsamples; //added to fix bug
411  }
412  }
414 
415  if (!mes1 || !mes2 || !mes3 || !mes4)
416  failed++;
417  total++;
418  if (failed == 1000) {
419  if (debug)
420  printf("Errors in Crdc Unpackings: %g%%\n", 1.0 * failed / total * 100);
421  total = 0;
422  failed = 0;
423  }
424  return (pStore + length);
425 }
426 
427 unsigned short *S800::DecodeS800NewMultiHitTDC(unsigned short *p)
428 {
429  // Data should be interpreted in 16-bit words
430 
431  // Declare temporay arrays to hold the raw data
432  unsigned short data[32][32];
433  signed short hits[32];
434  unsigned short raw[32];
435  for (int i = 0; i < 32; i++) {
436  hits[i] = -1;
437  raw[i] = 0;
438  for (int j = 0; j < 32; j++) {
439  data[i][j] = 0;
440  }
441  }
442 
443  UShort_t length, ch, hit;
444  length = *(p - 2);
445  length -= 2;
446  while (length > 0) {
447  ch = (*p) & 0xFF;
448  hit = (*p++) >> 8;
449  if (hit < 32)
450  data[ch][hit] = *p++;
451  else
452  p++;
453  if (hit == 0)
454  raw[ch] = data[ch][0];
455  if (hit > hits[ch])
456  hits[ch] = hit;
457  length -= 2;
458  }
459 
460  if (raw[15] != 0) {
461  for (int i = 0; i < 13; i++) {
462  switch (i) {
463  case 0: // e1up
464  if (hits[0] >= 0) {
465  fMultiHitTOF.fE1Up.push_back((data[0][0] - raw[15]) * 0.0625);
466  }
467  break;
468  case 1: // e1down
469  if (hits[1] >= 0) {
470  fMultiHitTOF.fE1Down.push_back((data[1][0] - raw[15]) * 0.0625);
471  }
472  break;
473  case 2: // xf
474  if (hits[2] >= 0) {
475  for (int j = 0; j <= hits[2]; j++) {
476  fMultiHitTOF.fXf.push_back((data[2][j] - raw[15]) * 0.0625);
477  }
478  }
479  break;
480  case 3: // obj
481  if (hits[3] >= 0) {
482  for (int j = 0; j <= hits[3]; j++) {
483  fMultiHitTOF.fObj.push_back((data[3][j] - raw[15]) * 0.0625);
484  }
485  }
486  break;
487  case 4: // galotte
488  if (hits[4] >= 0) {
489  for (int j = 0; j <= hits[4]; j++) {
490  fMultiHitTOF.fGalotte.push_back((data[4][j] - raw[15]) * 0.0625);
491  }
492  }
493  break;
494  case 5: // rf
495  if (hits[5] >= 0) {
496  for (int j = 0; j <= hits[5]; j++) {
497  fMultiHitTOF.fRf.push_back((data[5][j] - raw[15]) * 0.0625);
498  }
499  }
500  break;
501  case 12: // hodoscope
502  if (hits[12] >= 0) {
503  for (int j = 0; j <= hits[12]; j++) {
504  fMultiHitTOF.fHodoscope.push_back((data[12][j] - raw[15]) * 0.0625);
505  }
506  }
507  break;
508  default: break;
509  } // end Switch i
510  } // end for i
511  } // end if raw[15]!=0
512 
513  // cout<<"fNewTOF.fE1Up.size() "<<fNewTOF.fE1Up.size()<<endl;
514  // cout<<"fNewTOF.fE1Down.size() "<<fNewTOF.fE1Down.size()<<endl;
515  // cout<<"fNewTOF.obj.size() "<<fNewTOF.fObj.size()<<endl;
516 
517  return p;
518 }
S800::DecodeS800Scintillator
unsigned short * DecodeS800Scintillator(unsigned short *pevent, unsigned short updown, int id)
Definition: S800.cxx:184
GMultiHitTOF::fXf
vector< Float_t > fXf
Definition: S800.h:295
S800::GetCrdc
GCrdc * GetCrdc(int id)
Definition: S800.h:364
S800::DecodeS800Crdc
unsigned short * DecodeS800Crdc(unsigned short *pevent, int id)
Definition: S800.cxx:254
S800::SetInternalTS
void SetInternalTS(long long int ts)
Definition: S800.h:357
S800::DecodeS800IonChamber
unsigned short * DecodeS800IonChamber(unsigned short *pevent)
Definition: S800.cxx:275
GCrdc_test::Get_raw
float Get_raw(int n, int q)
Definition: S800.h:321
S800::DecodeS800CrdcRaw
unsigned short * DecodeS800CrdcRaw(unsigned short *pevent, int id)
Definition: S800.cxx:305
S800::GetScintillator
GScintillator * GetScintillator(int id)
Definition: S800.h:361
GTrigger::Set
void Set(int registr, int s800, int external1, int external2, int secondary)
Definition: S800.h:95
S800_FP_HODO_PACKET
#define S800_FP_HODO_PACKET
Definition: S800defs.h:35
S800_FP_CRDC_CHANNELS
#define S800_FP_CRDC_CHANNELS
Definition: S800defs.h:43
GMultiHitTOF::fHodoscope
vector< Float_t > fHodoscope
Definition: S800.h:299
S800::DecodeS800NewMultiHitTDC
unsigned short * DecodeS800NewMultiHitTDC(unsigned short *pevent)
Definition: S800.cxx:427
GTimeOfFlight::SetTAC
void SetTAC(Short_t tac_obj, Short_t tac_xfp)
Definition: S800.h:50
GCrdc::SetID
void SetID(int id)
Definition: S800.h:241
S800_TRIGGER_PACKET
#define S800_TRIGGER_PACKET
Definition: S800defs.h:5
S800defs.h
S800::DecodeS800
int DecodeS800(unsigned short *pevent, unsigned short twords)
Definition: S800.cxx:7
S800_FP_IC_PACKET
#define S800_FP_IC_PACKET
Definition: S800defs.h:8
S800::DecodeS800TimeOfFlight
unsigned short * DecodeS800TimeOfFlight(unsigned short *pevent)
Definition: S800.cxx:123
S800::DecodeS800HodoScope
unsigned short * DecodeS800HodoScope(unsigned short *pevent)
Definition: S800.cxx:204
S800_TOF_PACKET
#define S800_TOF_PACKET
Definition: S800defs.h:6
S800_EVENT_NUMBER_PACKET
#define S800_EVENT_NUMBER_PACKET
Definition: S800defs.h:37
GCrdc::SetAnodeTAC
void SetAnodeTAC(int anode, int tac)
Definition: S800.h:242
S800::GetHodoscope
GHodoscope * GetHodoscope(int id)
Definition: S800.h:363
GMultiHitTOF::fGalotte
vector< Float_t > fGalotte
Definition: S800.h:297
GMultiHitTOF::fObj
vector< Float_t > fObj
Definition: S800.h:296
GHodoscope::SetEnergy
void SetEnergy(Int_t energy)
Definition: S800.h:176
S800::GetIonChamber
GIonChamber * GetIonChamber()
Definition: S800.h:362
GMultiHitTOF::fE1Up
vector< Float_t > fE1Up
Definition: S800.h:293
S800::GetCrdc_test
GCrdc_test * GetCrdc_test()
Definition: S800.h:369
S800::DecodeS800Trigger
unsigned short * DecodeS800Trigger(unsigned short *pevent)
Definition: S800.cxx:158
GMultiHitTOF::fRf
vector< Float_t > fRf
Definition: S800.h:298
S800_FP_SCINT_PACKET
#define S800_FP_SCINT_PACKET
Definition: S800defs.h:7
S800_TIMESTAMP_PACKET
#define S800_TIMESTAMP_PACKET
Definition: S800defs.h:36
S800_CRDC_MAXWIDTH
#define S800_CRDC_MAXWIDTH
Definition: S800defs.h:40
S800.h
S800::GetTrigger
GTrigger * GetTrigger()
Definition: S800.h:360
GCrdc::SetSampleWidth
void SetSampleWidth(int width)
Definition: S800.h:247
S800_DEBUG
#define S800_DEBUG
Definition: S800defs.h:41
GScintillator::SetID
void SetID(int id)
Definition: S800.h:141
GMultiHitTOF::fE1Down
vector< Float_t > fE1Down
Definition: S800.h:294
S800_VME_TDC_PACKET
#define S800_VME_TDC_PACKET
Definition: S800defs.h:38
GIonChamber::Set
void Set(int ch, int data)
Definition: S800.h:201
S800::SetEvtNr
void SetEvtNr(long long int nr)
Definition: S800.h:358
GScintillator::Set
void Set(int de_up, int time_up, int de_down, int time_down)
Definition: S800.h:142
GCrdc_test::Set_raw
void Set_raw(int n, int q, float val)
Definition: S800.h:319
S800_PACKET
#define S800_PACKET
Definition: S800defs.h:1
S800_FP_IC_ENERGY_PACKET
#define S800_FP_IC_ENERGY_PACKET
Definition: S800defs.h:9
S800::GetTimeOfFlight
GTimeOfFlight * GetTimeOfFlight()
Definition: S800.h:359
S800_VERSION
#define S800_VERSION
Definition: S800defs.h:3
S800::fMultiHitTOF
GMultiHitTOF fMultiHitTOF
Definition: S800.h:381
S800_FP_CRDC_PACKET
#define S800_FP_CRDC_PACKET
Definition: S800defs.h:12
GTimeOfFlight::Set
void Set(Short_t rf, Short_t obj, Short_t xfp, Short_t si)
Definition: S800.h:43
GCrdc::Set
void Set(Short_t data, Short_t sample, Short_t ch)
Definition: S800.h:248