Belle II Software  release-08-01-10
PXDReadRawONSEN.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/PXDReadRawONSEN.h>
10 #include <pxd/unpacking/PXDRawDataDefinitions.h>
11 
12 #include <framework/datastore/StoreArray.h>
13 
14 #include <boost/endian/arithmetic.hpp>
15 
16 using namespace std;
17 using namespace Belle2;
18 using namespace PXD;
19 
20 using ulittle16_t = boost::endian::little_uint16_t;
21 using ulittle32_t = boost::endian::little_uint32_t;
22 using ubig16_t = boost::endian::big_uint16_t;
23 using ubig32_t = boost::endian::big_uint32_t;
24 
25 //-----------------------------------------------------------------
26 // Register the Module
27 //-----------------------------------------------------------------
28 REG_MODULE(PXDReadRawONSEN);
29 
30 //-----------------------------------------------------------------
31 // Implementation
32 //-----------------------------------------------------------------
33 
34 PXDReadRawONSENModule::PXDReadRawONSENModule() : Module()
35 {
36  fh = 0;
37  m_msghandler = 0;
38  //Set module properties
39  setDescription("Read a Raw PXD-Data Dump from ONSEN (or a simulator) and stores it as RawPXD in Data Store");
40  //setPropertyFlags(c_Input | c_ParallelProcessingCertified);
41  //setPropertyFlags(c_Input);
42 
43  addParam("FileName", m_filename, "file name");
44  addParam("SetEvtMeta", m_setEvtMeta, "Set Event MEta Info from DHE", true);
45 
46  m_nread = 0;
48  m_buffer = new int[MAXEVTSIZE];
49 
50  B2DEBUG(29, "PXDReadRawONSENModule: Constructor done.");
51 }
52 
53 
55 {
56  delete[] m_buffer;
57 }
58 
60 {
61  // Open receiver sockets
62 // m_recv = new EvtSocketSend(m_host, m_port);
63  fh = fopen(m_filename.c_str(), "rb");
64  if (fh) {
65  B2INFO("Read Raw ONSEN Data from " << m_filename);
66  } else {
67  B2ERROR("Could not open Raw ONSEN Data: " << m_filename);
68  }
69 
70  // Open message handler
72 
73  // Initialize EvtMetaData
74  m_eventMetaDataPtr.registerInDataStore();
75 
76  // Initialize Array of RawCOPPER
77  StoreArray<RawPXD> storeRawPIDs;
78  storeRawPIDs.registerInDataStore();
79 
80  B2DEBUG(29, "PXDReadRawONSENModule: initialized.");
81 }
82 
83 int PXDReadRawONSENModule::read_data(char* data, size_t len)
84 {
85  size_t l = 0;
86  if (fh) l = fread(data, 1, len, fh);
87  if (l != len) return 0;
88  return l;
89 }
90 
92 {
93  char* data = (char*)m_buffer;
94  int len = MAXEVTSIZE * sizeof(int);
95 
96 #define MAX_PXD_FRAMES 256
97  const int headerlen = 8;
98  ubig32_t* pxdheader = (ubig32_t*) data;
99  ubig32_t* pxdheadertable = (ubig32_t*) &data[headerlen];
100  int framenr = 0, tablelen = 0, datalen = 0;
101  int br = read_data(data, headerlen);
102  if (br <= 0) return br;
103  if (pxdheader[0] != 0xCAFEBABEu) {
104  B2FATAL(Form("pxdheader wrong : Magic %X , Frames %X \n", (unsigned int) pxdheader[0], (unsigned int) pxdheader[1]));
105  exit(0);
106  }
107  framenr = pxdheader[1];
108  if (framenr > MAX_PXD_FRAMES) {
109  B2FATAL(Form("MAX_PXD_FRAMES too small : %d(%d) \n", framenr, MAX_PXD_FRAMES));
110  exit(0);
111  }
112  tablelen = 4 * framenr;
113  br = read_data((char*)&data[headerlen], tablelen);
114  if (br <= 0) return br;
115  for (int i = 0; i < framenr; i++) {
116  datalen += (pxdheadertable[i] + 3) & 0xFFFFFFFC;
117  }
118 
119  if (datalen + headerlen + tablelen > len) {
120  B2FATAL(Form("buffer too small : %d %d %d(%d) \n", headerlen, tablelen, datalen, len));
121  exit(0);
122  }
123  br = read_data(data + headerlen + tablelen, datalen);
124  if (br <= 0) return br;
125  return (headerlen + tablelen + br);
126 }
127 
129 {
130  if (fh == 0) {
131  B2ERROR("Unexpected close of dump file.");
132  terminate();
133  return;
134  }
135  // DataStore interface
136  StoreArray<RawPXD> rawpxdary;
137 
138  // Get a record from socket
139  int stat;
140  do {
141  stat = readOneEvent();
142  if (stat <= 0) {
144  terminate();
145  return;
146  };
147  } while (stat == 0);
148 
149  // Fill RawPXD in DataStore, stat=lenght_in_Bytes
150  rawpxdary.appendNew(m_buffer, stat);
151 
152 
153  if (m_setEvtMeta) {
154  // Update EventMetaData
155  m_eventMetaDataPtr.create();
156  for (auto& it : rawpxdary) {
157  if (getTrigNr(it)) break; // only first (valid) one
158  }
159  }
160 
161  m_nread++;
162 
163  return;
164 }
165 
167 {
168  if (fh) fclose(fh);
169  fh = 0;
170 }
171 
172 
174 {
175  int Frames_in_event;
176  int fullsize;
177  int datafullsize;
178 
179  if (px.size() <= 0 || px.size() > 16 * 1024 * 1024) {
180  B2ERROR("PXD Trigger Shifter --> invalid packet size (32bit words) " << hex << px.size());
181  return false;
182  }
183  std::vector<unsigned int> data(px.size());
184  fullsize = px.size() * 4;
185  std::copy_n(px.data(), px.size(), data.begin());
186 
187 
188  if (fullsize < 8) {
189  B2ERROR("Data is to small to hold a valid Header! Will not unpack anything. Size:" << fullsize);
190  return false;
191  }
192 
193  if (data[0] != 0xCAFEBABE && data[0] != 0xBEBAFECA) {
194  B2ERROR("Magic invalid: Will not unpack anything. Header corrupted! " << hex << data[0]);
195  return false;
196  }
197 
198  Frames_in_event = ((ubig32_t*)data.data())[1];
199  if (Frames_in_event < 1 || Frames_in_event > 250) {
200  B2ERROR("Number of Frames invalid: Will not unpack anything. Header corrupted! Frames in event: " << Frames_in_event);
201  return false;
202  }
203 
204  unsigned int* tableptr;
205  tableptr = &data[2]; // skip header!!!
206 
207  unsigned int* dataptr;
208  dataptr = &tableptr[Frames_in_event];
209  datafullsize = fullsize - 2 * 4 - Frames_in_event * 4; // minus header, minus table
210 
211  int ll = 0; // Offset in dataptr in bytes
212  for (int j = 0; j < Frames_in_event; j++) {
213  int lo;
214  lo = ((ubig32_t*)tableptr)[j];
215  if (lo <= 0) {
216  B2ERROR("size of frame invalid: " << j << "size " << lo << " at byte offset in dataptr " << ll);
217  return false;
218  }
219  if (ll + lo > datafullsize) {
220  B2ERROR("frames exceed packet size: " << j << " size " << lo << " at byte offset in dataptr " << ll << " of datafullsize " <<
221  datafullsize << " of fullsize " << fullsize);
222  return false;
223  }
224  if (lo & 0x3) {
225  B2ERROR("SKIP Frame with Data with not MOD 4 length " << " ( $" << hex << lo << " ) ");
226  ll += (lo + 3) & 0xFFFFFFFC;
227  } else {
228  if (unpack_dhc_frame(ll + (char*)dataptr)) return true;
229  ll += lo;
230  }
231  }
232  return false;
233 }
234 
236 {
237  switch (((*(ubig16_t*)data) & 0x7800) >> 11) {
238  case EDHCFrameHeaderDataType::c_ONSEN_TRG: {
239  unsigned int trignr = ((ubig32_t*)data)[2];
240  unsigned int tag = ((ubig32_t*)data)[3];
241 
242  B2INFO("Set event and exp/run from ONSEN: $" << hex << trignr << ", $" << hex << tag);
243  m_eventMetaDataPtr->setEvent(trignr);
244  m_eventMetaDataPtr->setRun((tag & 0x003FFF00) >> 8);
245  m_eventMetaDataPtr->setSubrun(tag & 0xFF);
246  m_eventMetaDataPtr->setExperiment((tag & 0xFFC00000) >> 22);
247  m_eventMetaDataPtr->setTime(0);// will overwrite in next frame (below)
248  break;
249  }
250  case EDHCFrameHeaderDataType::c_DHC_START: {
251  unsigned int time_tag_lo_and_type = ((ubig16_t*)data)[3];
252  unsigned int time_tag_mid = ((ubig16_t*)data)[4];
253  unsigned int time_tag_hi = ((ubig16_t*)data)[5];
254  B2INFO("Set time tag from DHC: $" << hex << time_tag_mid << ", $" << hex << time_tag_lo_and_type);
255  uint32_t tt = ((time_tag_mid & 0x7FFF) << 12) | (time_tag_lo_and_type >> 4);
256  // we cannot recover full time tag from DHH header, but we do as much as possible to
257  // allow for check against a second PXD packet. Again: The time recovered here is WRONG, as we only have the lowest 17 bit of the second since epoch
258  m_eventMetaDataPtr->setTime((unsigned long long int)((time_tag_hi << 1) + ((time_tag_mid & 0x8000) ? 1 : 0)) * 1000000000 +
259  (int)std::round(tt / 0.127216));
260  return true;// assumes that DHC start is behind ONSEN_TRG
261  }
262  default:
263  break;
264 
265  }
266  return false;
267 }
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 encode/decode an EvtMessage.
Definition: MsgHandler.h:103
void initialize() override final
Initialize.
bool getTrigNr(RawPXD &px)
get the trigger number
int m_nread
No. of sent events.
int read_data(char *data, size_t len)
Read amount of data (len bytes) from file to ptr data.
bool m_setEvtMeta
Set Event Meta Info.
void terminate() override final
Terminate.
void event() override final
Event.
MsgHandler * m_msghandler
Message handler.
bool unpack_dhc_frame(void *data)
unpack the dhc frame
std::string m_filename
File Name.
int m_compressionLevel
Compression Level.
int readOneEvent(void)
Read data of one Event from File.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
Event Meta Data.
The Raw PXD class.
Definition: RawPXD.h:27
virtual int * data(void)
get pointer to data
Definition: RawPXD.cc:81
virtual int size() const
get size of buffer in 32 Bit words
Definition: RawPXD.cc:76
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
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::big_uint32_t ubig32_t
define alias ubig32_t
boost::endian::big_uint16_t ubig16_t
define alias ubig16_t
Abstract base class for different kinds of events.