correct id channel assignment

This commit is contained in:
Mario Fink 2019-04-30 13:18:27 +02:00
parent a4a8aa91c2
commit afe7331feb
3 changed files with 104 additions and 23 deletions

View File

@ -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<double,double> 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<<locol<<" "<<locolval<<" "<<locolvalext<<"\n";
// save external id of channel and get corresponding channel index
inc_id_.push_back(locolvalext);
int extid = 0;
for ( int i = 0; i < (int)external_id_.size(); i++ )
{
if ( external_id_[i].compare(locolvalext) == 0 ) extid = i+1;
}
channel_ext_.push_back(extid);
}
}
@ -131,6 +172,7 @@ void tdm_ripper::list_channels(std::ostream& gout, int width, int maxshow)
{
gout<<std::setw(width)<<"index";
gout<<std::setw(width)<<"id";
gout<<std::setw(width)<<"inc_id";
gout<<std::setw(2*width)<<"name";
gout<<std::setw(width)<<"offset";
gout<<std::setw(width)<<"length";
@ -139,22 +181,27 @@ void tdm_ripper::list_channels(std::ostream& gout, int width, int maxshow)
gout<<std::setw(width)<<"group id";
gout<<std::setw(width)<<"group name";
gout<<std::setw(width)<<"num channels";
gout<<std::setw(width)<<"minimum";
gout<<std::setw(width)<<"maximum";
gout<<"\n";
gout<<std::setfill('-')<<std::setw(11*width+1)<<"\n";
gout<<std::setfill('-')<<std::setw(14*width+1)<<"\n";
gout<<std::setfill(' ');
for ( int i = 0; i < num_channels_ && i < maxshow; i++ )
{
gout<<std::setw(width)<<i+1;
gout<<std::setw(width)<<channel_id_[i];
gout<<std::setw(width)<<inc_id_[i];
gout<<std::setw(2*width)<<channel_name_[i];
gout<<std::setw(width)<<byteoffset_[i];
gout<<std::setw(width)<<length_[i];
gout<<std::setw(width)<<type_[i];
gout<<std::setw(width)<<byteoffset_[channel_ext_[i]-1];
gout<<std::setw(width)<<length_[channel_ext_[i]-1];
gout<<std::setw(width)<<type_[channel_ext_[i]-1];
gout<<std::setw(width)<<channels_group_[i];
gout<<std::setw(width)<<group_id_[channels_group_[i]-1];
gout<<std::setw(width)<<group_name_[channels_group_[i]-1];
gout<<std::setw(width)<<num_channels_group_[channels_group_[i]-1];
gout<<std::setw(width)<<minmax_[i].first;
gout<<std::setw(width)<<minmax_[i].second;
gout<<"\n";
}
gout<<"\n\n";
@ -165,6 +212,7 @@ void tdm_ripper::list_channels(std::ostream& gout, int width, int maxshow)
{
gout<<std::setw(width)<<i+1;
gout<<std::setw(width)<<channel_id_[i];
gout<<std::setw(width)<<inc_id_[i];
gout<<std::setw(2*width)<<channel_name_[i];
gout<<std::setw(width)<<byteoffset_[i];
gout<<std::setw(width)<<length_[i];
@ -173,6 +221,8 @@ void tdm_ripper::list_channels(std::ostream& gout, int width, int maxshow)
gout<<std::setw(width)<<group_id_[channels_group_[i]-1];
gout<<std::setw(width)<<group_name_[channels_group_[i]-1];
gout<<std::setw(width)<<num_channels_group_[channels_group_[i]-1];
gout<<std::setw(width)<<minmax_[i].first;
gout<<std::setw(width)<<minmax_[i].second;
gout<<"\n";
}
gout<<"\n\n";
@ -305,19 +355,27 @@ double tdm_ripper::convert_double(std::vector<unsigned char> bych)
return df;
}
std::vector<double> tdm_ripper::convert_channel(int byteoffset, int length, std::string type)
std::vector<double> tdm_ripper::convert_channel(int channelid)
{
std::vector<double> 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<double> chann(length);
for ( int i = 0; i < length; i++ )
{
std::vector<unsigned char> 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<<chann[i]<<" "<<minmax_[channelid-1].first<<" "<<minmax_[channelid-1].second<<"\n";
// assert( chann[i] >= minmax_[channelid-1].first && chann[i] <= minmax_[channelid-1].second );
}
return chann;
@ -327,9 +385,7 @@ std::vector<double> 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)

View File

@ -10,6 +10,8 @@
#include <stdlib.h>
#include <assert.h>
#include <map>
#include <numeric>
#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<std::string> channel_id_, group_id_, channel_name_, group_name_;
std::vector<std::string> channel_id_, inc_id_, group_id_, channel_name_, group_name_;
std::vector<int> num_channels_group_;
std::vector<int> channels_group_;
std::vector<int> channel_ext_;
// minimum/maximum value in particular channel (is provided in .tdm file as float)
std::vector<std::pair<double,double>> minmax_;
// byteoffset, length and datatype of channels
std::vector<int> byteoffset_;
std::vector<int> length_;
std::vector<std::string> type_;
std::vector<std::string> external_id_;
// mapping of NI datatype to size (in bytes) of type
std::map<std::string, int> 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<double> convert_channel(int byteoffset, int length, int typesize);
std::vector<double> convert_channel(int byteoffset, int length, std::string type);
std::vector<double> convert_channel(int channelid);
std::vector<double> get_channel(int channelid);

View File

@ -12,8 +12,16 @@ int main(int argc, char* argv[])
ripper.list_datatypes();
// int sn = -76476;
// std::vector<unsigned char> bych = ripper.convert_int(sn);
// std::cout<<"length of vector "<<bych.size()<<"\n\n";
// for ( auto c: bych) std::cout<<(int)c<<" ";
// std::cout<<"\n\n";
//
// std::cout<<ripper.convert_int(bych)<<"\n\n";
ripper.list_channels();
std::ofstream fout("list_of_channels.dat");
std::ofstream fout("data/list_of_channels.dat");
ripper.list_channels(fout);
fout.close();
// ripper.show_structure();
@ -21,13 +29,14 @@ int main(int argc, char* argv[])
std::cout<<"number of channels "<<ripper.num_channels()<<"\n\n";
std::cout<<"number of groups "<<ripper.num_groups()<<"\n\n";
std::vector<double> channA = ripper.get_channel(1);
for ( auto el: channA ) std::cout<<el<<"\n";
std::cout<<"\n\n";
// std::vector<double> channA = ripper.get_channel(1);
// for ( auto el: channA ) std::cout<<el<<"\n";
// std::cout<<"\n\n";
for ( int i = 0; i < 12; i++ )
for ( int i = 0; i < ripper.num_channels(); i++ )
{
ripper.print_channel(i+1,("channel_"+std::to_string(i+1)+".dat").c_str());
ripper.print_channel(i+1,("data/channel_"+std::to_string(i+1)+"_"
+ripper.channel_name(i+1)+".dat").c_str());
}
return 0;