Belle II Software development
PXDReadRawBonnDAQ.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#include <pxd/modules/pxdUnpacking/PXDReadRawBonnDAQ.h>
10#include <boost/endian/arithmetic.hpp>
11#include <boost/crc.hpp>
12
13using namespace std;
14using namespace Belle2;
15using namespace PXD;
16
17using ulittle16_t = boost::endian::little_uint16_t;
18using ulittle32_t = boost::endian::little_uint32_t;
19using ubig16_t = boost::endian::big_uint16_t;
20using ubig32_t = boost::endian::big_uint32_t;
21
22using boost::crc_optimal;
23typedef crc_optimal<32, 0x04C11DB7, 0, 0, false, false> dhe_crc_32_type;
24
25//-----------------------------------------------------------------
26// Register the Module
27//-----------------------------------------------------------------
28REG_MODULE(PXDReadRawBonnDAQ);
29
30//-----------------------------------------------------------------
31// Implementation
32//-----------------------------------------------------------------
33
35{
36 fh = 0;
37 //Set module properties
38 setDescription("Read a BonnDAQ file and stores it as RawPXD in Data Store");
39 //setPropertyFlags(c_Input | c_ParallelProcessingCertified); // not parallel processing!
40
41 addParam("FileName", m_filename, "file name");
42 addParam("SubRunNr", m_subRunNr, "sub-run number", 0u);
43 addParam("RunNr", m_runNr, "run number", 0u);
44 addParam("ExpNr", m_expNr, "exp number", 0u);
45 m_buffer = new int[MAXEVTSIZE];
46
47 B2DEBUG(29, "PXDReadRawBonnDAQModule: Constructor done.");
48}
49
50
52{
53 delete[] m_buffer;
54}
55
57{
58 // Open file
60 if (fh) {
61 B2INFO("Read BonnDAQ Data from " << m_filename);
62 } else {
63 B2ERROR("Could not open BonnDAQ Data: " << m_filename);
64 }
65
66 // Register EvtMetaData
68 // Register RawPXD
70
71 B2DEBUG(29, "PXDReadRawBonnDAQModule: initialized.");
72}
73
75{
76
77 if (!fh) {
78 B2ERROR("BonnDAQ Data file is not open ");
79 }
80
81 unsigned int triggernr = 0xFFFFFFFF;
82
83 struct EvtHeader {
84 ulittle16_t size;
85 ulittle16_t header;
86 unsigned int get_size(void) { return (unsigned int) size + (((unsigned int)(header & 0x000F)) << 16);};
87 unsigned int get_size_group(void) { return (unsigned int) size + (((unsigned int)((header & 0x003F) ^ 0x0020)) << 16);};
88 unsigned int get_header12(void) { return (header & 0xFFF0);};
89 unsigned int get_header10(void) { return (header & 0xFFC0);};
90 unsigned int get_header8(void) { return (header & 0xFF00);};
91 };
92
93 char* data = (char*)m_buffer;
94 struct EvtHeader* evt = (struct EvtHeader*)data;
95
96 while (1) {
97 ulittle32_t* data32 = (ulittle32_t*)data;
98 ulittle16_t* data16 = (ulittle16_t*)data;
99 // Read 8 bytes header (group)
100 int br = fh->read_data(data, 4);
101 if (br <= 0) return br;
102 unsigned int chunk_size = 0;
103 if (evt->get_header8() == 0) {
104 B2DEBUG(29, "Group Header $" << std::hex << evt->get_header10() << " Chunk size " << std::dec << evt->get_size());
105 chunk_size = evt->get_size_group();
106 } else {
107 B2DEBUG(29, "Header $" << std::hex << evt->get_header12() << " Chunk size " << std::dec << evt->get_size());
108 chunk_size = evt->get_size();
109 }
110 if (chunk_size <= 1) return 0;
111 br = fh->read_data(data + 4, chunk_size * 4 - 4);
112 if (br <= 0) return br;
113 if (evt->get_header12() == 0xe230) {
114 B2DEBUG(29, "File info " << std::hex << evt->get_header12() << " Events " << std::dec << data32[1]);
115 continue;
116 } else if (evt->get_header12() == 0xe100) {
117 B2DEBUG(29, "Info Event " << std::hex << evt->get_header12() << " RunNr $" << std::hex << data32[1]);
118 if (m_runNr == 0) m_runNr = data32[1]; // we assume it will not change within one file
119 continue;
120 } else if (evt->get_header10() == 0x0000) { // war 0x0020
121 B2DEBUG(29, "Run Event Group " << std::hex << evt->get_header10() << " Magic $" << std::hex << data32[1]);
122 continue;
123 } else if (evt->get_header12() == 0xbb00) {
124 B2DEBUG(29, "Run Event " << std::hex << evt->get_header12() << " Magic $" << std::hex << data32[1]);
125 continue;
126 } else if (evt->get_header10() == 0x0080) { // war 0x00A0
127 int togo = chunk_size;
128 B2DEBUG(29, "Data Event Group " << std::hex << evt->get_header10() << " TriggerNr $" << std::hex << data32[1]);
129 triggernr = data32[1];
130 togo -= 2;
131 data32 += 2;
132 data16 += 4;
133 while (togo > 2) {
134 B2DEBUG(29, "TOGO: " << togo);
135 B2DEBUG(29, " ............... " << std::hex << data32[0] << " TriggerNr $" << std::hex << data32[1]);
136 if (triggernr != data32[1]) B2ERROR("Trigger Nr does not match!");
137 B2DEBUG(29, " ............... " << std::hex << data32[2]);
138 togo -= 2;
139 data32 += 2;
140 data16 += 4;
141 if ((data32[0] & 0xFFFF0000) == 0xCAFE0000) {
142 int frames = (data32[0] & 0x3FF);
143 B2DEBUG(29, "Frames: " << frames);
144 int size = 0;
145 bool nocrc = (data32[0] & 0x8000) != 0;
146
147 if ((data32[0] & 0x4000) == 0) B2FATAL("large data fields not supported");
148
149 togo--;
150 data32++;
151 data16 += 2;
153 std::vector <unsigned int> m_onsen_header;
154
156 std::vector <std::vector <unsigned char>> m_onsen_payload;
157 int offset = ((frames + 1) & ~1);
158
159 ulittle16_t* table16 = data16;
160 if (!nocrc) {
161 togo--; // jump over TOC CRC
162 data32++;
163 data16 += 2;
164 }
165
166 for (int i = 0; i < frames; i++) {
167 //B2INFO(".... " << i << ": " << table16[i]); -> do we need this?
168 size += table16[i];
169
171 std::vector <unsigned char> m_current_frame;
172
173 for (int j = 0; j < (int)table16[i] * 2; j++) {
174 unsigned short w = data16[offset++];
175 m_current_frame.push_back((unsigned char)(w >> 8));
176 m_current_frame.push_back((unsigned char)(w));
177 }
178
179 if (nocrc) { // recalculate
180 dhe_crc_32_type current_crc;
181 current_crc.process_bytes(m_current_frame.data(), m_current_frame.size());
182 unsigned int w = current_crc.checksum();
183 m_current_frame.push_back((unsigned char)(w >> 24));
184 m_current_frame.push_back((unsigned char)(w >> 16));
185 m_current_frame.push_back((unsigned char)(w >> 8));
186 m_current_frame.push_back((unsigned char)(w));
187 }
188
189 m_onsen_header.push_back(m_current_frame.size());
190 m_onsen_payload.push_back(m_current_frame);
191 }
192 togo -= ((frames + 1) & ~1) / 2 + size;
193 data32 += ((frames + 1) & ~1) / 2 + size;
194 data16 += ((frames + 1) & ~1) + size * 2;
195
196 if (nocrc) {
197 togo--;
198 data32++;
199 data16 += 2;
200 }
201
202 m_rawPXD.appendNew(m_onsen_header, m_onsen_payload);
203 }
204 }// while ...
205
206 // Update EventMetaData
207 B2INFO("Set Meta: Exp " << m_expNr << " Run " << m_runNr << " TrgNr " << triggernr);
208 m_eventMetaDataPtr.create();
209 m_eventMetaDataPtr->setExperiment(m_expNr);
211 m_eventMetaDataPtr->setEvent(triggernr);
212 // we cannot recover time tag here. this would need further decoding from DHH header
213 // m_eventMetaDataPtr->setTime((unsigned long long int)((time_tag_hi<<1) +(time_tag_mid &0x8000?1:0))*1000000000+(int)std::round(tt / 0.127216));
214
215 return 1;
216 } else {
217 B2ERROR("Undefine Header $" << std::hex << evt->get_header12());
218 continue;
219 }
220 continue;
221
222 }
223 return 0;
224}
225
227{
228 if (fh == 0) {
229 B2ERROR("Unexpected close of dump file.");
230 terminate();
231 return;
232 }
233
234 // Get a record from file
235 int stat;
236 do {
237 stat = readOneEvent();
238 if (stat <= 0) {
240 terminate();
241 return;
242 };
243 } while (stat == 0);
244
245 return;
246}
247
249{
250 if (fh) {
251 delete (fh);
252 fh = 0;
253 }
254}
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
A class to manage I/O for a chain of blocked files.
int read_data(char *data, size_t len)
Read a record from a file.
void initialize() override final
Initialize.
unsigned int m_subRunNr
set by Param
void terminate() override final
Terminate.
void event() override final
Event.
~PXDReadRawBonnDAQModule() override final
Destructor.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
Event Meta Data.
PXDLocalDAQFile * fh
File handle.
StoreArray< RawPXD > m_rawPXD
DHH Data.
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
boost::endian::little_uint16_t ulittle16_t
define alias ulittle16_t
boost::endian::little_uint32_t ulittle32_t
define alias ulittle32_t
Abstract base class for different kinds of events.
STL namespace.
Header structure of streamed object list.
Definition: EvtMessage.h:28