diff --git a/lib/tdm_reaper.cpp b/lib/tdm_reaper.cpp index 778b017..251335d 100644 --- a/lib/tdm_reaper.cpp +++ b/lib/tdm_reaper.cpp @@ -4,10 +4,37 @@ // -------------------------------------------------------------------------- // -tdm_ripper::tdm_ripper(std::string tdmfile, std::string tdxfile, - bool suppress_status, bool neglect_empty_groups) +tdm_ripper::tdm_ripper(std::string tdmfile, std::string tdxfile, bool showlog): + tdmfile_(tdmfile), tdxfile_(tdxfile) { + // 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 { + xml_result_ = xml_doc_.load_file(tdmfile_.c_str()); + + if ( !showlog ) + { + std::cout<<"loading and parsing file: "< #include #include +#include +#include +#include #include "pugixml.hpp" // -------------------------------------------------------------------------- // // define datatypes +// https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_header_tdx_data/ + +enum class tdm_datatype { + eInt16Usi, + eInt32Usi, + // + eUInt8Usi, + eUInt16Usi, + eUInt32Usi, + // + eFloat32Usi, + eFloat64Usi, + // + eStringUsi +}; + struct datatype { std::string name_; std::string channel_datatype_; int numeric_; std::string value_sequence_; int size_; - std::string description; + std::string description_; + + std::string get_info() + { + std::stringstream ss; + ss<<"name: "< tdm_datatypes = { - {"eInt16Usi",{"eInt16Usi","DT_SHORT",2,"short_sequence",2,"signed 16 bit integer"}} + + {"eInt16Usi",{"eInt16Usi","DT_SHORT",2,"short_sequence",2,"signed 16 bit integer"}}, + {"eInt32Usi",{"eInt32Usi","DT_LONG",6,"long_sequence",4,"signed 32 bit integer"}}, + + {"eUInt8Usi",{"eUInt8Usi","DT_BYTE",5,"byte_sequence",1,"unsigned 8 bit integer"}}, + {"eUInt16Usi",{"eUInt16Usi","DT_SHORT",2,"short_sequence",2,"unsigned 16 bit integer"}}, + {"eUInt32Usi",{"eUInt32Usi","DT_LONG",6,"long_sequence",4,"unsigned 32 bit integer"}}, + + {"eFloat32Usi",{"eFloat32Usi","DT_FLOAT",3,"float_sequence",4,"32 bit float"}}, + {"eFloat64Usi",{"eFloat64Usi","DT_DOUBLE",7,"double_sequence",8,"64 bit double"}}, + + {"eStringUsi",{"eStringUsi","DT_STRING",1,"string_sequence",0,"text"}} + +}; + +// -------------------------------------------------------------------------- // +// tdm root, tdm group and tdm channel, etc. + +// for reference of the tdm data model, see +// https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_headerfile/ +// https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_datamodel/ + +struct tdm_root { + std::string name_; + std::string description_; + std::string title_; + std::string author_; + std::string timestamp_; + // std::chrono::time_point timestamp_; // from string 2008-05-06T17:20:12.65074539184570313 + + // std::stringstream ss; + // ss<<"2008-05-06T17:20:12.65074539184570313"; + // std::cout< channels_; // referenced by id +}; + +enum class wf_time_pref_type { + absolute, + relative +}; + +// additional elements for wave form channels (encoded as attributes in +// of ) +// https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_tdxdata_waveform/ +struct waveform_channel { + std::string wf_xname_; + std::string wf_xunit_string_; + std::string wf_start_time_; + double wf_start_offset_; + double wf_increment_; + unsigned long wf_samples_; + wf_time_pref_type wf_time_pref; +}; + +// https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_metadata_channel/ +struct tdm_channel { + unsigned long int id_; + std::string name_; + std::string description_; + std::string unit_string_; + tdm_datatype datatype_; + double minimum_, maximum_; + unsigned long int groupd_id_; + waveform_channel wf_channel_; +}; + +// https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_tdxdata_submatrix/ +struct tdm_submatrix { + std::string name_; + unsigned long int number_of_rows_; + unsigned long int measurement_id_; + unsigned long int local_column_id_; +}; + +enum class representation { + explicit_, // !! explicit is C++ keyword!! + implicit_linear_, // datatype is always DT_DOUBLE, no for implicit_linear_!! + raw_linear_ // datatype is always DT_DOUBLE +}; + +// https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_tdxdata_localcolumn/ +struct localcolumn { + std::string name_; + unsigned long int global_flag_; + unsigned long int independent_; + double minimum_, maximum_; + representation sequence_representation_; + std::vector generation_parameters_; // { offset, factor } + unsigned long int measurement_quantity_id_; + unsigned long int submatrix_id_; + unsigned long int values_id_; }; // -------------------------------------------------------------------------- // @@ -47,6 +191,9 @@ class tdm_ripper // endianness (true = little, false = big) bool endianness_, machine_endianness_; + // tdm root + tdm_root tdmroot_; + // number/names/ids of channels, channelgroups and channels's assignment to groups int num_channels_, num_groups_; std::vector channel_id_, inc_id_, units_, channel_name_; @@ -88,8 +235,7 @@ class tdm_ripper public: - tdm_ripper(std::string tdmfile, std::string tdxfile = "", - bool suppress_status = true, bool neglect_empty_groups = true); + tdm_ripper(std::string tdmfile, std::string tdxfile = std::string(""), bool showlog = false); void parse_structure();