10 #include <top/modules/TOPPacker/TOPPackerModule.h>
11 #include <top/RawDataTypes.h>
14 #include <framework/datastore/StoreArray.h>
15 #include <framework/datastore/StoreObjPtr.h>
18 #include <framework/logging/Logger.h>
21 #include <top/dataobjects/TOPDigit.h>
22 #include <top/dataobjects/TOPRawDigit.h>
23 #include <rawdata/dataobjects/RawTOP.h>
24 #include <framework/dataobjects/EventMetaData.h>
49 setDescription(
"Raw data packer for TOP");
50 setPropertyFlags(c_ParallelProcessingCertified);
53 addParam(
"inputDigitsName", m_inputDigitsName,
54 "name of TOPDigit store array",
string(
""));
55 addParam(
"inputRawDigitsName", m_inputRawDigitsName,
56 "name of TOPRawDigit store array",
string(
""));
57 addParam(
"outputRawDataName", m_outputRawDataName,
58 "name of RawTOP store array",
string(
""));
59 addParam(
"format", m_format,
60 "data format (draft, FE, production)",
string(
"production"));
64 TOPPackerModule::~TOPPackerModule()
68 void TOPPackerModule::initialize()
71 if (m_format ==
"draft") {
72 m_dataType = TOP::RawDataType::c_Draft;
75 }
else if (m_format ==
"FE") {
76 m_dataType = TOP::RawDataType::c_Type0Ver16;
79 }
else if (m_format ==
"production") {
80 m_dataType = TOP::RawDataType::c_ProductionDebug01;
84 B2ERROR(
"TOPPacker: unknown data format."
85 <<
LogVar(
"format", m_format));
92 const auto& mapper = m_topgp->getFrontEndMapper();
93 if (!mapper.isValid()) B2ERROR(
"No front-end mapping available for TOP");
97 void TOPPackerModule::beginRun()
101 void TOPPackerModule::event()
104 switch (m_dataType) {
105 case TOP::RawDataType::c_Type0Ver16:
108 case TOP::RawDataType::c_ProductionDebug01:
109 packProductionDebug();
111 case TOP::RawDataType::c_Draft:
112 packProductionDraft();
115 B2ERROR(
"TOPPacker: data format unknown or not implemented");
121 void TOPPackerModule::endRun()
125 void TOPPackerModule::terminate()
130 void TOPPackerModule::packProductionDraft()
136 const auto& mapper = m_topgp->getFrontEndMapper();
137 int mapSize = mapper.getMapSize();
138 if (mapSize == 0)
return;
140 vector<const TOPDigit*>* sortedDigits =
new vector<const TOPDigit*>[mapSize];
142 for (
const auto& digit : digits) {
143 int moduleID = digit.getModuleID();
144 int boardstack = digit.getChannel() / 128;
145 const auto* feemap = mapper.getMap(moduleID, boardstack);
147 B2ERROR(
"TOPPacker: no front-end map available."
148 <<
LogVar(
"moduleID", moduleID)
149 <<
LogVar(
"boardstack", boardstack));
152 sortedDigits[feemap->getIndex()].push_back(&digit);
155 auto subBits = m_topgp->getGeometry()->getNominalTDC().getSubBits();
156 int sampleDivisions = 0x1 << subBits;
158 for (
const auto& copperID : mapper.getCopperIDs()) {
160 for (
int finesse = 0; finesse < 4; finesse++) {
161 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
162 if (!feemap)
continue;
163 unsigned scrodID = feemap->getScrodID();
164 unsigned dataFormat =
static_cast<unsigned>(TOP::RawDataType::c_Draft);
165 Buffer[finesse].push_back(scrodID + (dataFormat << 16));
166 for (
const auto& digit : sortedDigits[feemap->getIndex()]) {
167 double rawTime = digit->getRawTime();
168 unsigned tdc = int(rawTime * sampleDivisions) & 0xFFFF;
169 unsigned chan = digit->getChannel() % 128;
170 unsigned flags = (unsigned) digit->getHitQuality();
171 Buffer[finesse].push_back(tdc + (chan << 16) + (flags << 24));
175 info.exp_num = evtMetaData->getExperiment();
177 info.run_subrun_num = (evtMetaData->getRun() << 8) +
178 (evtMetaData->getSubrun() & 0xFF);
179 info.eve_num = evtMetaData->getEvent();
180 info.node_id = TOP_ID + copperID;
184 info.hslb_crc16_error_bit = 0;
185 info.truncation_mask = 0;
186 info.type_of_data = 0;
189 raw->PackDetectorBuf(
Buffer[0].data(),
Buffer[0].size(),
195 delete [] sortedDigits;
199 void TOPPackerModule::packType0Ver16()
205 const auto& mapper = m_topgp->getFrontEndMapper();
206 int mapSize = mapper.getMapSize();
207 if (mapSize == 0)
return;
209 auto* sortedDigits =
new vector<const TOPRawDigit*>[mapSize];
211 for (
const auto& digit : digits) {
212 auto scrodID = digit.getScrodID();
213 const auto* feemap = mapper.getMap(scrodID);
215 B2ERROR(
"TOPPacker: no front-end map available."
216 <<
LogVar(
"scrodID", scrodID));
219 sortedDigits[feemap->getIndex()].push_back(&digit);
222 for (
const auto& copperID : mapper.getCopperIDs()) {
224 for (
int finesse = 0; finesse < 4; finesse++) {
225 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
226 if (!feemap)
continue;
227 unsigned scrodID = feemap->getScrodID();
228 unsigned dataFormat =
static_cast<unsigned>(TOP::RawDataType::c_Type0Ver16);
231 unsigned head = (dataFormat << 16) | (0xA << 12) | (scrodID & 0x0FFF);
232 Buffer[finesse].push_back(head);
234 for (
const auto& digit : sortedDigits[feemap->getIndex()]) {
236 (digit->getCarrierNumber() << 30) |
237 ((digit->getASICNumber() & 0x3) << 28) |
238 ((digit->getASICChannel() & 0x7) << 25) |
239 ((digit->getASICWindow() & 0x1FF) << 16) |
241 ((digit->getTFine() & 0xF) << 8);
242 Buffer[finesse].push_back(word1);
244 ((digit->getValuePeak() & 0x1FFF) << 16) |
245 (digit->getIntegral() & 0xFFFF);
246 Buffer[finesse].push_back(word2);
248 ((digit->getValueRise0() & 0x1FFF) << 16) |
249 (digit->getValueRise1() & 0x1FFF);
250 Buffer[finesse].push_back(word3);
252 ((digit->getValueFall0() & 0x1FFF) << 16) |
253 (digit->getValueFall1() & 0x1FFF);
254 Buffer[finesse].push_back(word4);
256 (digit->getSampleRise() << 24) |
257 ((digit->getDeltaSamplePeak() & 0xF) << 20) |
258 ((digit->getDeltaSampleFall() & 0xF) << 16);
259 short checkSum = -(sumShorts(word1) + sumShorts(word2) + sumShorts(word3) +
260 sumShorts(word4) + sumShorts(word5));
261 word5 |= (checkSum & 0xFFFF);
262 Buffer[finesse].push_back(word5);
265 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
266 Buffer[finesse].push_back(tail);
269 info.exp_num = evtMetaData->getExperiment();
271 info.run_subrun_num = (evtMetaData->getRun() << 8) +
272 (evtMetaData->getSubrun() & 0xFF);
273 info.eve_num = evtMetaData->getEvent();
274 info.node_id = TOP_ID + copperID;
278 info.hslb_crc16_error_bit = 0;
279 info.truncation_mask = 0;
280 info.type_of_data = 0;
283 raw->PackDetectorBuf(
Buffer[0].data(),
Buffer[0].size(),
289 delete [] sortedDigits;
293 void TOPPackerModule::packProductionDebug()
299 const auto& mapper = m_topgp->getFrontEndMapper();
300 int mapSize = mapper.getMapSize();
301 if (mapSize == 0)
return;
303 auto* sortedDigits =
new vector<const TOPRawDigit*>[mapSize];
305 for (
const auto& digit : digits) {
306 auto scrodID = digit.getScrodID();
307 const auto* feemap = mapper.getMap(scrodID);
309 B2ERROR(
"TOPPacker: no front-end map available."
310 <<
LogVar(
"scrodID", scrodID));
313 sortedDigits[feemap->getIndex()].push_back(&digit);
316 unsigned revo9count = 0;
318 if (digits.getEntries() > 0) {
319 revo9count = digits[0]->getRevo9Counter();
320 phase = digits[0]->getPhase();
323 for (
const auto& copperID : mapper.getCopperIDs()) {
325 for (
int finesse = 0; finesse < 4; finesse++) {
326 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
327 if (!feemap)
continue;
328 unsigned scrodID = feemap->getScrodID();
329 unsigned format =
static_cast<unsigned>(TOP::RawDataType::c_ProductionDebug01);
331 unsigned head0 = (format << 16) | (0xA << 12) | (scrodID & 0x0FFF);
332 Buffer[finesse].push_back(head0);
334 unsigned numWordsCore = sortedDigits[feemap->getIndex()].size() * 5 + 1;
335 unsigned head1 = ((phase & 0xF) << 12) | (numWordsCore & 0xFFF);
336 Buffer[finesse].push_back(head1);
338 unsigned head2 = revo9count & 0xFFFF;
339 Buffer[finesse].push_back(head2);
342 Buffer[finesse].push_back(head3);
345 for (
const auto& digit : sortedDigits[feemap->getIndex()]) {
346 unsigned checkSum = 0;
348 (digit->getCarrierNumber() << 30) |
349 ((digit->getASICNumber() & 0x3) << 28) |
350 ((digit->getASICChannel() & 0x7) << 25) |
351 ((digit->getASICWindow() & 0x1FF) << 16) |
353 ((digit->getTFine() & 0xF) << 8);
354 checkSum += (word0 & 0xFFFF) + ((word0 >> 16) & 0xFFFF);
355 Buffer[finesse].push_back(word0);
357 ((digit->getValuePeak() & 0x1FFF) << 16) |
358 (digit->getIntegral() & 0xFFFF);
359 checkSum += (word1 & 0xFFFF) + ((word1 >> 16) & 0xFFFF);
360 Buffer[finesse].push_back(word1);
362 ((digit->getValueRise0() & 0x1FFF) << 16) |
363 (digit->getValueRise1() & 0x1FFF);
364 checkSum += (word2 & 0xFFFF) + ((word2 >> 16) & 0xFFFF);
365 Buffer[finesse].push_back(word2);
367 ((digit->getValueFall0() & 0x1FFF) << 16) |
368 (digit->getValueFall1() & 0x1FFF);
369 checkSum += (word3 & 0xFFFF) + ((word3 >> 16) & 0xFFFF);
370 Buffer[finesse].push_back(word3);
372 (digit->getSampleRise() << 24) |
373 ((digit->getDeltaSamplePeak() & 0xF) << 20) |
374 ((digit->getDeltaSampleFall() & 0xF) << 16);
375 checkSum += (word4 & 0xFFFF) + ((word4 >> 16) & 0xFFFF);
376 while ((checkSum >> 16) > 0) {
377 checkSum = (checkSum & 0xFFFF) + (checkSum >> 16);
379 word4 |= ((~checkSum) & 0xFFFF);
380 Buffer[finesse].push_back(word4);
383 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
384 Buffer[finesse].push_back(tail);
388 info.exp_num = evtMetaData->getExperiment();
390 info.run_subrun_num = (evtMetaData->getRun() << 8) +
391 (evtMetaData->getSubrun() & 0xFF);
392 info.eve_num = evtMetaData->getEvent();
393 info.node_id = TOP_ID + copperID;
397 info.hslb_crc16_error_bit = 0;
398 info.truncation_mask = 0;
399 info.type_of_data = 0;
402 raw->PackDetectorBuf(
Buffer[0].data(),
Buffer[0].size(),
408 delete [] sortedDigits;
struct to contain header information used by RawCOPPERFormat::Packer()
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.
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.