10 #include <pxd/modules/pxdUnpacking/PXDReadRawBonnDAQ.h>
11 #include <boost/spirit/home/support/detail/endian.hpp>
12 #include <boost/crc.hpp>
18 using namespace boost::spirit::endian;
20 using boost::crc_optimal;
21 typedef crc_optimal<32, 0x04C11DB7, 0, 0, false, false> dhe_crc_32_type;
36 setDescription(
"Read a BonnDAQ file and stores it as RawPXD in Data Store");
39 addParam(
"FileName", m_filename,
"file name");
40 addParam(
"SubRunNr", m_subRunNr,
"sub-run number", 0u);
41 addParam(
"RunNr", m_runNr,
"run number", 0u);
42 addParam(
"ExpNr", m_expNr,
"exp number", 0u);
43 m_buffer =
new int[MAXEVTSIZE];
45 B2DEBUG(29,
"PXDReadRawBonnDAQModule: Constructor done.");
49 PXDReadRawBonnDAQModule::~PXDReadRawBonnDAQModule()
54 void PXDReadRawBonnDAQModule::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.registerInDataStore(DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
67 m_rawPXD.registerInDataStore(DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
69 B2DEBUG(29,
"PXDReadRawBonnDAQModule: initialized.");
72 int PXDReadRawBonnDAQModule::read_data(
char* data,
size_t len)
75 if (fh) l = fread(data, 1, len, fh);
76 if (l != len)
return 0;
80 int PXDReadRawBonnDAQModule::readOneEvent()
82 unsigned int triggernr = 0xFFFFFFFF;
87 unsigned int get_size(
void) {
return (
unsigned int) size + (((
unsigned int)(header & 0x000F)) << 16);};
88 unsigned int get_size_group(
void) {
return (
unsigned int) size + (((
unsigned int)((header & 0x003F) ^ 0x0020)) << 16);};
89 unsigned int get_header12(
void) {
return (header & 0xFFF0);};
90 unsigned int get_header10(
void) {
return (header & 0xFFC0);};
91 unsigned int get_header8(
void) {
return (header & 0xFF00);};
94 char* data = (
char*)m_buffer;
98 ulittle32_t* data32 = (ulittle32_t*)data;
99 ulittle16_t* data16 = (ulittle16_t*)data;
101 int br = read_data(data, 4);
102 if (br <= 0)
return br;
103 unsigned int chunk_size = 0;
104 if (evt->get_header8() == 0) {
105 B2DEBUG(29,
"Group Header $" << std::hex << evt->get_header10() <<
" Chunk size " << std::dec << evt->get_size());
106 chunk_size = evt->get_size_group();
108 B2DEBUG(29,
"Header $" << std::hex << evt->get_header12() <<
" Chunk size " << std::dec << evt->get_size());
109 chunk_size = evt->get_size();
111 if (chunk_size <= 1)
return 0;
112 br = read_data(data + 4, chunk_size * 4 - 4);
113 if (br <= 0)
return br;
114 if (evt->get_header12() == 0xe230) {
115 B2DEBUG(29,
"File info " << std::hex << evt->get_header12() <<
" Events " << std::dec << data32[1]);
117 }
else if (evt->get_header12() == 0xe100) {
118 B2DEBUG(29,
"Info Event " << std::hex << evt->get_header12() <<
" RunNr $" << std::hex << data32[1]);
119 if (m_runNr == 0) m_runNr = data32[1];
121 }
else if (evt->get_header10() == 0x0000) {
122 B2DEBUG(29,
"Run Event Group " << std::hex << evt->get_header10() <<
" Magic $" << std::hex << data32[1]);
124 }
else if (evt->get_header12() == 0xbb00) {
125 B2DEBUG(29,
"Run Event " << std::hex << evt->get_header12() <<
" Magic $" << std::hex << data32[1]);
127 }
else if (evt->get_header10() == 0x0080) {
128 int togo = chunk_size;
129 B2DEBUG(29,
"Data Event Group " << std::hex << evt->get_header10() <<
" TriggerNr $" << std::hex << data32[1]);
130 triggernr = data32[1];
135 B2DEBUG(29,
"TOGO: " << togo);
136 B2DEBUG(29,
" ............... " << std::hex << data32[0] <<
" TriggerNr $" << std::hex << data32[1]);
137 if (triggernr != data32[1]) B2ERROR(
"Trigger Nr does not match!");
138 B2DEBUG(29,
" ............... " << std::hex << data32[2]);
142 if ((data32[0] & 0xFFFF0000) == 0xCAFE0000) {
143 int frames = (data32[0] & 0x3FF);
144 B2DEBUG(29,
"Frames: " << frames);
146 bool nocrc = (data32[0] & 0x8000) != 0;
148 if ((data32[0] & 0x4000) == 0) B2FATAL(
"large data fields not supported");
154 std::vector <unsigned int> m_onsen_header;
157 std::vector <std::vector <unsigned char>> m_onsen_payload;
158 int offset = ((frames + 1) & ~1);
160 ulittle16_t* table16 = data16;
167 for (
int i = 0; i < frames; i++) {
168 B2INFO(
".... " << i <<
": " << table16[i]);
172 std::vector <unsigned char> m_current_frame;
174 for (
int j = 0; j < (int)table16[i] * 2; j++) {
175 unsigned short w = data16[offset++];
176 m_current_frame.push_back((
unsigned char)(w >> 8));
177 m_current_frame.push_back((
unsigned char)(w));
181 dhe_crc_32_type current_crc;
182 current_crc.process_bytes(m_current_frame.data(), m_current_frame.size());
183 unsigned int w = current_crc.checksum();
184 m_current_frame.push_back((
unsigned char)(w >> 24));
185 m_current_frame.push_back((
unsigned char)(w >> 16));
186 m_current_frame.push_back((
unsigned char)(w >> 8));
187 m_current_frame.push_back((
unsigned char)(w));
190 m_onsen_header.push_back(m_current_frame.size());
191 m_onsen_payload.push_back(m_current_frame);
193 togo -= ((frames + 1) & ~1) / 2 + size;
194 data32 += ((frames + 1) & ~1) / 2 + size;
195 data16 += ((frames + 1) & ~1) + size * 2;
203 m_rawPXD.appendNew(m_onsen_header, m_onsen_payload);
208 B2INFO(
"Set Meta: Exp " << m_expNr <<
" Run " << m_runNr <<
" TrgNr " << triggernr);
209 m_eventMetaDataPtr.create();
210 m_eventMetaDataPtr->setExperiment(m_expNr);
211 m_eventMetaDataPtr->setRun(m_runNr);
212 m_eventMetaDataPtr->setEvent(triggernr);
218 B2ERROR(
"Undefine Header $" << std::hex << evt->get_header12());
227 void PXDReadRawBonnDAQModule::event()
230 B2ERROR(
"Unexpected close of dump file.");
238 stat = readOneEvent();
249 void PXDReadRawBonnDAQModule::terminate()