9#include <pxd/modules/pxdUnpacking/PXDReadRawBonnDAQMatched.h>
10#include <boost/endian/arithmetic.hpp>
11#include <boost/crc.hpp>
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;
22using boost::crc_optimal;
23typedef crc_optimal<32, 0x04C11DB7, 0, 0, false, false> dhe_crc_32_type;
38 setDescription(
"Read a BonnDAQ form file, match to current event and stores it as RawPXD in Data Store");
41 addParam(
"RawPXDsName",
m_RawPXDsName,
"The name of the StoreArray of RawPXDs to be written", std::string(
""));
46 B2DEBUG(29,
"PXDReadRawBonnDAQMatchedModule: Constructor done.");
50PXDReadRawBonnDAQMatchedModule::~PXDReadRawBonnDAQMatchedModule()
60 B2INFO(
"Read BonnDAQ Data from " <<
m_filename);
62 B2ERROR(
"Could not open BonnDAQ Data: " <<
m_filename);
70 B2DEBUG(29,
"PXDReadRawBonnDAQMatchedModule: initialized.");
76 if (
fh) l = fread(data, 1, len,
fh);
77 if (l != len)
return 0;
83 unsigned int triggernr = 0xFFFFFFFF;
85 auto current_offset = ftell(
fh);
91 unsigned int get_size(
void) {
return (
unsigned int) size + (((
unsigned int)(header & 0x000F)) << 16);};
92 unsigned int get_size_group(
void) {
return (
unsigned int) size + (((
unsigned int)((header & 0x003F) ^ 0x0020)) << 16);};
93 unsigned int get_header12(
void) {
return (header & 0xFFF0);};
94 unsigned int get_header10(
void) {
return (header & 0xFFC0);};
95 unsigned int get_header8(
void) {
return (header & 0xFF00);};
106 if (br <= 0)
return br;
107 unsigned int chunk_size = 0;
108 if (evt->get_header8() == 0) {
109 B2DEBUG(29,
"Group Header $" << std::hex << evt->get_header10() <<
" Chunk size " << std::dec << evt->get_size());
110 chunk_size = evt->get_size_group();
112 B2DEBUG(29,
"Header $" << std::hex << evt->get_header12() <<
" Chunk size " << std::dec << evt->get_size());
113 chunk_size = evt->get_size();
115 if (chunk_size <= 1)
return 0;
116 br =
read_data(data + 4, chunk_size * 4 - 4);
117 if (br <= 0)
return br;
118 if (evt->get_header12() == 0xe230) {
119 B2DEBUG(29,
"File info " << std::hex << evt->get_header12() <<
" Events " << std::dec << data32[1]);
121 }
else if (evt->get_header12() == 0xe100) {
122 B2DEBUG(29,
"Info Event " << std::hex << evt->get_header12() <<
" RunNr $" << std::hex << data32[1]);
125 }
else if (evt->get_header10() == 0x0000) {
126 B2DEBUG(29,
"Run Event Group " << std::hex << evt->get_header10() <<
" Magic $" << std::hex << data32[1]);
128 }
else if (evt->get_header12() == 0xbb00) {
129 B2DEBUG(29,
"Run Event " << std::hex << evt->get_header12() <<
" Magic $" << std::hex << data32[1]);
131 }
else if (evt->get_header10() == 0x0080) {
132 int togo = chunk_size;
133 B2DEBUG(29,
"Data Event Group " << std::hex << evt->get_header10() <<
" TriggerNr $" << std::hex << data32[1]);
134 triggernr = data32[1];
139 B2DEBUG(29,
"TOGO: " << togo);
140 B2DEBUG(29,
" ............... " << std::hex << data32[0] <<
" TriggerNr $" << std::hex << data32[1]);
141 if (triggernr != data32[1]) B2ERROR(
"Trigger Nr does not match!");
142 B2DEBUG(29,
" ............... " << std::hex << data32[2]);
146 if ((data32[0] & 0xFFFF0000) == 0xCAFE0000) {
147 int frames = (data32[0] & 0x3FF);
148 B2DEBUG(29,
"Frames: " << frames);
150 bool nocrc = (data32[0] & 0x8000) != 0;
152 if ((data32[0] & 0x4000) == 0) B2FATAL(
"large data fields not supported");
158 std::vector <unsigned int> m_onsen_header;
161 std::vector <std::vector <unsigned char>> m_onsen_payload;
162 int offset = ((frames + 1) & ~1);
171 for (
int i = 0; i < frames; i++) {
176 std::vector <unsigned char> m_current_frame;
178 for (
int j = 0; j < (int)table16[i] * 2; j++) {
179 unsigned short w = data16[offset++];
180 m_current_frame.push_back((
unsigned char)(w >> 8));
181 m_current_frame.push_back((
unsigned char)(w));
185 dhe_crc_32_type current_crc;
186 current_crc.process_bytes(m_current_frame.data(), m_current_frame.size());
187 unsigned int w = current_crc.checksum();
188 m_current_frame.push_back((
unsigned char)(w >> 24));
189 m_current_frame.push_back((
unsigned char)(w >> 16));
190 m_current_frame.push_back((
unsigned char)(w >> 8));
191 m_current_frame.push_back((
unsigned char)(w));
194 m_onsen_header.push_back(m_current_frame.size());
195 m_onsen_payload.push_back(m_current_frame);
197 togo -= ((frames + 1) & ~1) / 2 + size;
198 data32 += ((frames + 1) & ~1) / 2 + size;
199 data16 += ((frames + 1) & ~1) + size * 2;
207 if (rettriggernr == triggernr)
m_rawPXD.appendNew(m_onsen_header, m_onsen_payload);
211 rettriggernr = triggernr;
214 current_offset = ftell(
fh);
219 B2ERROR(
"Undefine Header $" << std::hex << evt->get_header12());
225 rettriggernr = 0xFFFFFFFF;
233 B2ERROR(
"Unexpected close of bonndaq file.");
243 fseek(
fh, offset, SEEK_SET);
245 unsigned int tnr = 0;
254 }
while (tnr != triggernr);
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
void setDescription(const std::string &description)
Sets the description of the module.
void setReturnValue(int value)
Sets the return value for this module as integer.
void initialize() override final
Initialize.
std::map< unsigned int, off_t > m_event_offset
map event nr to offsets
int read_data(char *data, size_t len)
Read amount of data (len bytes) from file to ptr data.
std::string m_RawPXDsName
The name of the StoreArray RawPXDs to create.
void terminate() override final
Terminate.
void event() override final
Event.
off_t m_last_offset
last checked file offset
int readOneEvent(unsigned int &tnr)
Read event and store it in datastore if trigger nr matches.
PXDReadRawBonnDAQMatchedModule()
Constructor / Destructor.
std::string m_filename
File Name.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
Event Meta Data.
StoreArray< RawPXD > m_rawPXD
DHH Data.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
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.