fix conversion of with CP marker : Zahlenformat = 11 (2-Byte Word digital)

This commit is contained in:
Mario Fink 2020-07-03 17:55:59 +02:00
parent 25b203aabd
commit 9c1e9d1468
5 changed files with 263 additions and 71 deletions

2
.gitignore vendored
View File

@ -4,6 +4,7 @@
*.csv *.csv
eatraw eatraw
eatdev
nohup.out nohup.out
@ -12,4 +13,3 @@ nohup.out
*.so *.so
raw_eater.cpp raw_eater.cpp

66
lib/hexshow.hpp Normal file
View File

@ -0,0 +1,66 @@
//---------------------------------------------------------------------------//
#ifndef HEXSHOW
#define HEXSHOW
#include <sstream>
//---------------------------------------------------------------------------//
namespace hex
{
void show(std::vector<unsigned char> &mydata, unsigned long int width = 32,
unsigned long int startidx = 0,
unsigned long int breakidx = 512)
{
// check input
assert ( startidx <= breakidx );
breakidx = ( breakidx > mydata.size() || breakidx == 0 ) ? mydata.size() : breakidx;
// introduce additional line break
std::cout<<"\n";
// declare two stringstreams for hexadecimal and ASCII output
std::stringstream sshex, sschr;
// count bytes
unsigned long int idx = 0;
// process data
for ( std::size_t i = startidx; i < breakidx; i++ )
{
unsigned char el = mydata[i];
// hex representation
if ( (idx+0)%width == 0 )
{
sshex<<std::hex<<"0x"<<std::setw(6)<<std::setfill('0')<<idx<<": ";
}
sshex<<std::hex<<std::setw(2)<<std::setfill('0')<<(int)el;
sshex<<std::dec<<std::setfill(' ')<<" ";
// ascii representation
unsigned char elcl = ( (int)el > 0x1f && (int)el < 0x7f) ? el : '.';
sschr<<std::dec<<std::setfill(' ')<<elcl;
// do actual printing
if ( (idx+1)%width == 0 )
{
std::cout<<sshex.str()<<" "<<sschr.str();
std::cout<<"\n";
// clear stringstreams
sshex.str(std::string());
sschr.str(std::string());
}
// count number of bytes
idx++;
}
std::cout<<"\n";
}
}
#endif
//---------------------------------------------------------------------------//

View File

@ -1,4 +1,11 @@
//---------------------------------------------------------------------------// //---------------------------------------------------------------------------//
//
// @file raweat.hpp
// @author Mario Fink <mario.fink@record-evolution.de>
// @date Feb 2020, 2020-07-03
// @brief header only class for decoding the imc ".raw" format
//
//---------------------------------------------------------------------------//
#ifndef RAW_EATER #ifndef RAW_EATER
#define RAW_EATER #define RAW_EATER
@ -14,6 +21,7 @@
#include <cmath> #include <cmath>
#include "endian.hpp" #include "endian.hpp"
#include "hexshow.hpp"
// support for 16bit floats // support for 16bit floats
#include <emmintrin.h> #include <emmintrin.h>
@ -68,23 +76,32 @@ public:
// constructor // constructor
raw_eater(std::string rawfile) : rawfile_(rawfile) raw_eater(std::string rawfile) : rawfile_(rawfile)
{ {
// open file and put data in buffer // open file
std::ifstream fin(rawfile.c_str(),std::ifstream::binary); std::ifstream fin(rawfile_.c_str(),std::ifstream::binary);
assert( fin.good() && "failed to open file" ); assert ( fin.good() && "failed to open file" );
// try {
// std::ifstream fin(rawfile.c_str(),std::ifstream::binary); // put data in buffer
// }
// catch (std::ifstream::failure e) {
// std::cerr<<"opening file " + rawfile + " failed";
// }
std::vector<unsigned char> rawdata((std::istreambuf_iterator<char>(fin)), std::vector<unsigned char> rawdata((std::istreambuf_iterator<char>(fin)),
(std::istreambuf_iterator<char>())); (std::istreambuf_iterator<char>()));
rawdata_ = rawdata; rawdata_ = rawdata;
// prepare and convert data // close file
fin.close();
// show raw data
this->show_buffer();
// display predefined markers
this->show_markers();
// extract data corresponding to predefined markers from buffer
find_markers(); find_markers();
// split data corresponding to markers into segments
split_segments(); split_segments();
convert_data();
// convert binary data to arrays of intrinsic data types
convert_data(true);
} }
// destructor // destructor
@ -94,19 +111,10 @@ public:
} }
// display buffer/data properties // display buffer/data properties
void show_buffer(int numel = 128) void show_buffer(int numel = 32)
{ {
// show size of buffer hex::show(rawdata_,numel,0,0);
std::cout<<"size of buffer "<<rawdata_.size()<<"\n\n"; // this->show_hex(rawdata_,32,0);
// show excerpt from buffer
int ista = 0, iend = numel;
for ( int i= ista; i < iend; i++ )
{
std::cout<<std::hex<<(int)rawdata_[i]<<" ";
if ( (i+1)%16 == 0 ) std::cout<<"\n";
}
std::cout<<"\n";
} }
// show predefined markers // show predefined markers
@ -117,12 +125,13 @@ public:
{ {
std::cout<<el.first<<" "; std::cout<<el.first<<" ";
for ( unsigned char c: el.second) std::cout<<std::hex<<int(c); for ( unsigned char c: el.second) std::cout<<std::hex<<int(c);
std::cout<<"\n\n"; std::cout<<"\n";
} }
std::cout<<std::dec; std::cout<<std::dec;
std::cout<<"\n";
} }
//---------------------------------------------------------------------------// //-------------------------------------------------------------------------//
// find predefined markers in data buffer // find predefined markers in data buffer
void find_markers() void find_markers()
@ -132,18 +141,20 @@ public:
for (std::pair<std::string,std::vector<unsigned char>> mrk : markers_ ) for (std::pair<std::string,std::vector<unsigned char>> mrk : markers_ )
{ {
assert( mrk.second.size() > 0 && "please don't define any empty marker" ); assert( mrk.second.size() > 0 && "please don't define any empty markers" );
// find marker's byte sequence in buffer // find marker's byte sequence in buffer
for ( unsigned long int idx = 0; idx < rawdata_.size(); idx++ ) for ( unsigned long int idx = 0; idx < rawdata_.size(); idx++ )
{ {
// for every byte in buffer, check, if the three subsequent bytes
// correspond to required predefined marker
bool gotit = true; bool gotit = true;
for ( unsigned long int mrkidx = 0; mrkidx < mrk.second.size() && gotit; mrkidx ++ ) for ( unsigned long int mrkidx = 0; mrkidx < mrk.second.size() && gotit; mrkidx ++ )
{ {
if ( ! (mrk.second[mrkidx] == rawdata_[idx+mrkidx]) ) gotit = false; if ( ! (mrk.second[mrkidx] == rawdata_[idx+mrkidx]) ) gotit = false;
} }
// if we got the marker, collect following bytes until end of marker byte 0x 3b // if we got the marker, collect following bytes until end of marker byte 0x3b
if ( gotit ) if ( gotit )
{ {
// array of data associated to marker // array of data associated to marker
@ -161,7 +172,8 @@ public:
} }
else else
{ {
// data marker is actually assumed to be the last and should extend until end of file // marker 'datas' is the data marker and is supposed to be the last
// and should extend until end of file
for ( unsigned long int didx = idx; didx < rawdata_.size()-1; didx++ ) for ( unsigned long int didx = idx; didx < rawdata_.size()-1; didx++ )
{ {
markseq.push_back(rawdata_[didx]); markseq.push_back(rawdata_[didx]);
@ -182,9 +194,14 @@ public:
for (std::pair<std::string,std::vector<unsigned char>> mrk : markers_ ) for (std::pair<std::string,std::vector<unsigned char>> mrk : markers_ )
{ {
//assert ( datasec_[mrk.first].size() > 0 && "marker segment of length zero" ); //assert ( datasec_[mrk.first].size() > 0 && "marker segment of length zero" );
if ( datasec_[mrk.first].size() == 0 )
{
std::cout<<"warning: "<<mrk.first<<" not found in buffer\n";
}
totalmarksize += datasec_[mrk.first].size(); totalmarksize += datasec_[mrk.first].size();
} }
assert ( totalmarksize > 0 && "didn't find any predefined marker => probably not a valid .raw-file" ); assert ( totalmarksize > 0 && "didn't find any predefined marker => probably not a valid .raw-file" );
std::cout<<"\n";
} }
@ -222,7 +239,8 @@ public:
// parse data segment // parse data segment
for ( unsigned char el: datasec_[mrk.first] ) for ( unsigned char el: datasec_[mrk.first] )
{ {
// note that data segment of "datas marker" may contain any number of 0x2c's // note that data segment of "datas marker" may contain any number
// of 0x2c's (0x2c = comma ',')
if ( ( el != 0x2c && parse ) || ( mrk.first == "datas marker" && commcount > 2 ) ) if ( ( el != 0x2c && parse ) || ( mrk.first == "datas marker" && commcount > 2 ) )
{ {
elstr.push_back(el); elstr.push_back(el);
@ -248,7 +266,7 @@ public:
} }
} }
//---------------------------------------------------------------------------// //-------------------------------------------------------------------------//
// convert actual measurement data // convert actual measurement data
void convert_data(bool showlog = false) void convert_data(bool showlog = false)
@ -265,20 +283,43 @@ public:
int typesize = std::stoi(segments_["datyp marker"][5]); int typesize = std::stoi(segments_["datyp marker"][5]);
// retrieve transformation index, factor and offset // retrieve transformation index, factor and offset
int trafo = std::stoi(segments_["punit marker"][2]); int trafo = 0;
double factor = std::stod(segments_["punit marker"][3]); double factor = 1., offset = 0.;
double offset = std::stod(segments_["punit marker"][4]); if ( segments_["punit marker"].size() > 4 )
{
trafo = std::stoi(segments_["punit marker"][2]);
factor = std::stod(segments_["punit marker"][3]);
offset = std::stod(segments_["punit marker"][4]);
}
if ( showlog )
{
std::cout<<"dattype: "<<dattype<<"\n"
<<"typesize: "<<typesize<<"\n"
<<"trafo: "<<trafo<<"\n"
<<"factor: "<<factor<<"\n"
<<"offset: "<<offset<<"\n\n";
}
// if traf = 0, make sure that factor and offset don't affect result // if traf = 0, make sure that factor and offset don't affect result
assert ( ( trafo == 0 && factor == 1.0 && offset == 0.0 ) assert ( ( ( trafo == 0 && factor == 1.0 && offset == 0.0 )
|| ( trafo == 1 ) ); || ( trafo == 1 ) )
&& "internally inconsistent 'punit' marker" );
// just don't support weird datatypes // just don't support weird datatypes
assert ( dattype > 2 && dattype < 9 ); assert ( dattype > 2 && dattype < 12 );
// switch for datatypes // switch for datatypes
switch ( dattype ) switch ( dattype )
{ {
case 1 :
assert ( sizeof(unsigned char)*8 == typesize );
convert_data_as_type<unsigned char>(datbuf,factor,offset);
break;
case 2 :
assert ( sizeof(signed char)*8 == typesize );
convert_data_as_type<signed char>(datbuf,factor,offset);
break;
case 3 : case 3 :
assert ( sizeof(unsigned short int)*8 == typesize ); assert ( sizeof(unsigned short int)*8 == typesize );
convert_data_as_type<unsigned short int>(datbuf,factor,offset); convert_data_as_type<unsigned short int>(datbuf,factor,offset);
@ -303,12 +344,29 @@ public:
assert ( sizeof(double)*8 == typesize ); assert ( sizeof(double)*8 == typesize );
convert_data_as_type<double>(datbuf,factor,offset); convert_data_as_type<double>(datbuf,factor,offset);
break; break;
case 9 :
std::cerr<<"'imc Devices Transitional Recording' datatype not supported\n";
break;
case 10 :
std::cerr<<"'Timestamp Ascii' datatype not supported\n";
break;
case 11 :
std::cout<<"warning: '2-Byte-Word digital' datatype with experimental support\n";
assert ( sizeof(short int)*8 == typesize );
convert_data_as_type<int>(datbuf,factor,offset);
break;
} }
// show excerpt of result // show excerpt of result
if ( showlog ) if ( showlog )
{ {
std::cout<<"length of data: "<<datmes_.size()<<"\n"; std::cout<<"\nlength of data: "<<datmes_.size()<<"\n";
std::cout<<"\nheader excerpt of data:\n";
for ( unsigned long int i = 0; i < datmes_.size() && i < 10; i++ )
{
std::cout<<datmes_[i]<<" ";
}
std::cout<<"\n\n";
} }
} }
@ -327,7 +385,7 @@ public:
dattype num; dattype num;
uint8_t* pnum = reinterpret_cast<uint8_t*>(&num); uint8_t* pnum = reinterpret_cast<uint8_t*>(&num);
// parse all bytes of the number // parse all bytes of the number
for ( int byi = 0; byi < (int)sizeof(dattype); byi++ ) for ( int byi = 0; byi < (int)sizeof(dattype); byi++ )
{ {
pnum[byi] = (int)datbuf[(unsigned long int)(numfl*sizeof(dattype)+byi)]; pnum[byi] = (int)datbuf[(unsigned long int)(numfl*sizeof(dattype)+byi)];
@ -338,7 +396,7 @@ public:
} }
} }
//---------------------------------------------------------------------------// //-------------------------------------------------------------------------//
// show hex dump // show hex dump
void show_hex(std::vector<unsigned char> &datavec, int width = 32, unsigned long int maxchars = 512) void show_hex(std::vector<unsigned char> &datavec, int width = 32, unsigned long int maxchars = 512)

View File

@ -14,6 +14,9 @@ OPT = -O3 -Wall -mavx -mno-tbm -mf16c -mno-f16c
$(EXE) : $(SRC)main.cpp $(LIB)raweat.hpp $(EXE) : $(SRC)main.cpp $(LIB)raweat.hpp
$(CCC) $(OPT) $< -o $@ $(CCC) $(OPT) $< -o $@
eatdev : $(SRC)main_dev.cpp $(LIB)raweat.hpp
$(CCC) $(OPT) $< -o $@
# build target for conversion set of .raw files # build target for conversion set of .raw files
eatall : $(SRC)eatall.cpp $(LIB)raweat.hpp eatall : $(SRC)eatall.cpp $(LIB)raweat.hpp
$(CCC) $(OPT) $< -o $@ $(CCC) $(OPT) $< -o $@

65
src/main_dev.cpp Normal file
View File

@ -0,0 +1,65 @@
//---------------------------------------------------------------------------//
#include <iomanip>
#include <iostream>
#include "../lib/raweat.hpp"
//---------------------------------------------------------------------------//
int main(int argc, char* argv[])
{
std::cout<<"number of CLI-arguments: "<<argc<<"\n";
for ( int i = 0; i < argc; i++ ) std::cout<<std::setw(5)<<i<<": "<<argv[i]<<"\n";
std::cout<<"\n";
// get name/path of file from CLI argument
std::string rawfile(argv[1]);
// declare instance of "raw_eater"
raw_eater eatraw(rawfile);
// // show structure of data
// eatraw.show_buffer(32);
//
// // display predefined markers
// eatraw.show_markers();
std::cout<<"\n";
std::map<std::string,std::vector<unsigned char>> marks = eatraw.get_markers();
for ( auto mrk: marks )
{
// get data
std::vector<unsigned char> dat = eatraw.get_marker_data(mrk.first);
// print marker name, length and data
std::cout<<mrk.first<<" : "<<dat.size()<<'\n';
std::cout<<std::setfill('-')<<std::setw(96)<<'\n'<<std::setfill(' ');
eatraw.show_hex(dat,32,512);
std::cout<<"\n";
std::vector<std::string> segvec = eatraw.get_segment(mrk.first);
std::cout<<"number of elements in segment: "<<segvec.size()<<"\n\n";
//for ( auto el: segvec ) std::cout<<el<<"\n";
}
// get array of encoded data
std::vector<double> mydata = eatraw.get_data();
std::cout<<"\nsize of data array: "<<mydata.size()<<"\n";
std::cout<<"\ndata header:\n";
for ( unsigned long int i = 0; i < 10 && i < mydata.size(); i++ )
{
std::cout<<mydata[i]<<"\n";
}
std::cout<<"\n";
// write data in csv-file
if ( argc == 3 )
{
std::cout<<"writing data into file "<<argv[2]<<"\n";
eatraw.write_data(std::string(argv[2]));
}
return 0;
}
//---------------------------------------------------------------------------//