10 #include <arich/modules/arichUnpacker/ARICHUnpackerModule.h>
12 #include <arich/modules/arichUnpacker/ARICHRawDataHeader.h>
14 #include <framework/core/ModuleManager.h>
17 #include <framework/datastore/StoreArray.h>
18 #include <framework/datastore/StoreObjPtr.h>
21 #include <framework/logging/Logger.h>
24 #include <framework/dataobjects/EventMetaData.h>
25 #include <rawdata/dataobjects/RawARICH.h>
26 #include <arich/dataobjects/ARICHDigit.h>
27 #include <arich/dataobjects/ARICHInfo.h>
28 #include <arich/dataobjects/ARICHRawDigit.h>
56 setDescription(
"Raw data unpacker for ARICH");
57 setPropertyFlags(c_ParallelProcessingCertified);
59 addParam(
"bitMask", m_bitMask,
"hit bit mask (8 bits/channel, only used for unsuppresed format!)", (uint8_t)0xFF);
60 addParam(
"debug", m_debug,
"prints debug information", 0);
62 addParam(
"inputRawDataName", m_inputRawDataName,
"name of RawARICH store array",
string(
""));
63 addParam(
"outputDigitsName", m_outputDigitsName,
"name of ARICHDigit store array",
string(
""));
64 addParam(
"outputRawDigitsName", m_outputRawDigitsName,
"name of ARICHRawDigit store array",
string(
""));
65 addParam(
"outputarichinfoName", m_outputarichinfoName,
"name of ARICHInfo store array",
string(
""));
66 addParam(
"RawUnpackerMode", m_rawmode,
"Activate RawUnpacker mode", 0);
67 addParam(
"DisableUnpackerMode", m_disable_unpacker,
"Disable Regular Unpacker mode", 0);
71 ARICHUnpackerModule::~ARICHUnpackerModule()
75 void ARICHUnpackerModule::initialize()
82 digits.registerInDataStore();
92 void ARICHUnpackerModule::beginRun()
96 void ARICHUnpackerModule::event()
107 bool m_pciedata =
false;
109 double vth_thscan = 0.0;
112 std::cout << std::endl <<
"------------------------" << std::endl;
113 std::cout <<
"Run: " << evtMetaData->getRun() <<
" Event: " << evtMetaData->getEvent() << std::endl;
114 std::cout <<
"------------------------" << std::endl << std::endl;
117 unsigned thscan_mode = 0;
121 for (
auto& raw : rawData) {
123 if (raw.GetMaxNumOfCh(0) == 48) { m_pciedata =
true; }
124 else if (raw.GetMaxNumOfCh(0) == 4) { m_pciedata =
false; }
125 else { B2FATAL(
"ARICHUnpackerModule: Invalid value of GetMaxNumOfCh from raw data: " <<
LogVar(
"Number of ch: ", raw.GetMaxNumOfCh(0))); }
127 for (
int finesse = 0; finesse < raw.GetMaxNumOfCh(0); finesse++) {
128 const int* buffer = raw.GetDetectorBuffer(0, finesse);
129 int bufferSize = raw.GetDetectorNwords(0, finesse);
135 trgtype = raw.GetTRGType(0);
141 readHeader(buffer, ibyte, head);
143 if (m_debug > 1) printBits(buffer, bufferSize);
146 std::cout <<
"Merger header" << std::endl;
150 int type = (int)head.type;
151 int ver = (
int)head.version;
152 int boardid = (int)head.mergerID;
153 int febno = (
int)head.FEBSlot;
154 unsigned int length_all = (
unsigned int)head.length;
155 unsigned int mrg_evtno = (
unsigned int)head.trigger;
159 rawdigit->setCopperId(raw.GetNodeID(0));
160 rawdigit->setHslbId(finesse);
162 if (raw.GetNodeID(0) == 0x4000001) {
163 rawdigit->setCopperId(raw.GetNodeID(0) + (int)(finesse / 4));
164 }
else if (raw.GetNodeID(0) == 0x4000002) {
165 rawdigit->setCopperId(0x400000A + (
int)(finesse / 4));
167 B2FATAL(
"ARICHUnpackerModule: Invalid Node ID from readout: " <<
LogVar(
"NodeID: ", raw.GetNodeID(0)));
170 rawdigit->setHslbId(finesse % 4);
171 rawdigit->setPcieId(raw.GetNodeID(0));
172 rawdigit->setPcieChId(finesse);
179 unsigned begin = ibyte;
181 while (ibyte < head.length) {
185 readFEHeader(buffer, ibyte, febHead);
186 if (febHead.thscan_mode) {thscan_mode++;}
187 if (m_debug) febHead.print();
189 if ( febHead.version != head.version || febHead.mergerID != head.mergerID
190 || febHead.trigger != head.trigger) {
191 B2ERROR(
"ARICHUnpackerModule: data in FEB header not consistent with data in merger HEADER " <<
LogVar(
"FEB ID",
192 (
unsigned)febHead.FEBSlot) <<
193 LogVar(
"merger ID", (
unsigned)head.mergerID));
break;
197 ibyte += ARICHFEB_HEADER_SIZE;
198 int dataLen = febHead.length - ARICHFEB_HEADER_SIZE;
200 febHead.FEBSlot += 1;
202 unsigned mergID = m_mergerMap->getMergerIDfromSN((
unsigned)head.mergerID);
204 if (mergID == 99) { B2ERROR(
"ARICHUnpackerModule: unknown merger number. Merger data will be skipped. " <<
LogVar(
"merger ID", mergID) <<
LogVar(
"Serial Number", (
unsigned)head.mergerID));
break;}
206 unsigned moduleID = m_mergerMap->getModuleID(mergID, (
unsigned)febHead.FEBSlot);
208 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;}
211 if (m_debug) std::cout <<
"Hit channels: " << std::endl;
212 if (febHead.type == 1) {
213 for (
int i = 0; i < dataLen / 2; i++) {
214 int shift = (3 - ibyte % 4) * 8;
215 uint8_t asicCh = buffer[ibyte / 4] >> shift;
217 shift = (3 - ibyte % 4) * 8;
218 uint8_t hitBitSet = buffer[ibyte / 4] >> shift;
219 if (m_debug && hitBitSet) std::cout <<
"ch: " << (unsigned)asicCh <<
" " << std::bitset<8>(hitBitSet) << std::endl;
221 digits.appendNew(moduleID, (
unsigned)asicCh, hitBitSet);
224 }
else if (febHead.type == 2) {
225 unsigned asicCh = 143;
226 for (
int i = 0; i < dataLen; i++) {
227 int shift = (3 - ibyte % 4) * 8;
228 uint8_t hitBitSet = buffer[ibyte / 4] >> shift;
230 if (hitBitSet & m_bitMask) {
231 digits.appendNew(moduleID, asicCh, hitBitSet);
236 }
else B2ERROR(
"ARICHUnpackerModule: Unknown data type" <<
LogVar(
"type", febHead.type));
240 if (ceil(ibyte / 4.) != (
unsigned)bufferSize)
241 B2WARNING(
"ARICHUnpackerModule: data buffer size mismatch " <<
LogVar(
"size from copper", bufferSize) <<
LogVar(
"size from merger",
248 if (thscan_mode == 0 && m_rawmode == 0)
continue;
252 while (m_ibyte < length_all) {
254 readFEHeader(buffer, m_ibyte, febHead);
255 int type_feb = febHead.type;
256 ver = febHead.version;
257 boardid = febHead.mergerID;
258 febno = febHead.FEBSlot;
260 vth_thscan = (febHead.vth * 0.0024) - 1.27;
261 unsigned int length = febHead.length;
262 int evtno = febHead.trigger;
263 unsigned int jbyte = 0;
264 std::stringstream ss;
265 ss <<
"type=" << type_feb <<
", ver=" << ver <<
" "
266 <<
", boardid=" << boardid <<
", febno=" << febno
267 <<
", length=" << length <<
", evtno=" << evtno <<
" ";
269 long long feb_trigno = 0;
270 for (
int i = 0; i < 10; i++) {
271 int val = calbyte(buffer);
274 feb_trigno |= (0xff & val) << (5 - i) * 8;
279 if (type_feb == 0x02) {
282 while (jbyte < length) {
283 int val = calbyte(buffer);
286 ss <<
"ch# " << ch <<
"(" << val <<
") ";
288 if (febno < 0 || febno > 6) {
289 B2ERROR(
"FEB is bad : " <<
LogVar(
"FEB no.", febno) <<
LogVar(
"hslb", finesse) <<
LogVar(
"type", type_feb) <<
LogVar(
"ver",
290 ver) <<
LogVar(
"boardid", boardid) <<
LogVar(
"febno", febno) <<
LogVar(
"length", length) <<
LogVar(
"evtno", evtno));
292 feb.push_back(ch, val);
297 }
else if (type_feb == 0x01) {
302 while (jbyte < length) {
303 int ch = calbyte(buffer);
305 int val = calbyte(buffer);
308 ss <<
"ch# " << ch <<
"(" << val <<
") ";
310 if (febno < 0 || febno > 6) {
311 B2ERROR(
"FEB is bad : " <<
LogVar(
"FEB no.", febno) <<
LogVar(
"hslb", finesse) <<
LogVar(
"type", type_feb) <<
LogVar(
"ver",
312 ver) <<
LogVar(
"boardid", boardid) <<
LogVar(
"febno", febno) <<
LogVar(
"length", length) <<
LogVar(
"evtno", evtno));
315 feb.push_back(ch, val);
319 rawdigit->addFEB(feb, type, ver, boardid, febno, length, evtno, feb_trigno);
320 if (m_debug && hasHit) {
430 arichinfo->settrgtype(trgtype);
431 arichinfo->setpciedata(m_pciedata);
432 if (vth_thscan > -1.27) { arichinfo->setvth_thscan(vth_thscan); }
433 arichinfo->setntrack(0);
434 arichinfo->setnexthit(0);
435 arichinfo->setnhit(0);
436 if (thscan_mode > 0 || m_rawmode != 0)
437 { arichinfo->setthscan_mode(
true); }
439 { arichinfo->setthscan_mode(
false); }
443 void ARICHUnpackerModule::readHeader(
const int* buffer,
unsigned& ibyte,
ARICHRawHeader& head)
449 for (
int i = 0; i < 4; i++) {
450 shift = (3 - ibyte % 4) * 8;
451 line1[3 - i] = buffer[ibyte / 4] >> shift;
455 head.type = line1[3];
456 head.version = line1[2];
457 head.mergerID = line1[1];
458 head.FEBSlot = line1[0];
461 unsigned char len[4];
462 for (
int i = 0; i < 4; i++) {
463 shift = (3 - ibyte % 4) * 8;
464 len[3 - i] = buffer[ibyte / 4] >> shift;
468 unsigned seu = len[2];
472 uint32_t* tmp = (uint32_t*)len;
475 for (
int i = 0; i < 6; i ++) {
476 head.SEU_FEB[i] = (seu & (1 << i)) != 0;
481 for (
int i = 0; i < 4; i++) {
482 shift = (3 - ibyte % 4) * 8;
483 trg[3 - i] = buffer[ibyte / 4] >> shift;
486 tmp = (uint32_t*)trg;
491 void ARICHUnpackerModule::readFEHeader(
const int* buffer,
unsigned& ibyte,
ARICHRawHeader& head)
497 for (
int i = 0; i < 4; i++) {
498 shift = (3 - ibyte % 4) * 8;
499 line1[3 - i] = buffer[ibyte / 4] >> shift;
503 head.type = line1[3];
504 head.version = line1[2];
505 head.mergerID = line1[1];
506 head.FEBSlot = line1[0];
509 unsigned char len[4];
510 for (
int i = 0; i < 4; i++) {
511 shift = (3 - ibyte % 4) * 8;
512 len[3 - i] = buffer[ibyte / 4] >> shift;
516 unsigned vth_info = len[3] * 256 + len[2];
517 if (vth_info >= 32768) { head.thscan_mode =
true; vth_info -= 32768; }
522 uint32_t* tmp = (uint32_t*)len;
527 for (
int i = 0; i < 4; i++) {
528 shift = (3 - ibyte % 4) * 8;
529 trg[3 - i] = buffer[ibyte / 4] >> shift;
532 tmp = (uint32_t*)trg;
537 void ARICHUnpackerModule::printBits(
const int* buffer,
int bufferSize)
539 for (
int i = 0; i < bufferSize; i++) {
540 std::cout << i <<
"-th word bitset: " << std::bitset<32>(*(buffer + i)) << std::endl;
545 void ARICHUnpackerModule::endRun()
549 void ARICHUnpackerModule::terminate()
Raw data unpacker for ARICH.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
Type-safe access to single objects in the data store.
Class to store variables with their name which were sent to the logging service.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.