Belle II Software development
TOPPackerModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9// Own header.
10#include <top/modules/TOPPacker/TOPPackerModule.h>
11
12// TOP headers.
13#include <top/RawDataTypes.h>
14
15// framework - DataStore
16#include <framework/datastore/StoreArray.h>
17#include <framework/datastore/StoreObjPtr.h>
18
19// framework aux
20#include <framework/logging/Logger.h>
21
22// Dataobject classes
23#include <top/dataobjects/TOPDigit.h>
24#include <top/dataobjects/TOPRawDigit.h>
25#include <rawdata/dataobjects/RawTOP.h>
26#include <framework/dataobjects/EventMetaData.h>
27
28using namespace std;
29
30namespace Belle2 {
35
36 using namespace TOP;
37
38 //-----------------------------------------------------------------
40 //-----------------------------------------------------------------
41
42 REG_MODULE(TOPPacker);
43
44 //-----------------------------------------------------------------
45 // Implementation
46 //-----------------------------------------------------------------
47
49 {
50 // set module description (e.g. insert text)
51 setDescription("Raw data packer for TOP");
53
54 // Add parameters
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"));
63
64 }
65
67 {
68
69 if (m_format == "draft") {
70 m_dataType = TOP::RawDataType::c_Draft;
72 digits.isRequired();
73 } else if (m_format == "FE") {
74 m_dataType = TOP::RawDataType::c_Type0Ver16;
76 rawDigits.isRequired();
77 } else if (m_format == "production") {
78 m_dataType = TOP::RawDataType::c_ProductionDebug01;
80 rawDigits.isRequired();
81 } else {
82 B2ERROR("TOPPacker: unknown data format."
83 << LogVar("format", m_format));
84 }
85
87 rawData.registerInDataStore();
88
89 // check if front end mappings are available
90 const auto& mapper = m_topgp->getFrontEndMapper();
91 if (!mapper.isValid()) B2ERROR("No front-end mapping available for TOP");
92
93 }
94
96 {
97
98 switch (m_dataType) {
99 case TOP::RawDataType::c_Type0Ver16:
101 break;
102 case TOP::RawDataType::c_ProductionDebug01:
104 break;
105 case TOP::RawDataType::c_Draft:
107 break;
108 default:
109 B2ERROR("TOPPacker: data format unknown or not implemented");
110 }
111
112 }
113
114
116 {
117 StoreObjPtr<EventMetaData> evtMetaData;
120
121 const auto& mapper = m_topgp->getFrontEndMapper();
122 int mapSize = mapper.getMapSize();
123 if (mapSize <= 0) return;
124
125 vector<const TOPDigit*>* sortedDigits = new vector<const TOPDigit*>[mapSize];
126
127 for (const auto& digit : digits) {
128 int moduleID = digit.getModuleID();
129 int boardstack = digit.getChannel() / 128;
130 const auto* feemap = mapper.getMap(moduleID, boardstack);
131 if (!feemap) {
132 B2ERROR("TOPPacker: no front-end map available."
133 << LogVar("moduleID", moduleID)
134 << LogVar("boardstack", boardstack));
135 continue;
136 }
137 sortedDigits[feemap->getIndex()].push_back(&digit);
138 }
139
140 auto subBits = m_topgp->getGeometry()->getNominalTDC().getSubBits();
141 int sampleDivisions = 0x1 << subBits;
142
143 for (const auto& copperID : mapper.getCopperIDs()) {
144 vector<int> Buffer[4];
145 for (int finesse = 0; finesse < 4; finesse++) {
146 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
147 if (!feemap) continue;
148 unsigned scrodID = feemap->getScrodID();
149 unsigned dataFormat = static_cast<unsigned>(TOP::RawDataType::c_Draft);
150 Buffer[finesse].push_back(scrodID + (dataFormat << 16));
151 for (const auto& digit : sortedDigits[feemap->getIndex()]) {
152 double rawTime = digit->getRawTime();
153 unsigned tdc = int(rawTime * sampleDivisions) & 0xFFFF;
154 unsigned chan = digit->getChannel() % 128;
155 unsigned flags = (unsigned) digit->getHitQuality();
156 Buffer[finesse].push_back(tdc + (chan << 16) + (flags << 24));
157 }
158 }
160 info.exp_num = evtMetaData->getExperiment();
161 // run number : 14bits, subrun # : 8bits
162 info.run_subrun_num = (evtMetaData->getRun() << 8) +
163 (evtMetaData->getSubrun() & 0xFF);
164 info.eve_num = evtMetaData->getEvent();
165 info.node_id = TOP_ID + copperID;
166 info.tt_ctime = 0;
167 info.tt_utime = 0;
168 info.b2l_ctime = 0;
169 info.hslb_crc16_error_bit = 0;
170 info.truncation_mask = 0;
171 info.type_of_data = 0;
172
173 auto* raw = rawData.appendNew();
174 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
175 Buffer[1].data(), Buffer[1].size(),
176 Buffer[2].data(), Buffer[2].size(),
177 Buffer[3].data(), Buffer[3].size(),
178 info);
179 }
180 delete [] sortedDigits;
181 }
182
183
185 {
186 StoreObjPtr<EventMetaData> evtMetaData;
189
190 const auto& mapper = m_topgp->getFrontEndMapper();
191 int mapSize = mapper.getMapSize();
192 if (mapSize <= 0) return;
193
194 auto* sortedDigits = new vector<const TOPRawDigit*>[mapSize];
195
196 for (const auto& digit : digits) {
197 auto scrodID = digit.getScrodID();
198 const auto* feemap = mapper.getMap(scrodID);
199 if (!feemap) {
200 B2ERROR("TOPPacker: no front-end map available."
201 << LogVar("scrodID", scrodID));
202 continue;
203 }
204 sortedDigits[feemap->getIndex()].push_back(&digit);
205 }
206
207 for (const auto& copperID : mapper.getCopperIDs()) {
208 vector<int> Buffer[4];
209 for (int finesse = 0; finesse < 4; finesse++) {
210 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
211 if (!feemap) continue;
212 unsigned scrodID = feemap->getScrodID();
213 unsigned dataFormat = static_cast<unsigned>(TOP::RawDataType::c_Type0Ver16);
214
215 // production data v2.1 (data_format_v2_1.xlsx from Lynn 06/26/2016)
216 unsigned head = (dataFormat << 16) | (0xA << 12) | (scrodID & 0x0FFF);
217 Buffer[finesse].push_back(head);
218 unsigned Nhits = 0;
219 for (const auto& digit : sortedDigits[feemap->getIndex()]) {
220 unsigned word1 =
221 (digit->getCarrierNumber() << 30) |
222 ((digit->getASICNumber() & 0x3) << 28) |
223 ((digit->getASICChannel() & 0x7) << 25) |
224 ((digit->getASICWindow() & 0x1FF) << 16) |
225 (0xB << 12) |
226 ((digit->getTFine() & 0xF) << 8);
227 Buffer[finesse].push_back(word1);
228 unsigned word2 =
229 ((digit->getValuePeak() & 0x1FFF) << 16) |
230 (digit->getIntegral() & 0xFFFF);
231 Buffer[finesse].push_back(word2);
232 unsigned word3 =
233 ((digit->getValueRise0() & 0x1FFF) << 16) |
234 (digit->getValueRise1() & 0x1FFF);
235 Buffer[finesse].push_back(word3);
236 unsigned word4 =
237 ((digit->getValueFall0() & 0x1FFF) << 16) |
238 (digit->getValueFall1() & 0x1FFF);
239 Buffer[finesse].push_back(word4);
240 unsigned word5 =
241 (digit->getSampleRise() << 24) |
242 ((digit->getDeltaSamplePeak() & 0xF) << 20) |
243 ((digit->getDeltaSampleFall() & 0xF) << 16);
244 short checkSum = -(sumShorts(word1) + sumShorts(word2) + sumShorts(word3) +
245 sumShorts(word4) + sumShorts(word5));
246 word5 |= (checkSum & 0xFFFF);
247 Buffer[finesse].push_back(word5);
248 Nhits++;
249 }
250 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
251 Buffer[finesse].push_back(tail);
252 }
254 info.exp_num = evtMetaData->getExperiment();
255 // run number : 14bits, subrun # : 8bits
256 info.run_subrun_num = (evtMetaData->getRun() << 8) +
257 (evtMetaData->getSubrun() & 0xFF);
258 info.eve_num = evtMetaData->getEvent();
259 info.node_id = TOP_ID + copperID;
260 info.tt_ctime = 0;
261 info.tt_utime = 0;
262 info.b2l_ctime = 0;
263 info.hslb_crc16_error_bit = 0;
264 info.truncation_mask = 0;
265 info.type_of_data = 0;
266
267 auto* raw = rawData.appendNew();
268 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
269 Buffer[1].data(), Buffer[1].size(),
270 Buffer[2].data(), Buffer[2].size(),
271 Buffer[3].data(), Buffer[3].size(),
272 info);
273 }
274 delete [] sortedDigits;
275 }
276
277
279 {
280 StoreObjPtr<EventMetaData> evtMetaData;
283
284 const auto& mapper = m_topgp->getFrontEndMapper();
285 int mapSize = mapper.getMapSize();
286 if (mapSize <= 0) return;
287
288 auto* sortedDigits = new vector<const TOPRawDigit*>[mapSize];
289
290 for (const auto& digit : digits) {
291 auto scrodID = digit.getScrodID();
292 const auto* feemap = mapper.getMap(scrodID);
293 if (!feemap) {
294 B2ERROR("TOPPacker: no front-end map available."
295 << LogVar("scrodID", scrodID));
296 continue;
297 }
298 sortedDigits[feemap->getIndex()].push_back(&digit);
299 }
300
301 unsigned revo9count = 0;
302 unsigned phase = 0;
303 if (digits.getEntries() > 0) {
304 revo9count = digits[0]->getRevo9Counter();
305 phase = digits[0]->getPhase();
306 }
307
308 for (const auto& copperID : mapper.getCopperIDs()) {
309 vector<int> Buffer[4];
310 for (int finesse = 0; finesse < 4; finesse++) {
311 const auto* feemap = mapper.getMapFromCopper(copperID, finesse);
312 if (!feemap) continue;
313 unsigned scrodID = feemap->getScrodID();
314 unsigned format = static_cast<unsigned>(TOP::RawDataType::c_ProductionDebug01);
315
316 unsigned head0 = (format << 16) | (0xA << 12) | (scrodID & 0x0FFF);
317 Buffer[finesse].push_back(head0);
318
319 unsigned numWordsCore = sortedDigits[feemap->getIndex()].size() * 5 + 1;
320 unsigned head1 = ((phase & 0xF) << 12) | (numWordsCore & 0xFFF);
321 Buffer[finesse].push_back(head1);
322
323 unsigned head2 = revo9count & 0xFFFF;
324 Buffer[finesse].push_back(head2);
325
326 unsigned head3 = 0;
327 Buffer[finesse].push_back(head3);
328
329 unsigned Nhits = 0;
330 for (const auto& digit : sortedDigits[feemap->getIndex()]) {
331 unsigned checkSum = 0; // IPv4 checksum
332 unsigned word0 =
333 (digit->getCarrierNumber() << 30) |
334 ((digit->getASICNumber() & 0x3) << 28) |
335 ((digit->getASICChannel() & 0x7) << 25) |
336 ((digit->getASICWindow() & 0x1FF) << 16) |
337 (0xB << 12) |
338 ((digit->getTFine() & 0xF) << 8);
339 checkSum += (word0 & 0xFFFF) + ((word0 >> 16) & 0xFFFF);
340 Buffer[finesse].push_back(word0);
341 unsigned word1 =
342 ((digit->getValuePeak() & 0x1FFF) << 16) |
343 (digit->getIntegral() & 0xFFFF);
344 checkSum += (word1 & 0xFFFF) + ((word1 >> 16) & 0xFFFF);
345 Buffer[finesse].push_back(word1);
346 unsigned word2 =
347 ((digit->getValueRise0() & 0x1FFF) << 16) |
348 (digit->getValueRise1() & 0x1FFF);
349 checkSum += (word2 & 0xFFFF) + ((word2 >> 16) & 0xFFFF);
350 Buffer[finesse].push_back(word2);
351 unsigned word3 =
352 ((digit->getValueFall0() & 0x1FFF) << 16) |
353 (digit->getValueFall1() & 0x1FFF);
354 checkSum += (word3 & 0xFFFF) + ((word3 >> 16) & 0xFFFF);
355 Buffer[finesse].push_back(word3);
356 unsigned word4 =
357 (digit->getSampleRise() << 24) |
358 ((digit->getDeltaSamplePeak() & 0xF) << 20) |
359 ((digit->getDeltaSampleFall() & 0xF) << 16);
360 checkSum += (word4 & 0xFFFF) + ((word4 >> 16) & 0xFFFF);
361 while ((checkSum >> 16) > 0) {
362 checkSum = (checkSum & 0xFFFF) + (checkSum >> 16);
363 }
364 word4 |= ((~checkSum) & 0xFFFF);
365 Buffer[finesse].push_back(word4);
366 Nhits++;
367 }
368 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
369 Buffer[finesse].push_back(tail);
370 }
371
373 info.exp_num = evtMetaData->getExperiment();
374 // run number : 14bits, subrun # : 8bits
375 info.run_subrun_num = (evtMetaData->getRun() << 8) +
376 (evtMetaData->getSubrun() & 0xFF);
377 info.eve_num = evtMetaData->getEvent();
378 info.node_id = TOP_ID + copperID;
379 info.tt_ctime = 0;
380 info.tt_utime = 0;
381 info.b2l_ctime = 0;
382 info.hslb_crc16_error_bit = 0;
383 info.truncation_mask = 0;
384 info.type_of_data = 0;
385
386 auto* raw = rawData.appendNew();
387 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
388 Buffer[1].data(), Buffer[1].size(),
389 Buffer[2].data(), Buffer[2].size(),
390 Buffer[3].data(), Buffer[3].size(),
391 info);
392 }
393 delete [] sortedDigits;
394 }
395
397} // end Belle2 namespace
398
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
Module()
Constructor.
Definition Module.cc:30
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
struct to contain header information used by RawCOPPERFormat::Packer()
unsigned int exp_num
Experiment number (10bit)
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.
Definition StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition StoreArray.h:246
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
std::string m_format
data format
std::string m_inputDigitsName
name of TOPDigit store array
TOP::RawDataType m_dataType
enum for data format
std::string m_outputRawDataName
name of RawTOP store array
std::string m_inputRawDigitsName
name of TOPRawDigit store array
static unsigned short sumShorts(unsigned int x)
sum both 16-bit words of 32-bit integer
TOP::TOPGeometryPar * m_topgp
geometry
Class to store variables with their name which were sent to the logging service.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
virtual void initialize() override
Initialize the Module.
void packProductionDraft()
Pack in format: c_Draft (tentative production format) this format was never implemented in firmware!
void packProductionDebug()
Pack in format: Production Debugging Data Format 01.
virtual void event() override
Event processor.
void packType0Ver16()
Pack in format: c_Type0Ver16 (Feature-extracted data) this format was never implemented in firmware!
Abstract base class for different kinds of events.
STL namespace.