Belle II Software  release-08-01-10
ARICHPackerModule.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 <arich/modules/arichPacker/ARICHPackerModule.h>
11 
12 // framework - DataStore
13 #include <framework/datastore/StoreArray.h>
14 #include <framework/datastore/StoreObjPtr.h>
15 
16 // framework aux
17 #include <framework/logging/Logger.h>
18 
19 // Dataobject classes
20 #include <arich/dataobjects/ARICHDigit.h>
21 #include <rawdata/dataobjects/RawARICH.h>
22 #include <framework/dataobjects/EventMetaData.h>
23 #include <bitset>
24 
25 namespace Belle2 {
31 #define ARICH_BUFFER_NWORDS 252 // arich number of words (ints) in buffer; 3 + 33 + 6 * 36; 3 merger header words + 5.5 FEB header words / FEB + 36 data words per / FEB
32  //-----------------------------------------------------------------
34  //-----------------------------------------------------------------
35 
36  REG_MODULE(ARICHPacker);
37 
38  //-----------------------------------------------------------------
39  // Implementation
40  //-----------------------------------------------------------------
41 
43  m_nonSuppressed(0), m_bitMask(0), m_debug(0)
44 
45  {
46  // set module description (e.g. insert text)
47  setDescription("Raw data packer for ARICH");
49  addParam("nonSuppressed", m_nonSuppressed, "Pack in non-suppressed format (store all channels)", unsigned(0));
50  addParam("version", m_version, "dataformat version", unsigned(6));
51  addParam("bitMask", m_bitMask, "hit bit mask (4 bits/channel)", (unsigned)0xF);
52  addParam("debug", m_debug, "print packed bitmap", 0);
53  addParam("inputDigitsName", m_inputDigitsName, "name of ARICHDigit store array", std::string(""));
54  addParam("outputRawDataName", m_outputRawDataName, "name of RawARICH store array", std::string(""));
55 
56  }
57 
59  {
60  }
61 
63  {
64 
66  digits.isRequired();
67 
69  rawData.registerInDataStore();
70  }
71 
73  {
74 
75  StoreObjPtr<EventMetaData> evtMetaData;
78 
79  int nModules = N_MERGERS * N_FEB2MERGER;
80 
81  std::vector<const ARICHDigit*>* sortedDigits = new std::vector<const ARICHDigit*>[nModules];
82  for (const auto& digit : digits) {
83  int moduleID = digit.getModuleID();
84  unsigned mergerID = m_mergerMap->getMergerID(moduleID);
85  if (!mergerID) { B2WARNING("No module2merger mapping for module ID: " << moduleID << "; Digit will not be packed!"); continue;}
86  if (!m_copperMap->getCopperID(mergerID)) { B2WARNING("No merger2copper mapping for merger ID: " << mergerID << "; Digit will not be packed!"); continue;}
87  sortedDigits[moduleID - 1].push_back(&digit);
88  }
89 
90  int buffer[4][ARICH_BUFFER_NWORDS];
91 
92  for (const auto& copperID : m_copperMap->getCopperIDs()) {
93 
94  int bufferSize[4] = {0, 0, 0, 0};
95  for (int finesse = 0; finesse < 4; finesse++) {
96 
97  unsigned ibyte = 0;
98 
99  for (int j = 0; j < ARICH_BUFFER_NWORDS; j++) {
100  buffer[finesse][j] = 0;
101  }
102 
103  auto* buf = buffer[finesse];
104 
105  // get corresponding merger ID
106  unsigned mergerID = m_copperMap->getMergerID(copperID, finesse);
107  unsigned mergerSN = m_mergerMap->getMergerSN(mergerID);
108  if (!mergerID) continue;
109 
110  ARICHRawHeader mergerHead;
111  unsigned dataFormat = m_nonSuppressed + 1; // production data -> TODO: use enum
112  mergerHead.type = dataFormat;
113  mergerHead.version = m_version;
114  mergerHead.mergerID = mergerSN;
115  mergerHead.FEBSlot = 0;
116  mergerHead.trigger = evtMetaData->getEvent();
117  // mergerHead.length dont forget
118 
119  ibyte += ARICHRAW_HEADER_SIZE;
120 
121  int nboards = N_FEB2MERGER;
122 
123  for (int k = 0; k < nboards; k++) {
124 
125  int moduleID = m_mergerMap->getModuleID(mergerID, k + 1);
126  if (moduleID <= 0) continue;
127 
128  // FEB header
129  ARICHRawHeader FEBHead;
130  FEBHead.type = dataFormat;
131  FEBHead.version = m_version;
132  FEBHead.mergerID = mergerSN;
133  FEBHead.FEBSlot = k; // board slots go from 0-5 for now, if firmware is updated to 1-6 add +1 !!
134  FEBHead.trigger = evtMetaData->getEvent();
135 
136  if (m_nonSuppressed) {
137  // data length in bytes
138  FEBHead.length = 144 + ARICHFEB_HEADER_SIZE; // 144ch * 1 byte
139  writeHeader(buf, ibyte, FEBHead);
140  ibyte += ARICHFEB_HEADER_SIZE; // leave slot for FEB header (FEB header to be implemented!)
141 
142  // write data
143  for (const auto& digit : sortedDigits[moduleID - 1]) {
144  unsigned chn = digit->getChannelID();
145  //std::cout << "pack: mod: " << boardID << " ch " << chn<< std::endl;
146  unsigned shift = 143 - chn;
147  unsigned bitmap = (unsigned)digit->getBitmap();
148  buf[(ibyte + shift) / 4] += (bitmap << (3 - (ibyte + shift) % 4) * 8);
149  }
150  ibyte += 144;
151  } else {
152  FEBHead.length = ARICHFEB_HEADER_SIZE + sortedDigits[moduleID - 1].size() * 2; // each hit is 2 bytes! channel + bitmap
153  writeHeader(buf, ibyte, FEBHead);
154  ibyte += ARICHFEB_HEADER_SIZE; // leave slot for FEB header (FEB header to be implemented!)
155 
156  for (const auto& digit : sortedDigits[moduleID - 1]) {
157  unsigned chn = digit->getChannelID();
158  //std::cout << "pack: mod: " << boardID << " ch " << chn<< std::endl;
159  unsigned shift = (3 - ibyte % 4) * 8;
160  buf[ibyte / 4] += (chn << shift);
161  ibyte++;
162  shift = (3 - ibyte % 4) * 8;
163  unsigned bitmap = (unsigned)digit->getBitmap();
164  buf[ibyte / 4] += (bitmap << shift);
165  ibyte++;
166  }
167  }
168  }
169 
170  unsigned merg = 0;
171  mergerHead.length = ibyte - ARICHRAW_HEADER_SIZE;
172  writeHeader(buf, merg, mergerHead);
173 
174  bufferSize[finesse] = ceil(ibyte / 4.);
175 
176  if (m_debug) {
177  std::cout << "Pack finesse: " << finesse << std::endl;
178  for (int i = 0; i < bufferSize[finesse]; i++) {
179  std::cout << i << "-th word bitset " << std::bitset<32>(buf[i]) << std::endl;
180  }
181  }
182  }
183 
184  RawCOPPERPackerInfo info;
185  info.exp_num = evtMetaData->getExperiment();
186  info.run_subrun_num = (evtMetaData->getRun() << 8) +
187  (evtMetaData->getSubrun() & 0xFF); // run number : 14bits, subrun # : 8bits
188  info.eve_num = evtMetaData->getEvent();
189  info.node_id = ARICH_ID + copperID;
190  info.tt_ctime = 0;
191  info.tt_utime = 0;
192  info.b2l_ctime = 0;
193  info.hslb_crc16_error_bit = 0;
194  info.truncation_mask = 0;
195  info.type_of_data = 0;
196 
197  auto* raw = rawData.appendNew();
198  raw->PackDetectorBuf(buffer[0], bufferSize[0],
199  buffer[1], bufferSize[1],
200  buffer[2], bufferSize[2],
201  buffer[3], bufferSize[3],
202  info);
203 
204  }
205 
206  delete [] sortedDigits;
207 
208  }
209 
210  void ARICHPackerModule::writeHeader(int* buffer, unsigned& ibyte, const ARICHRawHeader& head)
211  {
212 
213  unsigned char line1[4];
214  int shift;
215 
216  line1[3] = head.type;
217  line1[2] = head.version;
218  line1[1] = head.mergerID;
219  line1[0] = head.FEBSlot;
220 
221  for (int i = 0; i < 4; i++) {
222  shift = (3 - ibyte % 4) * 8;
223  buffer[ibyte / 4] |= line1[3 - i] << shift;
224  ibyte++;
225  }
226 
227  auto len = reinterpret_cast<const unsigned char*>(&head.length);
228 
229  for (int i = 0; i < 4; i++) {
230  shift = (3 - ibyte % 4) * 8;
231  buffer[ibyte / 4] |= len[3 - i] << shift;
232  ibyte++;
233  }
234 
235  // trigger number
236  auto trg = reinterpret_cast<const unsigned char*>(&head.trigger);
237  for (int i = 0; i < 4; i++) {
238  shift = (3 - ibyte % 4) * 8;
239  buffer[ibyte / 4] |= trg[3 - i] << shift;
240  ibyte++;
241  }
242 
243  }
244 
246 } // end Belle2 namespace
247 
DBObjPtr< ARICHMergerMapping > m_mergerMap
mapping of modules to mergers
unsigned m_nonSuppressed
type of data (1 nonsuppressed, 0 suppressed)
unsigned m_version
dataformat version
std::string m_inputDigitsName
name of ARICHDigit store array
unsigned m_bitMask
bitmask for hit detection (4bit/hit)
std::string m_outputRawDataName
name of RawARICH store array
DBObjPtr< ARICHCopperMapping > m_copperMap
mapping of mergers to coppers
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 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
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
virtual ~ARICHPackerModule()
Destructor.
REG_MODULE(arichBtest)
Register the Module.
void writeHeader(int *buffer, unsigned &ibyte, const ARICHRawHeader &head)
TODO!
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
Abstract base class for different kinds of events.