From 0107e367c484d4181decf6c0e8e305c8bfb1ee9b Mon Sep 17 00:00:00 2001 From: Mario Fink Date: Thu, 11 Feb 2021 19:21:26 +0100 Subject: [PATCH] finished conversion + CLI --- lib/imc_channel.hpp | 182 ++++++++++++++++++++++++++++++----------- lib/imc_conversion.hpp | 45 ++++++++++ lib/imc_datatype.hpp | 16 ++-- lib/imc_raw.hpp | 31 +------ src/main.cpp | 68 +++++++++------ 5 files changed, 233 insertions(+), 109 deletions(-) create mode 100644 lib/imc_conversion.hpp diff --git a/lib/imc_channel.hpp b/lib/imc_channel.hpp index 01637ef..cbe1514 100644 --- a/lib/imc_channel.hpp +++ b/lib/imc_channel.hpp @@ -5,6 +5,7 @@ #include #include "imc_datatype.hpp" +#include "imc_conversion.hpp" //---------------------------------------------------------------------------// @@ -114,7 +115,8 @@ namespace imc { // associated environment of blocks and map of blocks channel_env chnenv_; - const std::map* blocks_; + std::map* blocks_; + std::vector* buffer_; // collect meta-data of channels according to env, // just everything valueable in here @@ -123,7 +125,7 @@ namespace imc std::string origin_, origin_comment_, text_; std::string yname_, yunit_; std::string xname_, xunit_; - double xstepwidth_; + double xstepwidth_, xoffset_; // buffer and data int signbits_, num_bytes_; @@ -132,7 +134,7 @@ namespace imc int datatp_; imc::datatype dattyp_; std::vector ydata_; - std::vector xdata_; + std::vector xdata_; // range, factor and offset double factor_, offset_; @@ -142,8 +144,9 @@ namespace imc std::string group_uuid_, group_name_, group_comment_; // constructor takes channel's block environment - channel(channel_env chnenv, std::map* blocks): - chnenv_(chnenv), blocks_(blocks), group_index_(-1) + channel(channel_env chnenv, std::map* blocks, + std::vector* buffer): + chnenv_(chnenv), blocks_(blocks), buffer_(buffer), group_index_(-1) { // declare list of block parameters std::vector prms; @@ -152,76 +155,159 @@ namespace imc uuid_ = chnenv_.CNuuid_; // extract associated CB data - if ( blocks->count(chnenv_.CBuuid_) == 1 ) + if ( blocks_->count(chnenv_.CBuuid_) == 1 ) { - prms = blocks->at(chnenv_.CBuuid_).get_parameters(); - group_index_ = std::stoi(blocks->at(chnenv_.CBuuid_).get_parameter(prms[2])); - group_name_ = blocks->at(chnenv_.CBuuid_).get_parameter(prms[4]); - group_comment_ = blocks->at(chnenv_.CBuuid_).get_parameter(prms[6]); + prms = blocks_->at(chnenv_.CBuuid_).get_parameters(); + group_index_ = std::stoi(blocks_->at(chnenv_.CBuuid_).get_parameter(prms[2])); + group_name_ = blocks_->at(chnenv_.CBuuid_).get_parameter(prms[4]); + group_comment_ = blocks_->at(chnenv_.CBuuid_).get_parameter(prms[6]); } // extract associated CT data - if ( blocks->count(chnenv_.CTuuid_) == 1 ) + if ( blocks_->count(chnenv_.CTuuid_) == 1 ) { - prms = blocks->at(chnenv_.CTuuid_).get_parameters(); - text_ = blocks->at(chnenv_.CTuuid_).get_parameter(prms[4]) + std::string(" - ") - + blocks->at(chnenv_.CTuuid_).get_parameter(prms[6]) + std::string(" - ") - + blocks->at(chnenv_.CTuuid_).get_parameter(prms[8]); + prms = blocks_->at(chnenv_.CTuuid_).get_parameters(); + text_ = blocks_->at(chnenv_.CTuuid_).get_parameter(prms[4]) + std::string(" - ") + + blocks_->at(chnenv_.CTuuid_).get_parameter(prms[6]) + std::string(" - ") + + blocks_->at(chnenv_.CTuuid_).get_parameter(prms[8]); } // extract associated CD data - if ( blocks->count(chnenv_.CDuuid_) == 1 ) + if ( blocks_->count(chnenv_.CDuuid_) == 1 ) { - prms = blocks->at(chnenv_.CDuuid_).get_parameters(); - xstepwidth_ = std::stod(blocks->at(chnenv_.CDuuid_).get_parameter(prms[2])); - xunit_ = blocks->at(chnenv_.CDuuid_).get_parameter(prms[5]); + prms = blocks_->at(chnenv_.CDuuid_).get_parameters(); + xstepwidth_ = std::stod(blocks_->at(chnenv_.CDuuid_).get_parameter(prms[2])); + xunit_ = blocks_->at(chnenv_.CDuuid_).get_parameter(prms[5]); // TODO - xname_ = std::string("time"); + // xname_ = std::string("time"); } // extract associated CP data - if ( blocks->count(chnenv_.CPuuid_) == 1 ) + if ( blocks_->count(chnenv_.CPuuid_) == 1 ) { - prms = blocks->at(chnenv_.CPuuid_).get_parameters(); - datatp_ = std::stoi(blocks->at(chnenv_.CPuuid_).get_parameter(prms[3])); - num_bytes_ = std::stoi(blocks->at(chnenv_.CPuuid_).get_parameter(prms[4])); - signbits_ = std::stoi(blocks->at(chnenv_.CPuuid_).get_parameter(prms[5])); - // byte_offset_ = std::stoul(blocks->at(chnenv_.CPuuid_).get_parameter(prms[7])); + prms = blocks_->at(chnenv_.CPuuid_).get_parameters(); + num_bytes_ = std::stoi(blocks_->at(chnenv_.CPuuid_).get_parameter(prms[3])); + datatp_ = std::stoi(blocks_->at(chnenv_.CPuuid_).get_parameter(prms[4])); + signbits_ = std::stoi(blocks_->at(chnenv_.CPuuid_).get_parameter(prms[5])); + // byte_offset_ = std::stoul(blocks_->at(chnenv_.CPuuid_).get_parameter(prms[7])); } // extract associated Cb data - if ( blocks->count(chnenv_.Cbuuid_) == 1 ) + if ( blocks_->count(chnenv_.Cbuuid_) == 1 ) { - prms = blocks->at(chnenv_.Cbuuid_).get_parameters(); - buffer_offset_ = std::stoul(blocks->at(chnenv_.Cbuuid_).get_parameter(prms[6])); - buffer_size_ = std::stoul(blocks->at(chnenv_.Cbuuid_).get_parameter(prms[7])); + prms = blocks_->at(chnenv_.Cbuuid_).get_parameters(); + buffer_offset_ = std::stoul(blocks_->at(chnenv_.Cbuuid_).get_parameter(prms[6])); + buffer_size_ = std::stoul(blocks_->at(chnenv_.Cbuuid_).get_parameter(prms[7])); + xoffset_ = std::stod(blocks_->at(chnenv_.Cbuuid_).get_parameter(prms[11])); } // extract associated CR data - if ( blocks->count(chnenv_.CRuuid_) == 1 ) + if ( blocks_->count(chnenv_.CRuuid_) == 1 ) { - prms = blocks->at(chnenv_.CRuuid_).get_parameters(); - factor_ = std::stod(blocks->at(chnenv_.CRuuid_).get_parameter(prms[3])); - offset_ = std::stod(blocks->at(chnenv_.CRuuid_).get_parameter(prms[4])); - yunit_ = blocks->at(chnenv_.CRuuid_).get_parameter(prms[7]); + prms = blocks_->at(chnenv_.CRuuid_).get_parameters(); + factor_ = std::stod(blocks_->at(chnenv_.CRuuid_).get_parameter(prms[3])); + offset_ = std::stod(blocks_->at(chnenv_.CRuuid_).get_parameter(prms[4])); + yunit_ = blocks_->at(chnenv_.CRuuid_).get_parameter(prms[7]); } // extract associated CN data - if ( blocks->count(chnenv_.CNuuid_) == 1 ) + if ( blocks_->count(chnenv_.CNuuid_) == 1 ) { - prms = blocks->at(chnenv_.CNuuid_).get_parameters(); - name_ = blocks->at(chnenv_.CNuuid_).get_parameter(prms[6]); + prms = blocks_->at(chnenv_.CNuuid_).get_parameters(); + name_ = blocks_->at(chnenv_.CNuuid_).get_parameter(prms[6]); yname_ = name_; - comment_ = blocks->at(chnenv_.CNuuid_).get_parameter(prms[8]); - // group_index_ = std::stoi(blocks->at(chnenv_.CNuuid_).get_parameter(prms[2])); + comment_ = blocks_->at(chnenv_.CNuuid_).get_parameter(prms[8]); + // group_index_ = std::stoi(blocks_->at(chnenv_.CNuuid_).get_parameter(prms[2])); } // extract associated NO data - if ( blocks->count(chnenv_.NOuuid_) == 1 ) + if ( blocks_->count(chnenv_.NOuuid_) == 1 ) { - prms = blocks->at(chnenv_.NOuuid_).get_parameters(); - origin_ = blocks->at(chnenv_.NOuuid_).get_parameter(prms[4]); - origin_comment_ = blocks->at(chnenv_.NOuuid_).get_parameter(prms[6]); + prms = blocks_->at(chnenv_.NOuuid_).get_parameters(); + origin_ = blocks_->at(chnenv_.NOuuid_).get_parameter(prms[4]); + origin_comment_ = blocks_->at(chnenv_.NOuuid_).get_parameter(prms[6]); + } + + // start converting binary buffer to imc::datatype + if ( !chnenv_.CSuuid_.empty() ) convert_buffer(); + } + + // convert buffer to actual datatype + void convert_buffer() + { + // TODO no clue how/if/when to handle buffer offset/mask/subsequent_bytes + // etc. and whatever that shit is! + std::vector prms = blocks_->at(chnenv_.CSuuid_).get_parameters(); + if ( prms.size() < 4) + { + throw std::runtime_error("CS block is invalid and features to few parameters"); + } + unsigned long int buffstrt = prms[3].begin(); + std::vector CSbuffer( buffer_->begin()+buffstrt+1, + buffer_->begin()+buffstrt+buffer_size_+1 ); + + // determine number of values in buffer + unsigned long int num_values = CSbuffer.size()/(signbits_/8); + if ( num_values*(signbits_/8) != CSbuffer.size() ) + { + throw std::runtime_error("CSbuffer and significant bits of datatype don't match"); + } + + // adjust size of ydata + ydata_.resize(num_values); + + // distinguish numeric datatypes included in "imc_datatype" + if ( datatp_ == 1 ) + { + imc::convert_data_to_type(CSbuffer,ydata_); + } + else if ( datatp_ == 2 ) + { + imc::convert_data_to_type(CSbuffer,ydata_); + } + else if ( datatp_ == 3 ) + { + imc::convert_data_to_type(CSbuffer,ydata_); + } + else if ( datatp_ == 4 ) + { + imc::convert_data_to_type(CSbuffer,ydata_); + } + else if ( datatp_ == 5 ) + { + imc::convert_data_to_type(CSbuffer,ydata_); + } + else if ( datatp_ == 6 ) + { + imc::convert_data_to_type(CSbuffer,ydata_); + } + else if ( datatp_ == 7 ) + { + imc::convert_data_to_type(CSbuffer,ydata_); + } + else if ( datatp_ == 8 ) + { + imc::convert_data_to_type(CSbuffer,ydata_); + } + else + { + throw std::runtime_error(std::string("unsupported/unknown datatype") + std::to_string(datatp_)); + } + + // fill xdata_ + for ( unsigned long int i = 0; i < num_values; i++ ) + { + xdata_.push_back(xoffset_+i*xstepwidth_); + } + + // employ data transformation + if ( factor_ != 1.0 || offset_ != 0.0 ) + { + for ( imc::datatype& el: ydata_ ) + { + // std::cout<<"value:"<(ydata_)<<"\n" - <(xdata_)<<"\n" - <(xdata_)<<"\n"; + // <(ydata_) - <<"\",\"xdata\":\""<(xdata_) + <<"\",\"xdata\":\""<(xdata_) <<"\",\"aff. blocks\":\""< + +//---------------------------------------------------------------------------// + +namespace imc +{ + // convert raw data in buffer into specific datatype + template + void convert_data_to_type(std::vector& subbuffer, + std::vector& channel) + { + // check number of elements of type "datatype" in buffer + if ( subbuffer.size() != channel.size()*sizeof(datatype) ) + { + throw std::runtime_error("size mismatch between subbuffer and datatype"); + } + + // extract every single number of type "datatype" from buffer + for ( unsigned long int i = 0; i < channel.size(); i++ ) + { + // declare number of required type and point it to first byte in buffer + // representing the number + datatype df; + uint8_t* dfcast = reinterpret_cast(&df); + + for ( unsigned long int j = 0; j < sizeof(datatype); j++ ) + { + dfcast[j] = (int)subbuffer[i*sizeof(datatype)+j]; + } + + // save number in channel + channel[i] = df; + } + } + +} + +#endif + +//---------------------------------------------------------------------------// diff --git a/lib/imc_datatype.hpp b/lib/imc_datatype.hpp index 5e32608..79360e7 100644 --- a/lib/imc_datatype.hpp +++ b/lib/imc_datatype.hpp @@ -32,10 +32,10 @@ namespace imc short int dtidx_; // \in \{0,...,7\} public: datatype(): ubyte_(0), sbyte_(0), - ushort_(0), sshort_(0), - ulint_(0.0), slint_(0.0), - sfloat_(0.0), sdouble_(0.0), - dtidx_(0) { }; + ushort_(0), sshort_(0), + ulint_(0.0), slint_(0.0), + sfloat_(0.0), sdouble_(0.0), + dtidx_(0) { }; // every supported datatype gets its own constructor datatype(imc_Ubyte num): ubyte_(num), dtidx_(0) {}; datatype(imc_Sbyte num): sbyte_(num), dtidx_(1) {}; @@ -44,7 +44,9 @@ namespace imc datatype(imc_Ulongint num): ulint_(num), dtidx_(4) {}; datatype(imc_Slongint num): slint_(num), dtidx_(5) {}; datatype(imc_float num): sfloat_(num), dtidx_(6) {}; - datatype(imc_double num): sdouble_(num), dtidx_(7) {}; + datatype(imc_double num): ubyte_(0), sbyte_(0), ushort_(0), sshort_(0), + ulint_(0.0), slint_(0.0), sfloat_(0.0), sdouble_(num), + dtidx_(7) {}; // identify type short int& dtype() { return dtidx_; } @@ -142,8 +144,8 @@ namespace imc else if ( num.dtidx_ == 3 ) out< - (chnenv.CNuuid_,imc::channel(chnenv,&mapblocks_)) + (chnenv.CNuuid_,imc::channel(chnenv,&mapblocks_,&buffer_)) ); // reset channel uuid @@ -245,35 +245,6 @@ namespace imc } } - // parse channel's raw data - template - void convert_data_to_type(std::vector& subbuffer, - std::vector& channel) - { - // check number of elements of type "datatype" in buffer - if ( subbuffer.size() != channel.size()*sizeof(datatype) ) - { - throw std::runtime_error("size mismatch between subbuffer and datatype"); - } - - // extract every single number of type "datatype" from buffer - for ( unsigned long int i = 0; i < channel.size(); i++ ) - { - // declare number of required type and point it to first byte in buffer - // representing the number - datatype df; - uint8_t* dfcast = reinterpret_cast(&df); - - for ( unsigned long int j = 0; j < sizeof(datatype); j++ ) - { - dfcast[j] = (int)subbuffer[i*sizeof(datatype)+j]; - } - - // save number in channel - channel[i] = df; - } - } - public: diff --git a/src/main.cpp b/src/main.cpp index 80b0bfb..e54bd58 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,11 +36,11 @@ optkeys parse_args(int argc, char* argv[], bool list_args = false) { prsdkeys.insert(std::pair("showmeta",argv[i])); } - else if ( std::string(argv[i]) == std::string("--listgroups") - || std::string(argv[i]) == std::string("-g") ) - { - prsdkeys.insert(std::pair("listgroups",argv[i])); - } + // else if ( std::string(argv[i]) == std::string("--listgroups") + // || std::string(argv[i]) == std::string("-g") ) + // { + // prsdkeys.insert(std::pair("listgroups",argv[i])); + // } else if ( std::string(argv[i]) == std::string("--listchannels") || std::string(argv[i]) == std::string("-c") ) { @@ -51,17 +51,17 @@ optkeys parse_args(int argc, char* argv[], bool list_args = false) { prsdkeys.insert(std::pair("listblocks",argv[i])); } - else if ( std::string(argv[i]) == std::string("--filename") - || std::string(argv[i]) == std::string("-f") ) + else if ( std::string(argv[i]) == std::string("--output") + || std::string(argv[i]) == std::string("-d") ) { if ( i+1 == argc || argv[i+1][0] == '-' ) { - std::cerr<<"invalid or missing --filename argument\n"; - prsdkeys.insert(std::pair("invalid","filename")); + std::cerr<<"invalid or missing --output argument\n"; + prsdkeys.insert(std::pair("invalid","output")); } else { - prsdkeys.insert(std::pair("filename",argv[i+1])); + prsdkeys.insert(std::pair("output",argv[i+1])); i = i + 1; } } @@ -116,10 +116,10 @@ void show_usage() <<"Options:" <<"\n\n" <<" -m, --showmeta show meta information about IMC dataset\n" - <<" -g, --listgroups list channelgroups\n" + // <<" -g, --listgroups list channelgroups\n" <<" -c, --listchannels list channels\n" <<" -b, --listblocks list IMC key-blocks\n" - <<" -f, --filename filename for csv output\n" + <<" -d, --output output directory\n" <<" -h, --help show this help message \n" <<" -v, --version display version\n" <<"\n"; @@ -146,13 +146,20 @@ int main(int argc, char* argv[]) else { // check for at least one file argument - if ( cfgopts.size() == (unsigned int)argc-1 ) + if ( argc == 1 ) { std::cerr<<"no .raw file given => check --help for usage\n"; return 1; } std::string rawfile(argv[1]); + // one further argument to do something useful with the file + if ( argc == 2 ) + { + std::cerr<<"provide any option => check --help for usage\n"; + return 1; + } + // check existence of file std::filesystem::path rawpath = rawfile; if ( !std::filesystem::exists(rawpath) ) @@ -170,20 +177,31 @@ int main(int argc, char* argv[]) return 1; } - // // list blocks - // for ( imc::block blk: imcraw.blocks() ) - // { - // std::cout< channels = imcraw.get_channels(); - for ( auto el: channels ) std::cout< channels = imcraw.get_channels(); + for ( auto el: channels ) std::cout<