Belle II Software  release-06-01-15
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 include
10 #include <top/modules/TOPPacker/TOPPackerModule.h>
11 #include <top/RawDataTypes.h>
12 
13 // framework - DataStore
14 #include <framework/datastore/StoreArray.h>
15 #include <framework/datastore/StoreObjPtr.h>
16 
17 // framework aux
18 #include <framework/logging/Logger.h>
19 
20 // Dataobject classes
21 #include <top/dataobjects/TOPDigit.h>
22 #include <top/dataobjects/TOPRawDigit.h>
23 #include <rawdata/dataobjects/RawTOP.h>
24 #include <framework/dataobjects/EventMetaData.h>
25 
26 using namespace std;
27 
28 namespace Belle2 {
34  using namespace TOP;
35 
36  //-----------------------------------------------------------------
37  // Register module
38  //-----------------------------------------------------------------
39 
40  REG_MODULE(TOPPacker)
41 
42  //-----------------------------------------------------------------
43  // Implementation
44  //-----------------------------------------------------------------
45 
47  {
48  // set module description (e.g. insert text)
49  setDescription("Raw data packer for TOP");
50  setPropertyFlags(c_ParallelProcessingCertified);
51 
52  // Add parameters
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"));
61 
62  }
63 
64  TOPPackerModule::~TOPPackerModule()
65  {
66  }
67 
68  void TOPPackerModule::initialize()
69  {
70 
71  if (m_format == "draft") {
72  m_dataType = TOP::RawDataType::c_Draft;
73  StoreArray<TOPDigit> digits(m_inputDigitsName);
74  digits.isRequired();
75  } else if (m_format == "FE") {
76  m_dataType = TOP::RawDataType::c_Type0Ver16;
77  StoreArray<TOPRawDigit> rawDigits(m_inputRawDigitsName);
78  rawDigits.isRequired();
79  } else if (m_format == "production") {
80  m_dataType = TOP::RawDataType::c_ProductionDebug01;
81  StoreArray<TOPRawDigit> rawDigits(m_inputRawDigitsName);
82  rawDigits.isRequired();
83  } else {
84  B2ERROR("TOPPacker: unknown data format."
85  << LogVar("format", m_format));
86  }
87 
88  StoreArray<RawTOP> rawData(m_outputRawDataName);
89  rawData.registerInDataStore();
90 
91  // check if front end mappings are available
92  const auto& mapper = m_topgp->getFrontEndMapper();
93  if (!mapper.isValid()) B2ERROR("No front-end mapping available for TOP");
94 
95  }
96 
97  void TOPPackerModule::beginRun()
98  {
99  }
100 
101  void TOPPackerModule::event()
102  {
103 
104  switch (m_dataType) {
105  case TOP::RawDataType::c_Type0Ver16:
106  packType0Ver16();
107  break;
108  case TOP::RawDataType::c_ProductionDebug01:
109  packProductionDebug();
110  break;
111  case TOP::RawDataType::c_Draft:
112  packProductionDraft();
113  break;
114  default:
115  B2ERROR("TOPPacker: data format unknown or not implemented");
116  }
117 
118  }
119 
120 
121  void TOPPackerModule::endRun()
122  {
123  }
124 
125  void TOPPackerModule::terminate()
126  {
127  }
128 
129 
130  void TOPPackerModule::packProductionDraft()
131  {
132  StoreObjPtr<EventMetaData> evtMetaData;
133  StoreArray<TOPDigit> digits(m_inputDigitsName);
134  StoreArray<RawTOP> rawData(m_outputRawDataName);
135 
136  const auto& mapper = m_topgp->getFrontEndMapper();
137  int mapSize = mapper.getMapSize();
138  if (mapSize == 0) return;
139 
140  vector<const TOPDigit*>* sortedDigits = new vector<const TOPDigit*>[mapSize];
141 
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);
146  if (!feemap) {
147  B2ERROR("TOPPacker: no front-end map available."
148  << LogVar("moduleID", moduleID)
149  << LogVar("boardstack", boardstack));
150  continue;
151  }
152  sortedDigits[feemap->getIndex()].push_back(&digit);
153  }
154 
155  auto subBits = m_topgp->getGeometry()->getNominalTDC().getSubBits();
156  int sampleDivisions = 0x1 << subBits;
157 
158  for (const auto& copperID : mapper.getCopperIDs()) {
159  vector<int> Buffer[4];
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));
172  }
173  }
174  RawCOPPERPackerInfo info;
175  info.exp_num = evtMetaData->getExperiment();
176  // run number : 14bits, subrun # : 8bits
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;
181  info.tt_ctime = 0;
182  info.tt_utime = 0;
183  info.b2l_ctime = 0;
184  info.hslb_crc16_error_bit = 0;
185  info.truncation_mask = 0;
186  info.type_of_data = 0;
187 
188  auto* raw = rawData.appendNew();
189  raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
190  Buffer[1].data(), Buffer[1].size(),
191  Buffer[2].data(), Buffer[2].size(),
192  Buffer[3].data(), Buffer[3].size(),
193  info);
194  }
195  delete [] sortedDigits;
196  }
197 
198 
199  void TOPPackerModule::packType0Ver16()
200  {
201  StoreObjPtr<EventMetaData> evtMetaData;
202  StoreArray<TOPRawDigit> digits(m_inputRawDigitsName);
203  StoreArray<RawTOP> rawData(m_outputRawDataName);
204 
205  const auto& mapper = m_topgp->getFrontEndMapper();
206  int mapSize = mapper.getMapSize();
207  if (mapSize == 0) return;
208 
209  auto* sortedDigits = new vector<const TOPRawDigit*>[mapSize];
210 
211  for (const auto& digit : digits) {
212  auto scrodID = digit.getScrodID();
213  const auto* feemap = mapper.getMap(scrodID);
214  if (!feemap) {
215  B2ERROR("TOPPacker: no front-end map available."
216  << LogVar("scrodID", scrodID));
217  continue;
218  }
219  sortedDigits[feemap->getIndex()].push_back(&digit);
220  }
221 
222  for (const auto& copperID : mapper.getCopperIDs()) {
223  vector<int> Buffer[4];
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);
229 
230  // production data v2.1 (data_format_v2_1.xlsx from Lynn 06/26/2016)
231  unsigned head = (dataFormat << 16) | (0xA << 12) | (scrodID & 0x0FFF);
232  Buffer[finesse].push_back(head);
233  unsigned Nhits = 0;
234  for (const auto& digit : sortedDigits[feemap->getIndex()]) {
235  unsigned word1 =
236  (digit->getCarrierNumber() << 30) |
237  ((digit->getASICNumber() & 0x3) << 28) |
238  ((digit->getASICChannel() & 0x7) << 25) |
239  ((digit->getASICWindow() & 0x1FF) << 16) |
240  (0xB << 12) |
241  ((digit->getTFine() & 0xF) << 8);
242  Buffer[finesse].push_back(word1);
243  unsigned word2 =
244  ((digit->getValuePeak() & 0x1FFF) << 16) |
245  (digit->getIntegral() & 0xFFFF);
246  Buffer[finesse].push_back(word2);
247  unsigned word3 =
248  ((digit->getValueRise0() & 0x1FFF) << 16) |
249  (digit->getValueRise1() & 0x1FFF);
250  Buffer[finesse].push_back(word3);
251  unsigned word4 =
252  ((digit->getValueFall0() & 0x1FFF) << 16) |
253  (digit->getValueFall1() & 0x1FFF);
254  Buffer[finesse].push_back(word4);
255  unsigned word5 =
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);
263  Nhits++;
264  }
265  unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
266  Buffer[finesse].push_back(tail);
267  }
268  RawCOPPERPackerInfo info;
269  info.exp_num = evtMetaData->getExperiment();
270  // run number : 14bits, subrun # : 8bits
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;
275  info.tt_ctime = 0;
276  info.tt_utime = 0;
277  info.b2l_ctime = 0;
278  info.hslb_crc16_error_bit = 0;
279  info.truncation_mask = 0;
280  info.type_of_data = 0;
281 
282  auto* raw = rawData.appendNew();
283  raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
284  Buffer[1].data(), Buffer[1].size(),
285  Buffer[2].data(), Buffer[2].size(),
286  Buffer[3].data(), Buffer[3].size(),
287  info);
288  }
289  delete [] sortedDigits;
290  }
291 
292 
293  void TOPPackerModule::packProductionDebug()
294  {
295  StoreObjPtr<EventMetaData> evtMetaData;
296  StoreArray<TOPRawDigit> digits(m_inputRawDigitsName);
297  StoreArray<RawTOP> rawData(m_outputRawDataName);
298 
299  const auto& mapper = m_topgp->getFrontEndMapper();
300  int mapSize = mapper.getMapSize();
301  if (mapSize == 0) return;
302 
303  auto* sortedDigits = new vector<const TOPRawDigit*>[mapSize];
304 
305  for (const auto& digit : digits) {
306  auto scrodID = digit.getScrodID();
307  const auto* feemap = mapper.getMap(scrodID);
308  if (!feemap) {
309  B2ERROR("TOPPacker: no front-end map available."
310  << LogVar("scrodID", scrodID));
311  continue;
312  }
313  sortedDigits[feemap->getIndex()].push_back(&digit);
314  }
315 
316  unsigned revo9count = 0;
317  unsigned phase = 0;
318  if (digits.getEntries() > 0) {
319  revo9count = digits[0]->getRevo9Counter();
320  phase = digits[0]->getPhase();
321  }
322 
323  for (const auto& copperID : mapper.getCopperIDs()) {
324  vector<int> Buffer[4];
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);
330 
331  unsigned head0 = (format << 16) | (0xA << 12) | (scrodID & 0x0FFF);
332  Buffer[finesse].push_back(head0);
333 
334  unsigned numWordsCore = sortedDigits[feemap->getIndex()].size() * 5 + 1;
335  unsigned head1 = ((phase & 0xF) << 12) | (numWordsCore & 0xFFF);
336  Buffer[finesse].push_back(head1);
337 
338  unsigned head2 = revo9count & 0xFFFF;
339  Buffer[finesse].push_back(head2);
340 
341  unsigned head3 = 0;
342  Buffer[finesse].push_back(head3);
343 
344  unsigned Nhits = 0;
345  for (const auto& digit : sortedDigits[feemap->getIndex()]) {
346  unsigned checkSum = 0; // IPv4 checksum
347  unsigned word0 =
348  (digit->getCarrierNumber() << 30) |
349  ((digit->getASICNumber() & 0x3) << 28) |
350  ((digit->getASICChannel() & 0x7) << 25) |
351  ((digit->getASICWindow() & 0x1FF) << 16) |
352  (0xB << 12) |
353  ((digit->getTFine() & 0xF) << 8);
354  checkSum += (word0 & 0xFFFF) + ((word0 >> 16) & 0xFFFF);
355  Buffer[finesse].push_back(word0);
356  unsigned word1 =
357  ((digit->getValuePeak() & 0x1FFF) << 16) |
358  (digit->getIntegral() & 0xFFFF);
359  checkSum += (word1 & 0xFFFF) + ((word1 >> 16) & 0xFFFF);
360  Buffer[finesse].push_back(word1);
361  unsigned word2 =
362  ((digit->getValueRise0() & 0x1FFF) << 16) |
363  (digit->getValueRise1() & 0x1FFF);
364  checkSum += (word2 & 0xFFFF) + ((word2 >> 16) & 0xFFFF);
365  Buffer[finesse].push_back(word2);
366  unsigned word3 =
367  ((digit->getValueFall0() & 0x1FFF) << 16) |
368  (digit->getValueFall1() & 0x1FFF);
369  checkSum += (word3 & 0xFFFF) + ((word3 >> 16) & 0xFFFF);
370  Buffer[finesse].push_back(word3);
371  unsigned word4 =
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);
378  }
379  word4 |= ((~checkSum) & 0xFFFF);
380  Buffer[finesse].push_back(word4);
381  Nhits++;
382  }
383  unsigned tail = (0x5 << 9) | (Nhits & 0x1FF);
384  Buffer[finesse].push_back(tail);
385  }
386 
387  RawCOPPERPackerInfo info;
388  info.exp_num = evtMetaData->getExperiment();
389  // run number : 14bits, subrun # : 8bits
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;
394  info.tt_ctime = 0;
395  info.tt_utime = 0;
396  info.b2l_ctime = 0;
397  info.hslb_crc16_error_bit = 0;
398  info.truncation_mask = 0;
399  info.type_of_data = 0;
400 
401  auto* raw = rawData.appendNew();
402  raw->PackDetectorBuf(Buffer[0].data(), Buffer[0].size(),
403  Buffer[1].data(), Buffer[1].size(),
404  Buffer[2].data(), Buffer[2].size(),
405  Buffer[3].data(), Buffer[3].size(),
406  info);
407  }
408  delete [] sortedDigits;
409  }
410 
412 } // end Belle2 namespace
413 
Base class for Modules.
Definition: Module.h:72
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:95
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.
Definition: Module.h:650
Abstract base class for different kinds of events.