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