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