dlardaq_service.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////////
2 //
3 // declarations / primitives / functions to handle raw data from DAQ
4 // ADC resolution is 12bit
5 //
6 // Created: vgalymov, Sat Jul 2 15:25:46 CEST 2016
7 // Modifed:
8 //
9 ////////////////////////////////////////////////////////////////////////////////
10 //#include <iostream>
11 #include <iomanip>
12 #include <sstream>
13 #include <fstream>
14 #include <limits>
15 #include <cstdlib>
16 #include <string.h>
17 #include <assert.h>
18 
19 #include "dlardaq.h"
20 #include "LogMsg.h"
21 
23 using namespace std;
24 using namespace dlardaq;
25 
26 //
27 // n8bit is the size of the output that should be
28 // allocated to be x3/2 larger of the input
29 //
30 void dlardaq::pack16into12(const void *in, void *out, size_t n8bit)
31 {
32  const adc16_t* in16 = static_cast<const adc16_t*>(in);
33  BYTE* out8 = static_cast<BYTE*>(out);
34  BYTE* stop = out8 + n8bit;
35 
36  while(out8!=stop)
37  {
38  // we pack 2x12 bit values into 3x8bit
39  adc16_t v1 = *in16++;
40  adc16_t v2 = *in16++;
41 
42  *out8++ = ( v1 >> 4 ) & 0xff;
43  *out8++ = ( (v1 & 0xf) << 4 ) + ( ( v2 >> 8) & 0xf );
44  *out8++ = v2 & 0xff;
45  }
46 }
47 
48 //
49 // n8bit is the size ouf the input that should be x3/2
50 // larger than the output vector
51 //
52 void dlardaq::unpack12into16(const void *in, void *out, size_t n8bit)
53 {
54  const BYTE* in8 = static_cast<const BYTE*>(in);
55  const BYTE* stop = in8 + n8bit;
56 
57  adc16_t* out16 = static_cast<adc16_t*>(out);
58 
59  while(in8!=stop)
60  {
61  BYTE v1 = *in8++;
62  BYTE v2 = *in8++;
63  BYTE v3 = *in8++;
64 
65  *out16++ = ((v1 << 4) + ((v2 >> 4) & 0xf)) & 0xfff;
66  *out16++ = (((v2 & 0xf) << 8 ) + (v3 & 0xff)) & 0xfff;
67  }
68 }
69 
70 //
71 // write binary file packing data into 12 bit segments
72 // this is just an example
73 //
74 void dlardaq::write12(const char *fname, std::vector<adc16_t> &adc)
75 {
76  size_t vecsize = adc.size();
77  if(vecsize % 2)
78  {
79  msg_warn<<"The input vector size is not even. Appending zeros"<<endl;
80  adc.push_back( 0 ); // careful, 0 added returns by reference !!!
81  vecsize++;
82  }
83 
84  // size of the 8 bit buffer
85  size_t bufsize = vecsize/2*3;
86 
87  // new buffer
88  char *buffer = new char[bufsize];
89 
90  // fill it
91  pack16into12(&adc[0], buffer, bufsize);
92 
93  // write it to file
94  ofstream fout(fname, ios::out | ios::binary);
95  fout.write(buffer, bufsize);
96  fout.close();
97 
98  delete [] buffer;
99 }
100 
101 
102 //
103 // read binary file uppacking 12 bit data into 16 bit segments
104 //
105 void dlardaq::read12(const char *fname, std::vector<adc16_t> &adc)
106 {
107  //std::ifstream fin(fname, ios::in | ios::binary | ios::ate);
108  std::ifstream fin(fname, ios::in | ios::binary);
109 
110  // get number of bytes
111  //size_t bufsize = fin.tellg();
112  //fin.seekg(0, ios::beg);
113 
114  // more presise ???
116  size_t bufsize = fin.gcount();
117  fin.clear();
118  fin.seekg( 0, std::ios_base::beg );
119 
120  size_t npad = 0;
121  while( (bufsize+npad) % 3 )
122  {
123  msg_warn<<"The input vector size is not divisible by 3. Appending zeros"<<endl;
124  npad++;
125  }
126 
127  // allocate memory for file content
128  char* buffer = new char[bufsize + npad];
129  for(size_t i=bufsize;i<bufsize+npad;i++)
130  buffer[i] = '\0';
131 
132  // read content of the file
133  fin.read(buffer, bufsize);
134  fin.close();
135 
136  adc.clear();
137  adc.resize( (bufsize + npad)/3*2, 0 );
138  unpack12into16( buffer, &adc[0], bufsize + npad );
139 
140  delete [] buffer;
141 }
142 
143 
144 //
145 // decode run header bytes
146 ssize_t dlardaq::decode_runhead(const char *buf, dlardaq::runheader_t &rh)
147 {
148  ssize_t rval = RunHeadSz;
149  memset(&rh, 0, sizeof(rh));
150  // in general we will get undefined behaviour if buf < required bytes
151  // the try - catch block will not help, but does not hurt either
152  try
153  {
154  // decode run number
155  rh.run_num = (((uint32_t)buf[0] << 24) & 0xFF000000);
156  rh.run_num += (((uint32_t)buf[1] << 16) & 0xFF0000);
157  rh.run_num += (((uint32_t)buf[2] << 8) & 0xFF00);
158  rh.run_num += ( (uint32_t)buf[3] & 0xFF);
159 
160  rh.run_flags = (uint8_t)buf[4];
161  }
162  catch(std::exception &e)
163  {
164  msg_err<<"Decode runheader exception "<<e.what()<<endl;
165  rval = -1;
166  }
167 
168  return rval;
169 }
170 
171 //
172 //
173 // event header bytes
174 ssize_t dlardaq::decode_evehead(const char* buf, dlardaq::evheader_t &eh)
175 {
176  ssize_t rval = EveHeadSz;
177  memset(&eh, 0, sizeof(eh));
178 
179  try
180  {
181  // check for delimiting words
182  BYTE k0 = buf[0];
183  BYTE k1 = buf[1];
184  if( !( ((k0 & 0xFF) == EVSKEY) && ((k1 & 0xFF) == EVSKEY) ) )
185  {
186  msg_err<<"Event delimiting word could not be detected "<<endl;
187  throw fex;
188  }
189  rval = 2;
190  // this is actually written in host byte order
191  eh.trig_info = ConvertToValue<trigger_t>(buf+rval);
192  rval += sizeof(eh.trig_info);
193 
194  // data quality flags
195  eh.dq_flag = (uint8_t)buf[rval++];
196 
197  // event number 4 bytes
198  eh.ev_num = (((uint32_t)buf[rval++] << 24) & 0xFF000000);
199  eh.ev_num += (((uint32_t)buf[rval++] << 16) & 0xFF0000);
200  eh.ev_num += (((uint32_t)buf[rval++] << 8) & 0xFF00);
201  eh.ev_num += ( (uint32_t)buf[rval++] & 0xFF);
202 
203 
204  // event number 4 bytes
205  eh.ev_size = (((uint32_t)buf[rval++] << 24) & 0xFF000000);
206  eh.ev_size += (((uint32_t)buf[rval++] << 16) & 0xFF0000);
207  eh.ev_size += (((uint32_t)buf[rval++] << 8) & 0xFF00);
208  eh.ev_size += ( (uint32_t)buf[rval++] & 0xFF);
209  }
210  catch(exception &e)
211  {
212  msg_err<<"Decode event header exception "<<e.what()<<endl;
213  rval = -1;
214  }
215 
216  return rval;
217 }
218 
219 //
220 // decode run footer to get number of events
221 ssize_t dlardaq::decode_filefoot(const char *buf, dlardaq::footer_t &rf)
222 {
223  ssize_t rval = FileFootSz;
224  memset(&rf, 0, sizeof(rf));
225 
226  try
227  {
228  // check for delimiting words
229  if( !( ((buf[0]&0xFF) == ENDKEY) && ((buf[1]&0xFF) == ENDKEY) ) )
230  {
231  msg_err<<"Delimiting word in footer could not be detected "<<endl;
232  throw fex;
233  }
234  rf.num_events = (((uint16_t)buf[2] << 8) & 0xff00) + (buf[3] & 0xff);
235  }
236  catch(exception &e)
237  {
238  msg_err<<"Decode footer info exception "<<e.what()<<endl;
239  rval = -1;
240  }
241 
242  return rval;
243 }
244 
245 
246 
uint16_t adc16_t
Definition: dlardaq.h:40
static LogStream msg_warn(std::cout, _strwarn)
static const size_t FileFootSz
Definition: dlardaq.h:60
trigger_t trig_info
Definition: dlardaq.h:83
uint32_t ev_num
Definition: dlardaq.h:85
int16_t adc
Definition: CRTFragment.hh:202
STL namespace.
ssize_t decode_evehead(const char *buf, evheader_t &eh)
ssize_t decode_runhead(const char *buf, runheader_t &rh)
static const size_t RunHeadSz
Definition: dlardaq.h:56
uint8_t dq_flag
Definition: dlardaq.h:84
#define ENDKEY
Definition: dlardaq.h:21
static const size_t EveHeadSz
Definition: dlardaq.h:58
const double e
char BYTE
Definition: dlardaq.h:39
uint32_t ev_size
Definition: dlardaq.h:86
ssize_t decode_filefoot(const char *buf, footer_t &rf)
static int max(int a, int b)
#define EVSKEY
Definition: dlardaq.h:20
QString read()
void unpack12into16(const void *in, void *out, size_t n)
void pack16into12(const void *in, void *out, size_t n)
void read12(const char *fname, std::vector< adc16_t > &adc)
uint16_t num_events
Definition: dlardaq.h:92
void write12(const char *fname, std::vector< adc16_t > &adc)
uint8_t run_flags
Definition: dlardaq.h:77
static LogStream msg_err(std::cerr, _strerror)
static formatexception fex
Definition: dlardaq.h:52
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
uint32_t run_num
Definition: dlardaq.h:76