// -------------------------------------------------------------------------- // #include "tdm_reaper.hpp" // -------------------------------------------------------------------------- // tdm_reaper::tdm_reaper() { } tdm_reaper::tdm_reaper(std::string tdmfile, std::string tdxfile, bool showlog): tdmfile_(tdmfile), tdxfile_(tdxfile) { // start processing tdm data model this->process_tdm(showlog); } void tdm_reaper::submit_files(std::string tdmfile, std::string tdxfile, bool showlog) { // save files tdmfile_ = tdmfile; tdxfile_ = tdxfile; // start processing tdm data model this->process_tdm(showlog); } void tdm_reaper::process_tdm(bool showlog) { // check both tdm, tdx files std::filesystem::path ptdm(tdmfile_), ptdx(tdxfile_); if ( !std::filesystem::exists(ptdm) ) { throw std::runtime_error(std::string("*.tdm file ") + tdmfile_ + " does not exist!"); } if ( !std::filesystem::exists(ptdx) ) { throw std::runtime_error(std::string("*.tdx file ") + tdxfile_ + " does not exist!"); } // set up xml-parser and load tdm-file try { // load XML document from stream std::ifstream fin(tdmfile_.c_str()); xml_result_ = xml_doc_.load(fin); fin.close(); // xml_result_ = xml_doc_.load_file(tdmfile_.c_str()); if ( showlog ) { std::cout<<"\nloading "<process_include(showlog); this->process_root(showlog); this->process_channelgroups(showlog); this->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): "<(tdxblock.id_,tdxblock)); if ( showlog ) std::cout<extract_ids(tdmdataroot.child_value("channelgroups")); if ( showlog ) std::cout< pugi::xml_node tdmdata = xml_doc_.child("usi:tdm").child("usi:data"); // find all its elements for ( pugi::xml_node group = tdmdata.child("tdm_channelgroup"); group; group = group.next_sibling("tdm_channelgroup") ) { // declare new group tdm_channelgroup tdmchannelgroup; // extract properties tdmchannelgroup.id_ = group.attribute("id").value(); tdmchannelgroup.name_ = group.child_value("name"); tdmchannelgroup.description_ = group.child_value("description"); std::vector gr = this->extract_ids(group.child_value("root")); if ( gr.size() == 1 ) { tdmchannelgroup.root_ = gr.at(0); } else { throw std::runtime_error("tdm_channelgroup with out/multiple root id(s)"); } tdmchannelgroup.channels_ = this->extract_ids(group.child_value("channels")); tdmchannelgroup.submatrices_ = this->extract_ids(group.child_value("submatrices")); // add channelgroup to map tdmchannelgroups_.insert( std::pair( tdmchannelgroup.id_,tdmchannelgroup) ); if ( showlog ) std::cout< pugi::xml_node tdmdata = xml_doc_.child("usi:tdm").child("usi:data"); // find all its elements for ( pugi::xml_node channel = tdmdata.child("tdm_channel"); channel; channel = channel.next_sibling("tdm_channel") ) { // declare new channel tdm_channel tdmchannel; // extract properties tdmchannel.id_ = channel.attribute("id").value(); tdmchannel.name_ = channel.child_value("name"); tdmchannel.description_ = channel.child_value("description"); tdmchannel.unit_string_ = channel.child_value("unit_string"); tdmchannel.datatype_ = channel.child_value("datatype"); std::string chmin = channel.child_value("minimum"); chmin = chmin.empty() ? std::string("0.0") : chmin; tdmchannel.minimum_ = std::stod(chmin); std::string chmax = channel.child_value("maximum"); chmax = chmax.empty() ? std::string("0.0") : chmax; tdmchannel.maximum_ = std::stod(chmax); std::vector cg = this->extract_ids(channel.child_value("group")); if ( cg.size() == 1 ) { tdmchannel.group_ = cg.at(0); } else { throw std::logic_error("tdm_channel with out/multiple group id(s)"); } tdmchannel.local_columns_ = this->extract_ids(channel.child_value("local_columns")); // add channel to map tdmchannels_.insert( std::pair(tdmchannel.id_,tdmchannel) ); if ( showlog ) std::cout< pugi::xml_node tdmdata = xml_doc_.child("usi:tdm").child("usi:data"); // find all its elements for ( pugi::xml_node subm = tdmdata.child("submatrix"); subm; subm = subm.next_sibling("submatrix") ) { // declare new submatrix submatrix submat; // extract properties submat.id_ = subm.attribute("id").value(); submat.name_ = subm.child_value("name"); submat.description_ = subm.child_value("description"); std::vector mid = this->extract_ids(subm.child_value("measurement")); if ( mid.size() == 1 ) { submat.measurement_ = mid.at(0); } else { 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"); numrows = numrows.empty() ? std::string("0") : numrows; submat.number_of_rows_ = std::stoul(numrows); // add submatrix to map submatrices_.insert( std::pair(submat.id_,submat) ); if ( showlog ) std::cout< pugi::xml_node tdmdata = xml_doc_.child("usi:tdm").child("usi:data"); // find all its elements for ( pugi::xml_node loccol = tdmdata.child("localcolumn"); loccol; loccol = loccol.next_sibling("localcolumn") ) { // declare new localcolumn localcolumn locc; // extract properties locc.id_ = loccol.attribute("id").value(); locc.name_ = loccol.child_value("name"); locc.description_ = loccol.child_value("description"); std::vector mq = this->extract_ids(loccol.child_value("measurement_quantity")); if ( mq.size() == 1 ) { locc.measurement_quantity_ = mq.at(0); } else { 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 ) { locc.submatrix_ = sm.at(0); } else { 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; locc.minimum_ = std::stod(lcmin); std::string lcmax = loccol.child_value("maximum"); lcmax = lcmax.empty() ? std::string("0.0") : lcmax; locc.maximum_ = std::stod(lcmax); locc.sequence_representation_ = loccol.child_value("sequence_representation"); // TODO // .... loccal.child_value("generation_parameters"); std::vector vl = this->extract_ids(loccol.child_value("values")); if ( vl.size() == 1 ) { locc.values_ = vl.at(0); } else { 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 localcolumns_.insert( std::pair(locc.id_,locc) ); if ( showlog ) std::cout<::iterator it=tdmchannels_.begin(); it!=tdmchannels_.end(); ++it) { // get corresponding group tdm_channelgroup grp = tdmchannelgroups_.at(it->second.group_); channels_summary += grp.get_info(chformatter); // ...and actual channel channels_summary += it->second.get_info(chformatter); channels_summary += std::string("\n"); } return channels_summary; } // -------------------------------------------------------------------------- // std::vector tdm_reaper::get_channel(std::string &id) { // check for existence of required channel id (=key) if ( tdmchannels_.count(id) == 1 ) { // retrieve full channel info tdm_channel chn = tdmchannels_.at(id); // extract (first) "localcolumn" for channel localcolumn loccol = localcolumns_.at(chn.local_columns_[0]); // use "values" id to map to external block block blk = tdx_blocks_.at(loccol.external_id_); // declare buffer covering the required range of "tdxbuffer_" std::vector 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); } } 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; } } // -------------------------------------------------------------------------- //