12 #include <top/modules/TOPPacker/TOPPackerModule.h>
13 #include <top/RawDataTypes.h>
16 #include <framework/datastore/StoreArray.h>
17 #include <framework/datastore/StoreObjPtr.h>
20 #include <framework/logging/Logger.h>
23 #include <top/dataobjects/TOPDigit.h>
24 #include <top/dataobjects/TOPRawDigit.h>
25 #include <rawdata/dataobjects/RawTOP.h>
26 #include <framework/dataobjects/EventMetaData.h>
51 setDescription(
"Raw data packer for TOP");
52 setPropertyFlags(c_ParallelProcessingCertified);
55 addParam(
"inputDigitsName", m_inputDigitsName,
56 "name of TOPDigit store array",
string(
""));
57 addParam(
"inputRawDigitsName", m_inputRawDigitsName,
58 "name of TOPRawDigit store array",
string(
""));
59 addParam(
"outputRawDataName", m_outputRawDataName,
60 "name of RawTOP store array",
string(
""));
61 addParam(
"format", m_format,
62 "data format (draft, FE, production)",
string(
"production"));
66 TOPPackerModule::~TOPPackerModule()
70 void TOPPackerModule::initialize()
73 if (m_format ==
"draft") {
74 m_dataType = TOP::RawDataType::c_Draft;
77 }
else if (m_format ==
"FE") {
78 m_dataType = TOP::RawDataType::c_Type0Ver16;
80 rawDigits.isRequired();
81 }
else if (m_format ==
"production") {
82 m_dataType = TOP::RawDataType::c_ProductionDebug01;
84 rawDigits.isRequired();
86 B2ERROR(
"TOPPacker: unknown data format."
87 <<
LogVar(
"format", m_format));
91 rawData.registerInDataStore();
94 const auto& mapper = m_topgp->getFrontEndMapper();
95 if (!mapper.isValid()) B2ERROR(
"No front-end mapping available for TOP");
99 void TOPPackerModule::beginRun()
103 void TOPPackerModule::event()
106 switch (m_dataType) {
107 case TOP::RawDataType::c_Type0Ver16:
110 case TOP::RawDataType::c_ProductionDebug01:
111 packProductionDebug();
113 case TOP::RawDataType::c_Draft:
114 packProductionDraft();
117 B2ERROR(
"TOPPacker: data format unknown or not implemented");
123 void TOPPackerModule::endRun()
127 void TOPPackerModule::terminate()
132 void TOPPackerModule::packProductionDraft()
138 const auto& mapper = m_topgp->getFrontEndMapper();
139 int mapSize = mapper.getMapSize();
140 if (mapSize == 0)
return;
142 vector<const TOPDigit*>* sortedDigits =
new vector<const TOPDigit*>[mapSize];
144 for (
const auto& digit : digits) {
145 int moduleID = digit.getModuleID();
146 int boardstack = digit.getChannel() / 128;
147 const auto* feemap = mapper.getMap(moduleID, boardstack);
149 B2ERROR(
"TOPPacker: no front-end map available."
150 <<
LogVar(
"moduleID", moduleID)
151 <<
LogVar(
"boardstack", boardstack));
154 sortedDigits[feemap->getIndex()].push_back(&digit);
157 auto subBits = m_topgp->getGeometry()->getNominalTDC().getSubBits();
158 int sampleDivisions = 0x1 << subBits;
160 for (
const auto& copperID : mapper.getCopperIDs()) {
162 for (
int finesse = 0; finesse < 4; finesse++) {
163 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
164 if (!feemap)
continue;
165 unsigned scrodID = feemap->getScrodID();
166 unsigned dataFormat =
static_cast<unsigned>(TOP::RawDataType::c_Draft);
167 Buffer[finesse].push_back(scrodID + (dataFormat << 16));
168 for (
const auto& digit : sortedDigits[feemap->getIndex()]) {
169 double rawTime = digit->getRawTime();
170 unsigned tdc = int(rawTime * sampleDivisions) & 0xFFFF;
171 unsigned chan = digit->getChannel() % 128;
172 unsigned flags = (unsigned) digit->getHitQuality();
173 Buffer[finesse].push_back(tdc + (chan << 16) + (flags << 24));
177 info.exp_num = evtMetaData->getExperiment();
179 info.run_subrun_num = (evtMetaData->getRun() << 8) +
180 (evtMetaData->getSubrun() & 0xFF);
181 info.eve_num = evtMetaData->getEvent();
182 info.node_id = TOP_ID + copperID;
186 info.hslb_crc16_error_bit = 0;
187 info.truncation_mask = 0;
188 info.type_of_data = 0;
191 raw->PackDetectorBuf(
Buffer[0].data(),
Buffer[0].size(),
197 delete [] sortedDigits;
201 void TOPPackerModule::packType0Ver16()
207 const auto& mapper = m_topgp->getFrontEndMapper();
208 int mapSize = mapper.getMapSize();
209 if (mapSize == 0)
return;
211 auto* sortedDigits =
new vector<const TOPRawDigit*>[mapSize];
213 for (
const auto& digit : digits) {
214 auto scrodID = digit.getScrodID();
215 const auto* feemap = mapper.getMap(scrodID);
217 B2ERROR(
"TOPPacker: no front-end map available."
218 <<
LogVar(
"scrodID", scrodID));
221 sortedDigits[feemap->getIndex()].push_back(&digit);
224 for (
const auto& copperID : mapper.getCopperIDs()) {
226 for (
int finesse = 0; finesse < 4; finesse++) {
227 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
228 if (!feemap)
continue;
229 unsigned scrodID = feemap->getScrodID();
230 unsigned dataFormat =
static_cast<unsigned>(TOP::RawDataType::c_Type0Ver16);
233 unsigned head = (dataFormat << 16) | (0xA << 12) | (scrodID & 0x0FFF);
234 Buffer[finesse].push_back(head);
236 for (
const auto& digit : sortedDigits[feemap->getIndex()]) {
238 (digit->getCarrierNumber() << 30) |
239 ((digit->getASICNumber() & 0x3) << 28) |
240 ((digit->getASICChannel() & 0x7) << 25) |
241 ((digit->getASICWindow() & 0x1FF) << 16) |
243 ((digit->getTFine() & 0xF) << 8);
244 Buffer[finesse].push_back(word1);
246 ((digit->getValuePeak() & 0x1FFF) << 16) |
247 (digit->getIntegral() & 0xFFFF);
248 Buffer[finesse].push_back(word2);
250 ((digit->getValueRise0() & 0x1FFF) << 16) |
251 (digit->getValueRise1() & 0x1FFF);
252 Buffer[finesse].push_back(word3);
254 ((digit->getValueFall0() & 0x1FFF) << 16) |
255 (digit->getValueFall1() & 0x1FFF);
256 Buffer[finesse].push_back(word4);
258 (digit->getSampleRise() << 24) |
259 ((digit->getDeltaSamplePeak() & 0xF) << 20) |
260 ((digit->getDeltaSampleFall() & 0xF) << 16);
261 short checkSum = -(sumShorts(word1) + sumShorts(word2) + sumShorts(word3) +
262 sumShorts(word4) + sumShorts(word5));
263 word5 |= (checkSum & 0xFFFF);
264 Buffer[finesse].push_back(word5);
267 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
268 Buffer[finesse].push_back(tail);
271 info.exp_num = evtMetaData->getExperiment();
273 info.run_subrun_num = (evtMetaData->getRun() << 8) +
274 (evtMetaData->getSubrun() & 0xFF);
275 info.eve_num = evtMetaData->getEvent();
276 info.node_id = TOP_ID + copperID;
280 info.hslb_crc16_error_bit = 0;
281 info.truncation_mask = 0;
282 info.type_of_data = 0;
285 raw->PackDetectorBuf(
Buffer[0].data(),
Buffer[0].size(),
291 delete [] sortedDigits;
295 void TOPPackerModule::packProductionDebug()
301 const auto& mapper = m_topgp->getFrontEndMapper();
302 int mapSize = mapper.getMapSize();
303 if (mapSize == 0)
return;
305 auto* sortedDigits =
new vector<const TOPRawDigit*>[mapSize];
307 for (
const auto& digit : digits) {
308 auto scrodID = digit.getScrodID();
309 const auto* feemap = mapper.getMap(scrodID);
311 B2ERROR(
"TOPPacker: no front-end map available."
312 <<
LogVar(
"scrodID", scrodID));
315 sortedDigits[feemap->getIndex()].push_back(&digit);
318 unsigned revo9count = 0;
320 if (digits.getEntries() > 0) {
321 revo9count = digits[0]->getRevo9Counter();
322 phase = digits[0]->getPhase();
325 for (
const auto& copperID : mapper.getCopperIDs()) {
327 for (
int finesse = 0; finesse < 4; finesse++) {
328 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
329 if (!feemap)
continue;
330 unsigned scrodID = feemap->getScrodID();
331 unsigned format =
static_cast<unsigned>(TOP::RawDataType::c_ProductionDebug01);
333 unsigned head0 = (format << 16) | (0xA << 12) | (scrodID & 0x0FFF);
334 Buffer[finesse].push_back(head0);
336 unsigned numWordsCore = sortedDigits[feemap->getIndex()].size() * 5 + 1;
337 unsigned head1 = ((phase & 0xF) << 12) | (numWordsCore & 0xFFF);
338 Buffer[finesse].push_back(head1);
340 unsigned head2 = revo9count & 0xFFFF;
341 Buffer[finesse].push_back(head2);
344 Buffer[finesse].push_back(head3);
347 for (
const auto& digit : sortedDigits[feemap->getIndex()]) {
348 unsigned checkSum = 0;
350 (digit->getCarrierNumber() << 30) |
351 ((digit->getASICNumber() & 0x3) << 28) |
352 ((digit->getASICChannel() & 0x7) << 25) |
353 ((digit->getASICWindow() & 0x1FF) << 16) |
355 ((digit->getTFine() & 0xF) << 8);
356 checkSum += (word0 & 0xFFFF) + ((word0 >> 16) & 0xFFFF);
357 Buffer[finesse].push_back(word0);
359 ((digit->getValuePeak() & 0x1FFF) << 16) |
360 (digit->getIntegral() & 0xFFFF);
361 checkSum += (word1 & 0xFFFF) + ((word1 >> 16) & 0xFFFF);
362 Buffer[finesse].push_back(word1);
364 ((digit->getValueRise0() & 0x1FFF) << 16) |
365 (digit->getValueRise1() & 0x1FFF);
366 checkSum += (word2 & 0xFFFF) + ((word2 >> 16) & 0xFFFF);
367 Buffer[finesse].push_back(word2);
369 ((digit->getValueFall0() & 0x1FFF) << 16) |
370 (digit->getValueFall1() & 0x1FFF);
371 checkSum += (word3 & 0xFFFF) + ((word3 >> 16) & 0xFFFF);
372 Buffer[finesse].push_back(word3);
374 (digit->getSampleRise() << 24) |
375 ((digit->getDeltaSamplePeak() & 0xF) << 20) |
376 ((digit->getDeltaSampleFall() & 0xF) << 16);
377 checkSum += (word4 & 0xFFFF) + ((word4 >> 16) & 0xFFFF);
378 while ((checkSum >> 16) > 0) {
379 checkSum = (checkSum & 0xFFFF) + (checkSum >> 16);
381 word4 |= ((~checkSum) & 0xFFFF);
382 Buffer[finesse].push_back(word4);
385 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
386 Buffer[finesse].push_back(tail);
390 info.exp_num = evtMetaData->getExperiment();
392 info.run_subrun_num = (evtMetaData->getRun() << 8) +
393 (evtMetaData->getSubrun() & 0xFF);
394 info.eve_num = evtMetaData->getEvent();
395 info.node_id = TOP_ID + copperID;
399 info.hslb_crc16_error_bit = 0;
400 info.truncation_mask = 0;
401 info.type_of_data = 0;
404 raw->PackDetectorBuf(
Buffer[0].data(),
Buffer[0].size(),
410 delete [] sortedDigits;