11 #include <pxd/modules/pxdUnpacking/PXDReadRawBonnDAQMatched.h>
12 #include <boost/spirit/home/support/detail/endian.hpp>
13 #include <boost/crc.hpp>
19 using namespace boost::spirit::endian;
21 using boost::crc_optimal;
22 typedef crc_optimal<32, 0x04C11DB7, 0, 0, false, false> dhe_crc_32_type;
37 setDescription(
"Read a BonnDAQ form file, match to current event and stores it as RawPXD in Data Store");
40 addParam(
"RawPXDsName", m_RawPXDsName,
"The name of the StoreArray of RawPXDs to be written", std::string(
""));
42 addParam(
"FileName", m_filename,
"file name");
43 m_buffer =
new int[MAXEVTSIZE];
45 B2DEBUG(29,
"PXDReadRawBonnDAQMatchedModule: Constructor done.");
49 PXDReadRawBonnDAQMatchedModule::~PXDReadRawBonnDAQMatchedModule()
54 void PXDReadRawBonnDAQMatchedModule::initialize()
57 fh = fopen(m_filename.c_str(),
"rb");
59 B2INFO(
"Read BonnDAQ Data from " << m_filename);
61 B2ERROR(
"Could not open BonnDAQ Data: " << m_filename);
65 m_eventMetaDataPtr.isRequired();
67 m_rawPXD.registerInDataStore(m_RawPXDsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
69 B2DEBUG(29,
"PXDReadRawBonnDAQMatchedModule: initialized.");
72 int PXDReadRawBonnDAQMatchedModule::read_data(
char* data,
size_t len)
75 if (fh) l = fread(data, 1, len, fh);
76 if (l != len)
return 0;
80 int PXDReadRawBonnDAQMatchedModule::readOneEvent(
unsigned int& rettriggernr)
82 unsigned int triggernr = 0xFFFFFFFF;
84 auto current_offset = ftell(fh);
85 if (current_offset > m_last_offset) m_last_offset = current_offset;
90 unsigned int get_size(
void) {
return (
unsigned int) size + (((
unsigned int)(header & 0x000F)) << 16);};
91 unsigned int get_size_group(
void) {
return (
unsigned int) size + (((
unsigned int)((header & 0x003F) ^ 0x0020)) << 16);};
92 unsigned int get_header12(
void) {
return (header & 0xFFF0);};
93 unsigned int get_header10(
void) {
return (header & 0xFFC0);};
94 unsigned int get_header8(
void) {
return (header & 0xFF00);};
97 char* data = (
char*)m_buffer;
101 ulittle32_t* data32 = (ulittle32_t*)data;
102 ulittle16_t* data16 = (ulittle16_t*)data;
104 int br = read_data(data, 4);
105 if (br <= 0)
return br;
106 unsigned int chunk_size = 0;
107 if (evt->get_header8() == 0) {
108 B2DEBUG(29,
"Group Header $" << std::hex << evt->get_header10() <<
" Chunk size " << std::dec << evt->get_size());
109 chunk_size = evt->get_size_group();
111 B2DEBUG(29,
"Header $" << std::hex << evt->get_header12() <<
" Chunk size " << std::dec << evt->get_size());
112 chunk_size = evt->get_size();
114 if (chunk_size <= 1)
return 0;
115 br = read_data(data + 4, chunk_size * 4 - 4);
116 if (br <= 0)
return br;
117 if (evt->get_header12() == 0xe230) {
118 B2DEBUG(29,
"File info " << std::hex << evt->get_header12() <<
" Events " << std::dec << data32[1]);
120 }
else if (evt->get_header12() == 0xe100) {
121 B2DEBUG(29,
"Info Event " << std::hex << evt->get_header12() <<
" RunNr $" << std::hex << data32[1]);
124 }
else if (evt->get_header10() == 0x0000) {
125 B2DEBUG(29,
"Run Event Group " << std::hex << evt->get_header10() <<
" Magic $" << std::hex << data32[1]);
127 }
else if (evt->get_header12() == 0xbb00) {
128 B2DEBUG(29,
"Run Event " << std::hex << evt->get_header12() <<
" Magic $" << std::hex << data32[1]);
130 }
else if (evt->get_header10() == 0x0080) {
131 int togo = chunk_size;
132 B2DEBUG(29,
"Data Event Group " << std::hex << evt->get_header10() <<
" TriggerNr $" << std::hex << data32[1]);
133 triggernr = data32[1];
138 B2DEBUG(29,
"TOGO: " << togo);
139 B2DEBUG(29,
" ............... " << std::hex << data32[0] <<
" TriggerNr $" << std::hex << data32[1]);
140 if (triggernr != data32[1]) B2ERROR(
"Trigger Nr does not match!");
141 B2DEBUG(29,
" ............... " << std::hex << data32[2]);
145 if ((data32[0] & 0xFFFF0000) == 0xCAFE0000) {
146 int frames = (data32[0] & 0x3FF);
147 B2DEBUG(29,
"Frames: " << frames);
149 bool nocrc = (data32[0] & 0x8000) != 0;
151 if ((data32[0] & 0x4000) == 0) B2FATAL(
"large data fields not supported");
157 std::vector <unsigned int> m_onsen_header;
160 std::vector <std::vector <unsigned char>> m_onsen_payload;
161 int offset = ((frames + 1) & ~1);
163 ulittle16_t* table16 = data16;
170 for (
int i = 0; i < frames; i++) {
175 std::vector <unsigned char> m_current_frame;
177 for (
int j = 0; j < (int)table16[i] * 2; j++) {
178 unsigned short w = data16[offset++];
179 m_current_frame.push_back((
unsigned char)(w >> 8));
180 m_current_frame.push_back((
unsigned char)(w));
184 dhe_crc_32_type current_crc;
185 current_crc.process_bytes(m_current_frame.data(), m_current_frame.size());
186 unsigned int w = current_crc.checksum();
187 m_current_frame.push_back((
unsigned char)(w >> 24));
188 m_current_frame.push_back((
unsigned char)(w >> 16));
189 m_current_frame.push_back((
unsigned char)(w >> 8));
190 m_current_frame.push_back((
unsigned char)(w));
193 m_onsen_header.push_back(m_current_frame.size());
194 m_onsen_payload.push_back(m_current_frame);
196 togo -= ((frames + 1) & ~1) / 2 + size;
197 data32 += ((frames + 1) & ~1) / 2 + size;
198 data16 += ((frames + 1) & ~1) + size * 2;
206 if (rettriggernr == triggernr) m_rawPXD.appendNew(m_onsen_header, m_onsen_payload);
210 rettriggernr = triggernr;
212 m_event_offset[triggernr] = current_offset;
213 current_offset = ftell(fh);
214 if (current_offset > m_last_offset) m_last_offset = current_offset;
218 B2ERROR(
"Undefine Header $" << std::hex << evt->get_header12());
224 rettriggernr = 0xFFFFFFFF;
229 void PXDReadRawBonnDAQMatchedModule::event()
232 B2ERROR(
"Unexpected close of bonndaq file.");
237 auto triggernr = m_eventMetaDataPtr->getEvent();
240 auto offset = m_event_offset[triggernr];
241 if (offset == 0) offset = m_last_offset;
242 fseek(fh, offset, SEEK_SET);
244 auto tnr = triggernr;
248 int stat = readOneEvent(tnr);
253 }
while (tnr != triggernr);
256 setReturnValue(tnr == triggernr);
261 void PXDReadRawBonnDAQMatchedModule::terminate()