From 7e373be49e856055b04b72d4082a1d6333e2ebfe Mon Sep 17 00:00:00 2001 From: Mario Fink Date: Wed, 20 Jan 2021 19:55:03 +0100 Subject: [PATCH] tdm_reaper: templateconvert_data_to_type --- Dockerfile | 4 +- lib/tdm_datamodel.hpp | 3 +- lib/tdm_reaper.cpp | 117 ++++++++++++++++++++++++++++++++++++++---- lib/tdm_reaper.hpp | 19 ++++++- src/main.cpp | 16 ++++-- 5 files changed, 138 insertions(+), 21 deletions(-) diff --git a/Dockerfile b/Dockerfile index 00a41b1..9ee403b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,8 +10,6 @@ RUN g++ -v COPY ./ /tdm_ripper/ -RUN cd /tdm_ripper && ls -lh && make install && ls -lh /usr/local/bin/tdmripper +RUN cd /tdm_ripper && ls -lh && make install && ls -lh /usr/local/bin/tdmreaper CMD ["sleep","inifity"] - - diff --git a/lib/tdm_datamodel.hpp b/lib/tdm_datamodel.hpp index 09c0f7a..cc3503a 100644 --- a/lib/tdm_datamodel.hpp +++ b/lib/tdm_datamodel.hpp @@ -317,7 +317,8 @@ struct localcolumn { // TODO // <process_channels(showlog); this->process_submatrices(showlog); this->process_localcolumns(showlog); + + // open .tdx and stream all binary data into buffer + try { + std::ifstream fin(tdxfile_.c_str(),std::ifstream::binary); + // if ( !fin.good() ) std::cerr<<"failed to open .tdx-file\n"; + + std::vector tdxbuf((std::istreambuf_iterator(fin)), + (std::istreambuf_iterator())); + tdxbuffer_ = tdxbuf; + + if ( showlog ) std::cout<<"size of .tdx buffer (bytes): "<extract_ids(channel.child_value("local_columns")); @@ -265,7 +283,7 @@ void tdm_reaper::process_submatrices(bool showlog) } else { - throw std::runtime_error("submatrix with out/multiple measurement id(s)"); + throw std::logic_error("submatrix with out/multiple measurement id(s)"); } submat.local_columns_ = this->extract_ids(subm.child_value("local_columns")); std::string numrows = subm.child_value("number_of_rows"); @@ -304,7 +322,7 @@ void tdm_reaper::process_localcolumns(bool showlog) } else { - throw std::runtime_error("localcolumn with out/multiple measurement quantity id(s)"); + throw std::logic_error("localcolumn with out/multiple measurement quantity id(s)"); } std::vector sm = this->extract_ids(loccol.child_value("submatrix")); if ( sm.size() == 1 ) @@ -313,7 +331,7 @@ void tdm_reaper::process_localcolumns(bool showlog) } else { - throw std::runtime_error("localcolumn with out/multiple submatrix id(s)"); + throw std::logic_error("localcolumn with out/multiple submatrix id(s)"); } std::string lcmin = loccol.child_value("minimum"); lcmin = lcmin.empty() ? std::string("0.0") : lcmin; @@ -332,7 +350,36 @@ void tdm_reaper::process_localcolumns(bool showlog) } else { - throw std::runtime_error("localcolumn with out/multiple values id(s)"); + throw std::logic_error("localcolumn with out/multiple values id(s)"); + } + + // add external id referring to block in + { + // relying on fully initialized "tdmchannels_" !!) + if ( tdmchannels_.size() == 0 ) throw std::logic_error("tdmchannels_ not initialized"); + + // determine "channel_datatype_" and map it to its sequence type + std::string dt = tdmchannels_.at(locc.measurement_quantity_).datatype_; + std::string sequence_type; + for( auto itd = std::begin(tdm_datatypes); itd != std::end(tdm_datatypes); ++itd) + { + if ( dt == itd->channel_datatype_ ) sequence_type = itd->value_sequence_; + } + + for ( pugi::xml_node seq = tdmdata.child(sequence_type.c_str()); seq; + seq = seq.next_sibling(sequence_type.c_str()) ) + { + if ( seq.attribute("id").value() == locc.values_ ) + { + locc.external_id_ = seq.child("values").attribute("external").value(); + } + } + + if ( locc.external_id_.empty() ) + { + throw std::logic_error( std::string("no external id found for ") + + sequence_type + std::string(" with ") + locc.values_ ); + } } // add localcolumn to map @@ -348,23 +395,71 @@ void tdm_reaper::process_localcolumns(bool showlog) std::vector tdm_reaper::get_channel(std::string &id) { - // declare vector of channel data - std::vector chn; - // check for existence of required channel id (=key) if ( tdmchannels_.count(id) == 1 ) { + // retrieve full channel info tdm_channel chn = tdmchannels_.at(id); - std::cout< blkbuff( tdxbuffer_.begin()+blk.byte_offset_, + tdxbuffer_.begin()+blk.byte_offset_ + + blk.length_*sizeof(double) ); + + std::vector datvec(blk.length_); + this->convert_data_to_type(blkbuff,datvec); + + return datvec; } else { throw std::invalid_argument(std::string("channel id does not exist: ") + id); } +} - return chn; +void tdm_reaper::print_channel(std::string &id, const char* filename) +{ + std::ofstream fou(filename); + + std::vector chn = this->get_channel(id); + + for ( auto el: chn ) fou< +void tdm_reaper::convert_data_to_type(std::vector &buffer, + std::vector &channel) +{ + // check number of elements of type "datatype" in buffer + if ( buffer.size() != channel.size()*sizeof(datatype) ) + { + throw std::runtime_error("size mismatch between buffer 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)buffer[i*sizeof(datatype)+j]; + } + + // save number in channel + channel[i] = df; + } } // -------------------------------------------------------------------------- // diff --git a/lib/tdm_reaper.hpp b/lib/tdm_reaper.hpp index 8a22b8b..707572e 100644 --- a/lib/tdm_reaper.hpp +++ b/lib/tdm_reaper.hpp @@ -55,8 +55,8 @@ class tdm_reaper std::map submatrices_; std::map localcolumns_; - // // binary data container - // std::vector tdxbuf_; + // binary data container + std::vector tdxbuffer_; // extract list of identifiers from e.g. "#xpointer(id("usi12") id("usi13"))" std::vector extract_ids(std::string idstring) @@ -140,6 +140,12 @@ public: void process_submatrices(bool showlog); void process_localcolumns(bool showlog); + // get root element + tdm_root get_root() + { + return tdmroot_; + } + // get list of channelgroup ids std::vector get_channelgroup_ids() { @@ -163,6 +169,15 @@ public: // extract channel by id // (TODO introduce template T to reference specific datatype instead of double in general) std::vector get_channel(std::string &id); + + void print_channel(std::string &id, const char* filename); + +private: + + template + void convert_data_to_type(std::vector &buffer, + std::vector &channel); + }; #endif diff --git a/src/main.cpp b/src/main.cpp index b707c94..fcffd93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -188,16 +188,24 @@ int main(int argc, char* argv[]) // check available datatypes on machine jack.check_local_datatypes(); + // show some meta data of the dataset + std::cout<<"\n"< chgrids = jack.get_channelgroup_ids(); for ( auto el: chgrids ) std::cout< chids = jack.get_channel_ids(); for ( auto el: chids ) std::cout< chi = jack.get_channel(id); + // std::string id("usi15"); + // std::vector chi = jack.get_channel(id); + + for ( auto el: chids ) + { + std::string chfile = std::string("channel_") +el +std::string(".csv"); + jack.print_channel(el,chfile.c_str()); + } // print list of groups or channels to stdout // if ( listgroups ) jack.list_groups();