From afe7331feb6d9e222e8355e74ea9052b33199615 Mon Sep 17 00:00:00 2001 From: Mario Fink Date: Tue, 30 Apr 2019 13:18:27 +0200 Subject: [PATCH] correct id channel assignment --- lib/tdm_ripper.cpp | 86 ++++++++++++++++++++++++++++++++++++++-------- lib/tdm_ripper.hpp | 20 +++++++++-- main.cpp | 21 +++++++---- 3 files changed, 104 insertions(+), 23 deletions(-) diff --git a/lib/tdm_ripper.cpp b/lib/tdm_ripper.cpp index a09ef77..dd586ea 100644 --- a/lib/tdm_ripper.cpp +++ b/lib/tdm_ripper.cpp @@ -3,9 +3,9 @@ tdm_ripper::tdm_ripper(std::string tdmfile, std::string tdxfile): tdmfile_(tdmfile), tdxfile_(tdxfile), num_channels_(0), num_groups_(0), - channel_id_(0), group_id_(0), channel_name_(0), group_name_(0), - num_channels_group_(0), channels_group_(0), - byteoffset_(0), length_(0), type_(0) + channel_id_(0), inc_id_(0), group_id_(0), channel_name_(0), group_name_(0), + num_channels_group_(0), channels_group_(0), channel_ext_(0), minmax_(0), + byteoffset_(0), length_(0), type_(0), external_id_(0) { datatypes_ = { {"eInt8Usi",8}, @@ -84,6 +84,9 @@ void tdm_ripper::parse_structure() // find datatype of channel type_.push_back(anode.attribute("valueType").value()); + + // external id of channel + external_id_.push_back(anode.attribute("id").value()); } // get node with channels and groups @@ -114,6 +117,44 @@ void tdm_ripper::parse_structure() { if ( groupid.find(group_id_[g]) != std::string::npos ) channels_group_.push_back(g+1); } + + // obtain minimum/maximum of channel + std::pair minmaxchan(atof(anode.child_value("minimum")), + atof(anode.child_value("maximum"))); + minmax_.push_back(minmaxchan); + + // TODO correct order of channels w.r.t. to list of offset, length and type by + // considering the xpointer id's !!!! + // follow xpointers to get external id + std::string locol = get_str_between(anode.child_value("local_columns"),"\"","\""); + std::string locolval; + for (pugi::xml_node anode: subtreedata.children()) + { + if ( std::string(anode.name()).compare("localcolumn") == 0 + && std::string(anode.attribute("id").value()).compare(locol) == 0 ) + { + locolval = get_str_between(anode.child_value("values"),"\"","\""); + } + } + std::string locolvalext; + for (pugi::xml_node anode: subtreedata.children()) + { + if ( std::string(anode.name()).compare("double_sequence") == 0 + && std::string(anode.attribute("id").value()).compare(locolval) == 0 ) + { + locolvalext = anode.child("values").attribute("external").value(); + } + } + // std::cout< bych) return df; } -std::vector tdm_ripper::convert_channel(int byteoffset, int length, std::string type) +std::vector tdm_ripper::convert_channel(int channelid) { - std::vector chann(length); + // obtain offset, length of channel and size of datatype + int byteoffset = byteoffset_[channelid-1]; + int length = length_[channelid-1]; + int typesize = datatypes_[type_[channelid-1]]/CHAR_BIT; - int typesize = datatypes_[type]/CHAR_BIT; + // declare resulting array + std::vector chann(length); for ( int i = 0; i < length; i++ ) { std::vector cseg(tdxbuf_.begin()+byteoffset+i*typesize, tdxbuf_.begin()+byteoffset+(i+1)*typesize); - if ( type.compare("eInt32Usi") == 0 ) chann[i] = convert_int(cseg); - if ( type.compare("eFloat64Usi") == 0 ) chann[i] = convert_double(cseg); + if ( type_[channelid-1].compare("eInt32Usi") == 0 ) chann[i] = convert_int(cseg); + if ( type_[channelid-1].compare("eFloat64Usi") == 0 ) chann[i] = convert_double(cseg); + + // check if converted value is within expected range + // if ( chann[i] < minmax_[channelid-1].first || chann[i] > minmax_[channelid-1].second ) std::cout<= minmax_[channelid-1].first && chann[i] <= minmax_[channelid-1].second ); } return chann; @@ -327,9 +385,7 @@ std::vector tdm_ripper::get_channel(int channelid) { assert( channelid > 0 && channelid <= num_channels_ && "please provide valid channel id" ); - return convert_channel(byteoffset_[channelid-1],length_[channelid-1],type_[channelid-1]); - // return convert_channel(byteoffset_[channelid-1],length_[channelid-1], - // datatypes_[type_[channelid-1]]/CHAR_BIT); + return convert_channel(channel_ext_[channelid-1]); } void tdm_ripper::print_channel(int channelid, const char* filename, int width) diff --git a/lib/tdm_ripper.hpp b/lib/tdm_ripper.hpp index 5f5acc4..94e11bf 100644 --- a/lib/tdm_ripper.hpp +++ b/lib/tdm_ripper.hpp @@ -10,6 +10,8 @@ #include #include #include +#include + #include "../pugixml/pugixml.hpp" class tdm_ripper @@ -23,14 +25,19 @@ class tdm_ripper // number/names/ids of channels, channelgroups and channels's assignment to groups int num_channels_, num_groups_; - std::vector channel_id_, group_id_, channel_name_, group_name_; + std::vector channel_id_, inc_id_, group_id_, channel_name_, group_name_; std::vector num_channels_group_; std::vector channels_group_; + std::vector channel_ext_; + + // minimum/maximum value in particular channel (is provided in .tdm file as float) + std::vector> minmax_; // byteoffset, length and datatype of channels std::vector byteoffset_; std::vector length_; std::vector type_; + std::vector external_id_; // mapping of NI datatype to size (in bytes) of type std::map datatypes_; @@ -67,6 +74,15 @@ public: return num_occs; } + // obtain substring of 'entirestr' in between starting and stopping delimiter + std::string get_str_between(std::string entirestr, std::string startlim, std::string stoplim) + { + std::size_t apos = entirestr.find(startlim); + std::size_t bpos = entirestr.find_last_of(stoplim); + assert( apos != std::string::npos && bpos != std::string::npos ); + return entirestr.substr(apos+startlim.length(),bpos-(apos+startlim.length())); + } + // provide number of channels and group const int& num_channels() { @@ -103,7 +119,7 @@ public: // convert entire channel, i.e. expert of .tdx binary file // std::vector convert_channel(int byteoffset, int length, int typesize); - std::vector convert_channel(int byteoffset, int length, std::string type); + std::vector convert_channel(int channelid); std::vector get_channel(int channelid); diff --git a/main.cpp b/main.cpp index 7086acb..02e578d 100644 --- a/main.cpp +++ b/main.cpp @@ -12,8 +12,16 @@ int main(int argc, char* argv[]) ripper.list_datatypes(); + // int sn = -76476; + // std::vector bych = ripper.convert_int(sn); + // std::cout<<"length of vector "< channA = ripper.get_channel(1); - for ( auto el: channA ) std::cout< channA = ripper.get_channel(1); + // for ( auto el: channA ) std::cout<