Belle II Software  release-05-02-19
ARICHUnpackerModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Luka Santelj *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 // Own include
12 #include <arich/modules/arichUnpacker/ARICHUnpackerModule.h>
13 
14 #include <arich/modules/arichUnpacker/ARICHRawDataHeader.h>
15 
16 #include <framework/core/ModuleManager.h>
17 
18 // framework - DataStore
19 #include <framework/datastore/StoreArray.h>
20 #include <framework/datastore/StoreObjPtr.h>
21 
22 // framework aux
23 #include <framework/logging/Logger.h>
24 
25 // Dataobject classes
26 #include <framework/dataobjects/EventMetaData.h>
27 #include <rawdata/dataobjects/RawARICH.h>
28 #include <arich/dataobjects/ARICHDigit.h>
29 #include <arich/dataobjects/ARICHInfo.h>
30 #include <arich/dataobjects/ARICHRawDigit.h>
31 
32 // print bitset
33 #include <bitset>
34 
35 using namespace std;
36 
37 namespace Belle2 {
43  //using namespace ARICH;
44 
45  //-----------------------------------------------------------------
46  // Register module
47  //-----------------------------------------------------------------
48 
49  REG_MODULE(ARICHUnpacker)
50 
51  //-----------------------------------------------------------------
52  // Implementation
53  //-----------------------------------------------------------------
54 
55  ARICHUnpackerModule::ARICHUnpackerModule() : Module(), m_bitMask(0), m_debug(0)
56  {
57  // set module description
58  setDescription("Raw data unpacker for ARICH");
59  setPropertyFlags(c_ParallelProcessingCertified);
60 
61  addParam("bitMask", m_bitMask, "hit bit mask (8 bits/channel, only used for unsuppresed format!)", (uint8_t)0xFF);
62  addParam("debug", m_debug, "prints debug information", 0);
63 
64  addParam("inputRawDataName", m_inputRawDataName, "name of RawARICH store array", string(""));
65  addParam("outputDigitsName", m_outputDigitsName, "name of ARICHDigit store array", string(""));
66  addParam("outputRawDigitsName", m_outputRawDigitsName, "name of ARICHRawDigit store array", string(""));
67  addParam("outputarichinfoName", m_outputarichinfoName, "name of ARICHInfo store array", string(""));
68  addParam("RawUnpackerMode", m_rawmode, "Activate RawUnpacker mode", 0);
69  addParam("DisableUnpackerMode", m_disable_unpacker, "Disable Regular Unpacker mode", 0);
70 
71  }
72 
73  ARICHUnpackerModule::~ARICHUnpackerModule()
74  {
75  }
76 
77  void ARICHUnpackerModule::initialize()
78  {
79 
80  StoreArray<RawARICH> rawData(m_inputRawDataName);
81  rawData.isRequired();
82 
83  StoreArray<ARICHDigit> digits(m_outputDigitsName);
84  digits.registerInDataStore();
85 
86  StoreArray<ARICHRawDigit> rawdigits(m_outputRawDigitsName);
87  rawdigits.registerInDataStore();
88 
89  StoreObjPtr<ARICHInfo> arichinfo(m_outputarichinfoName);
90  arichinfo.registerInDataStore();
91 
92  }
93 
94  void ARICHUnpackerModule::beginRun()
95  {
96  }
97 
98  void ARICHUnpackerModule::event()
99  {
100 
101  StoreArray<RawARICH> rawData(m_inputRawDataName);
102  StoreArray<ARICHDigit> digits(m_outputDigitsName);
103  StoreArray<ARICHRawDigit> rawdigits(m_outputRawDigitsName);
104  StoreObjPtr<ARICHInfo> arichinfo(m_outputarichinfoName);
105  arichinfo.create();
106  StoreObjPtr<EventMetaData> evtMetaData;
107 
108  digits.clear();
109  int trgtype = 16;
110  double vth_thscan = 0.0;
111 
112  if (m_debug) {
113  std::cout << std::endl << "------------------------" << std::endl;
114  std::cout << "Run: " << evtMetaData->getRun() << " Event: " << evtMetaData->getEvent() << std::endl;
115  std::cout << "------------------------" << std::endl << std::endl;
116  }
117 
118  unsigned thscan_mode = 0;
119  // regular Unpacker mode, fill ARICHDigit
120 // if (m_disable_unpacker == 0) {
121 
122  for (auto& raw : rawData) {
123  for (int finesse = 0; finesse < 4; finesse++) {
124  const int* buffer = raw.GetDetectorBuffer(0, finesse);
125  int bufferSize = raw.GetDetectorNwords(0, finesse);
126 
127  if (bufferSize < 1)
128  continue;
129 
130  // record the trigger type from the B2L data
131  trgtype = raw.GetTRGType(0);
132 
133  // read merger header
134  unsigned ibyte = 0;
135  ARICHRawHeader head;
136 
137  readHeader(buffer, ibyte, head);
138 
139  if (m_debug > 1) printBits(buffer, bufferSize);
140 
141  if (m_debug) {
142  std::cout << "Merger header" << std::endl;
143  head.print();
144  }
145  //-- RawDigit for Merger info
146  int type = (int)head.type;
147  int ver = (int)head.version;
148  int boardid = (int)head.mergerID;
149  int febno = (int)head.FEBSlot;
150  unsigned int length_all = (unsigned int)head.length;
151  unsigned int mrg_evtno = (unsigned int)head.trigger;
152  ARICHRawDigit* rawdigit = rawdigits.appendNew(type, ver, boardid, febno, length_all, mrg_evtno);
153  rawdigit->setCopperId(raw.GetNodeID(0));
154  rawdigit->setHslbId(finesse);
155  int nfebs = 0;
156  //-- end of RawDigit for Merger info
157 
158  // record the ibyte here
159  unsigned begin = ibyte;
160 
161  while (ibyte < head.length) {
162 
163  // new feb
164  ARICHRawHeader febHead;
165  readFEHeader(buffer, ibyte, febHead);
166  if (febHead.thscan_mode) {thscan_mode++;}
167  if (m_debug) febHead.print();
168 
169  if (/*febHead.type != head.type ||*/ febHead.version != head.version || febHead.mergerID != head.mergerID
170  || febHead.trigger != head.trigger) {
171  B2ERROR("ARICHUnpackerModule: data in FEB header not consistent with data in merger HEADER " << LogVar("FEB ID",
172  (unsigned)febHead.FEBSlot) <<
173  LogVar("merger ID", (unsigned)head.mergerID)); break;
174  }
175 
176  // feb header shift
177  ibyte += ARICHFEB_HEADER_SIZE;
178  int dataLen = febHead.length - ARICHFEB_HEADER_SIZE;
179 
180  febHead.FEBSlot += 1;
181 
182  unsigned mergID = m_mergerMap->getMergerIDfromSN((unsigned)head.mergerID);
183 
184  if (mergID == 99) { B2ERROR("ARICHUnpackerModule: unknown merger number. Merger data will be skipped. " << LogVar("merger ID", mergID) << LogVar("Serial Number", (unsigned)head.mergerID)); break;}
185 
186  unsigned moduleID = m_mergerMap->getModuleID(mergID, (unsigned)febHead.FEBSlot);
187 
188  if (!moduleID) { B2ERROR("ARICHUnpackerModule: no merger to FEB mapping. Merger data will be skipped. " << LogVar("merger ID", mergID) << LogVar("Serial Number", (unsigned)head.mergerID) << LogVar("FEB slot", (unsigned)febHead.FEBSlot)); break;}
189 
190  // read data
191  if (m_debug) std::cout << "Hit channels: " << std::endl;
192  if (febHead.type == 1) {
193  for (int i = 0; i < dataLen / 2; i++) {
194  int shift = (3 - ibyte % 4) * 8;
195  uint8_t asicCh = buffer[ibyte / 4] >> shift;
196  ibyte++;
197  shift = (3 - ibyte % 4) * 8;
198  uint8_t hitBitSet = buffer[ibyte / 4] >> shift;
199  if (m_debug && hitBitSet) std::cout << "ch: " << (unsigned)asicCh << " " << std::bitset<8>(hitBitSet) << std::endl;
200  // store digit
201  digits.appendNew(moduleID, (unsigned)asicCh, hitBitSet);
202  ibyte++;
203  }
204  } else if (febHead.type == 2) {
205  unsigned asicCh = 143;
206  for (int i = 0; i < dataLen; i++) {
207  int shift = (3 - ibyte % 4) * 8;
208  uint8_t hitBitSet = buffer[ibyte / 4] >> shift;
209  // store digit if hit
210  if (hitBitSet & m_bitMask) {
211  digits.appendNew(moduleID, asicCh, hitBitSet);
212  }
213  asicCh--;
214  ibyte++;
215  }
216  } else B2ERROR("ARICHUnpackerModule: Unknown data type" << LogVar("type", febHead.type));
217 
218  }
219 
220  if (ceil(ibyte / 4.) != (unsigned)bufferSize)
221  B2WARNING("ARICHUnpackerModule: data buffer size mismatch " << LogVar("size from copper", bufferSize) << LogVar("size from merger",
222  ceil(
223  ibyte / 4.)));
224 
225 
226  //-- If thscan_mode detected from header: proceed to fill ARICHRawDigit
227  //-- If m_rawmode is set to 1: proceed to fill ARICHRawDigit
228  if (thscan_mode == 0 && m_rawmode == 0) continue;
229  //-- go back to beginning again for second loop in case of thscan
230  m_ibyte = begin;
231 
232  while (m_ibyte < length_all) {
233  ARICHRawHeader febHead;
234  readFEHeader(buffer, m_ibyte, febHead);
235  int type_feb = febHead.type;
236  ver = febHead.version;
237  boardid = febHead.mergerID;
238  febno = febHead.FEBSlot;
239 
240  vth_thscan = (febHead.vth * 0.0024) - 1.27;
241  unsigned int length = febHead.length;
242  int evtno = febHead.trigger;
243  unsigned int jbyte = 0;
244  std::stringstream ss;
245  ss << "type=" << type_feb << ", ver=" << ver << " "
246  << ", boardid=" << boardid << ", febno=" << febno
247  << ", length=" << length << ", evtno=" << evtno << " ";
248  bool hasHit = false;
249  long long feb_trigno = 0;
250  for (int i = 0; i < 10; i++) {
251  int val = calbyte(buffer);
252  jbyte++;
253  if (i < 6) {
254  feb_trigno |= (0xff & val) << (5 - i) * 8;
255  }
256  }
258  nfebs++;
259  if (type_feb == 0x02) {//Raw mode
260  int ch = 143;
261  //B2INFO("raw mode");
262  while (jbyte < length) {
263  int val = calbyte(buffer);
264  if (val != 0) {
265  jbyte++;
266  ss << "ch# " << ch << "(" << val << ") ";
267  hasHit = true;
268  if (febno < 0 || febno > 6) {
269  B2ERROR("FEB is bad : " << LogVar("FEB no.", febno) << LogVar("hslb", finesse) << LogVar("type", type_feb) << LogVar("ver",
270  ver) << LogVar("boardid", boardid) << LogVar("febno", febno) << LogVar("length", length) << LogVar("evtno", evtno));
271  }
272  feb.push_back(ch, val);
273  }
274  ch--;
275  if (ch < 0) break;
276  }
277  } else if (type_feb == 0x01) { // Suppressed mode
278  // The below line is commented since it sometimes causes problem during processing threshold scan data.
279  // No harm to comment this line since it is only utilized for threshold scan data.
280  //if (length > 144 * 2 + 10) B2FATAL("error " << LogVar("length", length));
281  //B2INFO("suppreed mode");
282  while (jbyte < length) {
283  int ch = calbyte(buffer);
284  jbyte++;
285  int val = calbyte(buffer);
286  jbyte++;
287  if (val != 0) {
288  ss << "ch# " << ch << "(" << val << ") ";
289  hasHit = true;
290  if (febno < 0 || febno > 6) {
291  B2ERROR("FEB is bad : " << LogVar("FEB no.", febno) << LogVar("hslb", finesse) << LogVar("type", type_feb) << LogVar("ver",
292  ver) << LogVar("boardid", boardid) << LogVar("febno", febno) << LogVar("length", length) << LogVar("evtno", evtno));
293  return;
294  }
295  feb.push_back(ch, val);
296  }
297  }
298  }
299  rawdigit->addFEB(feb, type, ver, boardid, febno, length, evtno, feb_trigno);
300  if (m_debug && hasHit) {
301  B2INFO(ss.str());
302  }
303  }
304 
305 
306 
307  }
308  } // end of rawData loop
309 
310 // } // end of regular unpacker
311  /*
312  // RawUnpacker mode, fill ARICHRawDigit
313  if (m_rawmode == 1) {
314  for (auto& raw : rawData) {
315  for (int finesse = 0; finesse < 4; finesse++) {
316  const int* buf = (const int*)raw.GetDetectorBuffer(0, finesse);
317  int bufSize = raw.GetDetectorNwords(0, finesse);
318  if (bufSize < 1) continue;
319  m_ibyte = 0;
320  // read merger header
321  int type = calbyte(buf);
322  int ver = calbyte(buf);
323  int boardid = calbyte(buf);
324  int febno = calbyte(buf);
325  unsigned int length_all = calword(buf);
326  unsigned int mrg_evtno = calword(buf);
327  ARICHRawDigit* rawdigit = rawdigits.appendNew(type, ver, boardid, febno, length_all, mrg_evtno);
328  rawdigit->setCopperId(raw.GetNodeID(0));
329  rawdigit->setHslbId(finesse);
330  int nfebs = 0;
331  //--done
332  while (m_ibyte < length_all) {
333  int type_feb = calbyte(buf);
334  ver = calbyte(buf);
335  boardid = calbyte(buf);
336  febno = calbyte(buf);
337 
338  // first line: vth value
339  unsigned int vth_int = cal2byte(buf);
340  if (vth_int > 0) { vth_thscan = (vth_int * 0.0024) - 1.27; }
341  // second line: length
342  unsigned int length = cal2byte(buf);
343  int evtno = calword(buf);
344  unsigned int ibyte = 0;
345  std::stringstream ss;
346  ss << "type=" << type_feb << ", ver=" << ver << " "
347  << ", boardid=" << boardid << ", febno=" << febno
348  << ", length=" << length << ", evtno=" << evtno << " ";
349  bool hasHit = false;
350  long long feb_trigno = 0;
351  for (int i = 0; i < 10; i++) {
352  int val = calbyte(buf);
353  ibyte++;
354  if (i < 6) {
355  feb_trigno |= (0xff & val) << (5 - i) * 8;
356  }
357  }
358  ARICHRawDigit::FEBDigit feb;
359  nfebs++;
360  if (type_feb == 0x02) {//Raw mode
361  int ch = 143;
362  //B2INFO("raw mode");
363  while (ibyte < length) {
364  int val = calbyte(buf);
365  if (val != 0) {
366  ibyte++;
367  ss << "ch# " << ch << "(" << val << ") ";
368  hasHit = true;
369  if (febno < 0 || febno > 6) {
370  B2ERROR("FEB is bad : " << LogVar("FEB no.", febno) << LogVar("hslb", finesse) << LogVar("type", type_feb) << LogVar("ver",
371  ver) << LogVar("boardid", boardid) << LogVar("febno", febno) << LogVar("length", length) << LogVar("evtno", evtno));
372  }
373  feb.push_back(ch, val);
374  }
375  ch--;
376  if (ch < 0) break;
377  }
378  } else if (type_feb == 0x01) { // Suppressed mode
379  // The below line is commented since it sometimes causes problem during processing threshold scan data.
380  // No harm to comment this line since it is only utilized for threshold scan data.
381  //if (length > 144 * 2 + 10) B2FATAL("error " << LogVar("length", length));
382  //B2INFO("suppreed mode");
383  while (ibyte < length) {
384  int ch = calbyte(buf);
385  ibyte++;
386  int val = calbyte(buf);
387  ibyte++;
388  if (val != 0) {
389  ss << "ch# " << ch << "(" << val << ") ";
390  hasHit = true;
391  if (febno < 0 || febno > 6) {
392  B2ERROR("FEB is bad : " << LogVar("FEB no.", febno) << LogVar("hslb", finesse) << LogVar("type", type_feb) << LogVar("ver",
393  ver) << LogVar("boardid", boardid) << LogVar("febno", febno) << LogVar("length", length) << LogVar("evtno", evtno));
394  return;
395  }
396  feb.push_back(ch, val);
397  }
398  }
399  }
400  rawdigit->addFEB(feb, type, ver, boardid, febno, length, evtno, feb_trigno);
401  if (m_debug && hasHit) {
402  B2INFO(ss.str());
403  }
404  }
405  }
406  }
407 
408  } // end of raw unpacker
409  */
410  arichinfo->settrgtype(trgtype);
411  if (vth_thscan > -1.27) { arichinfo->setvth_thscan(vth_thscan); }
412  arichinfo->setntrack(0);
413  arichinfo->setnexthit(0);
414  arichinfo->setnhit(0);
415  if (thscan_mode > 0 || m_rawmode != 0)
416  { arichinfo->setthscan_mode(true); }
417  else
418  { arichinfo->setthscan_mode(false); }
419 
420  }
421 
422  void ARICHUnpackerModule::readHeader(const int* buffer, unsigned& ibyte, ARICHRawHeader& head)
423  {
424 
425  // read the first line of header
426  char line1[4];
427  int shift;
428  for (int i = 0; i < 4; i++) {
429  shift = (3 - ibyte % 4) * 8;
430  line1[3 - i] = buffer[ibyte / 4] >> shift;
431  ibyte++;
432  }
433 
434  head.type = line1[3];
435  head.version = line1[2];
436  head.mergerID = line1[1];
437  head.FEBSlot = line1[0];
438 
439  // data length
440  unsigned char len[4];
441  for (int i = 0; i < 4; i++) {
442  shift = (3 - ibyte % 4) * 8;
443  len[3 - i] = buffer[ibyte / 4] >> shift;
444  ibyte++;
445  }
446 
447  unsigned seu = len[2];
448  // This line (16 bits) is actaully not used for data length.
449  len[2] = 0;
450  len[3] = 0;
451  uint32_t* tmp = (uint32_t*)len;
452  head.length = *tmp;
453 
454  for (int i = 0; i < 6; i ++) {
455  head.SEU_FEB[i] = (seu & (1 << i)) != 0;
456  }
457 
458  // trigger number
459  char trg[4];
460  for (int i = 0; i < 4; i++) {
461  shift = (3 - ibyte % 4) * 8;
462  trg[3 - i] = buffer[ibyte / 4] >> shift;
463  ibyte++;
464  }
465  tmp = (uint32_t*)trg;
466  head.trigger = *tmp;
467 
468  }
469 
470  void ARICHUnpackerModule::readFEHeader(const int* buffer, unsigned& ibyte, ARICHRawHeader& head)
471  {
472 
473  // read the first line of header
474  char line1[4];
475  int shift;
476  for (int i = 0; i < 4; i++) {
477  shift = (3 - ibyte % 4) * 8;
478  line1[3 - i] = buffer[ibyte / 4] >> shift;
479  ibyte++;
480  }
481 
482  head.type = line1[3];
483  head.version = line1[2];
484  head.mergerID = line1[1];
485  head.FEBSlot = line1[0];
486 
487  // data length
488  unsigned char len[4];
489  for (int i = 0; i < 4; i++) {
490  shift = (3 - ibyte % 4) * 8;
491  len[3 - i] = buffer[ibyte / 4] >> shift;
492  ibyte++;
493  }
494 
495  unsigned vth_info = len[3] * 256 + len[2];
496  if (vth_info >= 32768) { head.thscan_mode = true; vth_info -= 32768; }
497  head.vth = vth_info;
498  // This line (16 bits) is actaully not used for data length.
499  len[2] = 0;
500  len[3] = 0;
501  uint32_t* tmp = (uint32_t*)len;
502  head.length = *tmp;
503 
504  // trigger number
505  char trg[4];
506  for (int i = 0; i < 4; i++) {
507  shift = (3 - ibyte % 4) * 8;
508  trg[3 - i] = buffer[ibyte / 4] >> shift;
509  ibyte++;
510  }
511  tmp = (uint32_t*)trg;
512  head.trigger = *tmp;
513 
514  }
515 
516  void ARICHUnpackerModule::printBits(const int* buffer, int bufferSize)
517  {
518  for (int i = 0; i < bufferSize; i++) {
519  std::cout << i << "-th word bitset: " << std::bitset<32>(*(buffer + i)) << std::endl;
520  }
521  }
522 
523 
524  void ARICHUnpackerModule::endRun()
525  {
526  }
527 
528  void ARICHUnpackerModule::terminate()
529  {
530  }
531 
532 
534 } // end Belle2 namespace
535 
Belle2::StoreArray::appendNew
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:256
Belle2::ARICHRawDigit
Definition: ARICHRawDigit.h:34
Belle2::ARICHUnpackerModule
Raw data unpacker for ARICH.
Definition: ARICHUnpackerModule.h:42
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::StoreObjPtr
Type-safe access to single objects in the data store.
Definition: ParticleList.h:33
LogVar
Class to store variables with their name which were sent to the logging service.
Definition: LogVariableStream.h:24
Belle2::StoreArray
Accessor to arrays stored in the data store.
Definition: ECLMatchingPerformanceExpertModule.h:33
Belle2::ARICHRawHeader
Definition: ARICHRawDataHeader.h:17
Belle2::ARICHRawDigit::FEBDigit
Definition: ARICHRawDigit.h:37