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 {
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
71 {
72
73 if (m_format == "draft") {
74 m_dataType = TOP::RawDataType::c_Draft;
76 digits.isRequired();
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();
85 } else {
86 B2ERROR("TOPPacker: unknown data format."
87 << LogVar("format", m_format));
88 }
89
91 rawData.registerInDataStore();
92
93 // check if front end mappings are available
94 const auto& mapper = m_topgp->getFrontEndMapper();
95 if (!mapper.isValid()) B2ERROR("No front-end mapping available for TOP");
96
97 }
98
100 {
101 }
102
104 {
105
106 switch (m_dataType) {
107 case TOP::RawDataType::c_Type0Ver16:
109 break;
110 case TOP::RawDataType::c_ProductionDebug01:
112 break;
113 case TOP::RawDataType::c_Draft:
115 break;
116 default:
117 B2ERROR("TOPPacker: data format unknown or not implemented");
118 }
119
120 }
121
122
124 {
125 }
126
128 {
129 }
130
131
133 {
134 StoreObjPtr<EventMetaData> evtMetaData;
137
138 const auto& mapper = m_topgp->getFrontEndMapper();
139 int mapSize = mapper.getMapSize();
140 if (mapSize == 0) return;
141
142 vector<const TOPDigit*>* sortedDigits = new vector<const TOPDigit*>[mapSize];
143
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);
148 if (!feemap) {
149 B2ERROR("TOPPacker: no front-end map available."
150 << LogVar("moduleID", moduleID)
151 << LogVar("boardstack", boardstack));
152 continue;
153 }
154 sortedDigits[feemap->getIndex()].push_back(&digit);
155 }
156
157 auto subBits = m_topgp->getGeometry()->getNominalTDC().getSubBits();
158 int sampleDivisions = 0x1 << subBits;
159
160 for (const auto& copperID : mapper.getCopperIDs()) {
161 vector<int> Buffer[4];
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));
174 }
175 }
177 info.exp_num = evtMetaData->getExperiment();
178 // run number : 14bits, subrun # : 8bits
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;
183 info.tt_ctime = 0;
184 info.tt_utime = 0;
185 info.b2l_ctime = 0;
186 info.hslb_crc16_error_bit = 0;
187 info.truncation_mask = 0;
188 info.type_of_data = 0;
189
190 auto* raw = rawData.appendNew();
191 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
192 Buffer[1].data(), Buffer[1].size(),
193 Buffer[2].data(), Buffer[2].size(),
194 Buffer[3].data(), Buffer[3].size(),
195 info);
196 }
197 delete [] sortedDigits;
198 }
199
200
202 {
203 StoreObjPtr<EventMetaData> evtMetaData;
206
207 const auto& mapper = m_topgp->getFrontEndMapper();
208 int mapSize = mapper.getMapSize();
209 if (mapSize == 0) return;
210
211 auto* sortedDigits = new vector<const TOPRawDigit*>[mapSize];
212
213 for (const auto& digit : digits) {
214 auto scrodID = digit.getScrodID();
215 const auto* feemap = mapper.getMap(scrodID);
216 if (!feemap) {
217 B2ERROR("TOPPacker: no front-end map available."
218 << LogVar("scrodID", scrodID));
219 continue;
220 }
221 sortedDigits[feemap->getIndex()].push_back(&digit);
222 }
223
224 for (const auto& copperID : mapper.getCopperIDs()) {
225 vector<int> Buffer[4];
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);
231
232 // production data v2.1 (data_format_v2_1.xlsx from Lynn 06/26/2016)
233 unsigned head = (dataFormat << 16) | (0xA << 12) | (scrodID & 0x0FFF);
234 Buffer[finesse].push_back(head);
235 unsigned Nhits = 0;
236 for (const auto& digit : sortedDigits[feemap->getIndex()]) {
237 unsigned word1 =
238 (digit->getCarrierNumber() << 30) |
239 ((digit->getASICNumber() & 0x3) << 28) |
240 ((digit->getASICChannel() & 0x7) << 25) |
241 ((digit->getASICWindow() & 0x1FF) << 16) |
242 (0xB << 12) |
243 ((digit->getTFine() & 0xF) << 8);
244 Buffer[finesse].push_back(word1);
245 unsigned word2 =
246 ((digit->getValuePeak() & 0x1FFF) << 16) |
247 (digit->getIntegral() & 0xFFFF);
248 Buffer[finesse].push_back(word2);
249 unsigned word3 =
250 ((digit->getValueRise0() & 0x1FFF) << 16) |
251 (digit->getValueRise1() & 0x1FFF);
252 Buffer[finesse].push_back(word3);
253 unsigned word4 =
254 ((digit->getValueFall0() & 0x1FFF) << 16) |
255 (digit->getValueFall1() & 0x1FFF);
256 Buffer[finesse].push_back(word4);
257 unsigned word5 =
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);
265 Nhits++;
266 }
267 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
268 Buffer[finesse].push_back(tail);
269 }
271 info.exp_num = evtMetaData->getExperiment();
272 // run number : 14bits, subrun # : 8bits
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;
277 info.tt_ctime = 0;
278 info.tt_utime = 0;
279 info.b2l_ctime = 0;
280 info.hslb_crc16_error_bit = 0;
281 info.truncation_mask = 0;
282 info.type_of_data = 0;
283
284 auto* raw = rawData.appendNew();
285 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
286 Buffer[1].data(), Buffer[1].size(),
287 Buffer[2].data(), Buffer[2].size(),
288 Buffer[3].data(), Buffer[3].size(),
289 info);
290 }
291 delete [] sortedDigits;
292 }
293
294
296 {
297 StoreObjPtr<EventMetaData> evtMetaData;
300
301 const auto& mapper = m_topgp->getFrontEndMapper();
302 int mapSize = mapper.getMapSize();
303 if (mapSize == 0) return;
304
305 auto* sortedDigits = new vector<const TOPRawDigit*>[mapSize];
306
307 for (const auto& digit : digits) {
308 auto scrodID = digit.getScrodID();
309 const auto* feemap = mapper.getMap(scrodID);
310 if (!feemap) {
311 B2ERROR("TOPPacker: no front-end map available."
312 << LogVar("scrodID", scrodID));
313 continue;
314 }
315 sortedDigits[feemap->getIndex()].push_back(&digit);
316 }
317
318 unsigned revo9count = 0;
319 unsigned phase = 0;
320 if (digits.getEntries() > 0) {
321 revo9count = digits[0]->getRevo9Counter();
322 phase = digits[0]->getPhase();
323 }
324
325 for (const auto& copperID : mapper.getCopperIDs()) {
326 vector<int> Buffer[4];
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);
332
333 unsigned head0 = (format << 16) | (0xA << 12) | (scrodID & 0x0FFF);
334 Buffer[finesse].push_back(head0);
335
336 unsigned numWordsCore = sortedDigits[feemap->getIndex()].size() * 5 + 1;
337 unsigned head1 = ((phase & 0xF) << 12) | (numWordsCore & 0xFFF);
338 Buffer[finesse].push_back(head1);
339
340 unsigned head2 = revo9count & 0xFFFF;
341 Buffer[finesse].push_back(head2);
342
343 unsigned head3 = 0;
344 Buffer[finesse].push_back(head3);
345
346 unsigned Nhits = 0;
347 for (const auto& digit : sortedDigits[feemap->getIndex()]) {
348 unsigned checkSum = 0; // IPv4 checksum
349 unsigned word0 =
350 (digit->getCarrierNumber() << 30) |
351 ((digit->getASICNumber() & 0x3) << 28) |
352 ((digit->getASICChannel() & 0x7) << 25) |
353 ((digit->getASICWindow() & 0x1FF) << 16) |
354 (0xB << 12) |
355 ((digit->getTFine() & 0xF) << 8);
356 checkSum += (word0 & 0xFFFF) + ((word0 >> 16) & 0xFFFF);
357 Buffer[finesse].push_back(word0);
358 unsigned word1 =
359 ((digit->getValuePeak() & 0x1FFF) << 16) |
360 (digit->getIntegral() & 0xFFFF);
361 checkSum += (word1 & 0xFFFF) + ((word1 >> 16) & 0xFFFF);
362 Buffer[finesse].push_back(word1);
363 unsigned word2 =
364 ((digit->getValueRise0() & 0x1FFF) << 16) |
365 (digit->getValueRise1() & 0x1FFF);
366 checkSum += (word2 & 0xFFFF) + ((word2 >> 16) & 0xFFFF);
367 Buffer[finesse].push_back(word2);
368 unsigned word3 =
369 ((digit->getValueFall0() & 0x1FFF) << 16) |
370 (digit->getValueFall1() & 0x1FFF);
371 checkSum += (word3 & 0xFFFF) + ((word3 >> 16) & 0xFFFF);
372 Buffer[finesse].push_back(word3);
373 unsigned word4 =
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);
380 }
381 word4 |= ((~checkSum) & 0xFFFF);
382 Buffer[finesse].push_back(word4);
383 Nhits++;
384 }
385 unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
386 Buffer[finesse].push_back(tail);
387 }
388
390 info.exp_num = evtMetaData->getExperiment();
391 // run number : 14bits, subrun # : 8bits
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;
396 info.tt_ctime = 0;
397 info.tt_utime = 0;
398 info.b2l_ctime = 0;
399 info.hslb_crc16_error_bit = 0;
400 info.truncation_mask = 0;
401 info.type_of_data = 0;
402
403 auto* raw = rawData.appendNew();
404 raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
405 Buffer[1].data(), Buffer[1].size(),
406 Buffer[2].data(), Buffer[2].size(),
407 Buffer[3].data(), Buffer[3].size(),
408 info);
409 }
410 delete [] sortedDigits;
411 }
412
414} // end Belle2 namespace
415
Base class for Modules.
Definition: Module.h:72
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
@ 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()
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
const TOPNominalTDC & getNominalTDC() const
Returns nominal time-to-digit conversion parameters.
Definition: TOPGeometry.h:218
unsigned getSubBits() const
Returns number of bits per sample.
std::string m_format
data format
std::string m_inputDigitsName
name of TOPDigit store array
unsigned short sumShorts(unsigned int x) const
sum both 16-bit words of 32-bit integer
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
TOP::TOPGeometryPar * m_topgp
geometry
int getMapSize() const
Return size of the map.
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
const FrontEndMapper & getFrontEndMapper() const
Returns front-end mapper (mapping of SCROD's to positions within TOP modules)
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
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.
virtual ~TOPPackerModule()
Destructor.
virtual void endRun() override
End-of-run action.
virtual void terminate() override
Termination action.
virtual void beginRun() override
Called when entering a new run.
TOPPackerModule()
Constructor.
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.