Belle II Software  release-08-01-10
PXDRawDumper.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/pxdHelper/PXDRawDumper.h>
10 #include <boost/format.hpp>
11 #include <boost/endian/arithmetic.hpp>
12 
13 using namespace std;
14 using namespace Belle2;
15 using namespace PXD;
16 
17 using ulittle16_t = boost::endian::little_uint16_t;
18 using ulittle32_t = boost::endian::little_uint32_t;
19 using ubig16_t = boost::endian::big_uint16_t;
20 using ubig32_t = boost::endian::big_uint32_t;
21 
22 //-----------------------------------------------------------------
23 // Register the Module
24 //-----------------------------------------------------------------
25 REG_MODULE(PXDRawDumper);
26 
27 void PXDRawDumperModule::initialize(void)
28 {
29  m_storeRaw.isRequired();
30 }
31 
32 void PXDRawDumperModule::event(void)
33 {
34  // erst mal muss man die beiden trigger nummern finden ...
35 
36  unsigned int pxdTriggerNr = 0x0, tag = 0x0;
37  for (auto& it : m_storeRaw) {
38  if (getTrigNr(it, pxdTriggerNr, tag)) break; // only first (valid) one
39  }
40 
41  if (pxdTriggerNr != 0x0 && tag != 0x0) {
42  } else { // else if put same upcounter in
43  static int nr1 = 1000, nr2 = 1000;
44  pxdTriggerNr = nr1++;
45  tag = nr2++;
46  }
47  {
48  int i = 0;
49  for (auto& it : m_storeRaw) {
50  FILE* fh;
51  string name = boost::str(boost::format("%08X_%08X_%d.pxd.dump") % tag % pxdTriggerNr % i);
52  B2ERROR("PXDRawDumper: Dump to " << name);
53  fh = fopen(name.c_str(), "wt+");
54  if (fh) {
55  fwrite(it.data(), 4, it.size(), fh);
56  fclose(fh);
57  }
58  i++;
59  }
60  }
61 }
62 
63 
64 bool PXDRawDumperModule::getTrigNr(RawPXD& px, unsigned int& innerDHH, unsigned int& tag)
65 {
66  int Frames_in_event;
67  int fullsize;
68  int datafullsize;
69 
70  if (px.size() <= 0 || px.size() > 16 * 1024 * 1024) {
71  B2ERROR("PXD Unpacker --> invalid packet size (32bit words) " << hex << px.size());
72  return false;
73  }
74  std::vector<unsigned int> data(px.size());
75  fullsize = px.size() * 4;
76  std::copy_n(px.data(), px.size(), data.begin());
77 
78 
79  if (fullsize < 8) {
80  B2ERROR("Data is to small to hold a valid Header! Will not unpack anything. Size:" << fullsize);
81  return false;
82  }
83 
84  if (data[0] != 0xCAFEBABE && data[0] != 0xBEBAFECA) {
85  B2ERROR("Magic invalid: Will not unpack anything. Header corrupted! " << hex << data[0]);
86  return false;
87  }
88 
89  Frames_in_event = ((ubig32_t*)data.data())[1];
90  if (Frames_in_event < 0 || Frames_in_event > 256) {
91  B2ERROR("Number of Frames invalid: Will not unpack anything. Header corrupted! Frames in event: " << to_string(Frames_in_event));
92  return false;
93  }
94 
95  unsigned int* tableptr;
96  tableptr = &data[2]; // skip header!!!
97 
98  unsigned int* dataptr;
99  dataptr = &tableptr[Frames_in_event];
100  datafullsize = fullsize - 2 * 4 - Frames_in_event * 4; // minus header, minus table
101 
102  int ll = 0; // Offset in dataptr in bytes
103  for (int j = 0; j < Frames_in_event; j++) {
104  int lo;
105  lo = ((ubig32_t*)tableptr)[j];
106  if (lo <= 0) {
107  B2ERROR("size of frame invalid: " << j << "size " << lo << " at byte offset in dataptr " << ll);
108  return false;
109  }
110  if (ll + lo > datafullsize) {
111  B2ERROR("frames exceed packet size: " << j << " size " << lo << " at byte offset in dataptr " << ll << " of datafullsize " <<
112  datafullsize << " of fullsize " << fullsize);
113  return false;
114  }
115  if (lo & 0x3) {
116  B2ERROR("SKIP Frame with Data with not MOD 4 length " << " ( $" << hex << lo << " ) ");
117  ll += (lo + 3) & 0xFFFFFFFC;
118  } else {
119  B2INFO("unpack DHE(C) frame: " << j << " with size " << lo << " at byte offset in dataptr " << ll);
120  if (unpack_dhc_frame(ll + (char*)dataptr, innerDHH, tag)) return true;
121  ll += lo;
122  }
123  }
124  return false;
125 }
126 
127 bool PXDRawDumperModule::unpack_dhc_frame(void* data, unsigned int& innerDHH, unsigned int& tag)
128 {
129 // DHC envelope, new
130 #define DHC_FRAME_HEADER_DATA_TYPE_DHC_START 0xB
131 #define DHC_FRAME_HEADER_DATA_TYPE_DHC_END 0xC
132 
133  switch (((*(ubig16_t*)data) & 0x7800) >> 11) {
134  case DHC_FRAME_HEADER_DATA_TYPE_DHC_START: {
135  unsigned int hi = ((ubig16_t*)data)[2];
136  innerDHH = (hi << 16) | ((ubig16_t*)data)[1];
137  tag = ((ubig32_t*)data)[3];
138  return true;
139  }
140  default:
141  break;
142 
143  }
144  return false;
145 }
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
#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.