// ------------------------------------------------------------------------- // /* 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/ */ #ifndef TDM_DATAMODEL #define TDM_DATAMODEL #include #include #include #include #include // -------------------------------------------------------------------------- // // format output of info strings for terminal and file table class format { private: unsigned int width_; bool tabular_; bool header_; char sep_; std::vector> columns_; public: format(int width = 25, bool tabular = false, bool header = false, char sep = ' '): width_(width), tabular_(tabular), header_(header), sep_(sep) { } void set_width(int width) { width_ = width; } void set_tabular(bool tabular) { tabular_ = tabular; } void set_header(bool header) { header_ = header; } void set_sep(char sep) { sep_ = sep; } void set_columns(std::vector> columns) { columns_ = columns; } std::string get_info() { std::stringstream ss; for ( std::vector>::iterator it = columns_.begin(); it != columns_.end(); ++it ) { if ( tabular_ ) { // header or body of table std::string entry = header_? it->first : it->second; // make broad aligned columns for human reader if ( sep_ == ' ' ) { entry = entry.size() > width_-2 ? entry.substr(0,width_-2) : entry; // if ( it == columns_.begin() && !header_ ) ss<<" "; ss<first+std::string(":"))<second<<"\n"; } } return ss.str(); } }; // define default formatter static format defformat(25,false,false,','); // join a list of strings static std::string join_strings(std::vector &thestring, const char* sep = " ") { std::string joined; for ( std::vector::iterator it = thestring.begin(); it != thestring.end(); ++it ) { joined += std::next(it,1) != thestring.end() ? ( *it + std::string(sep) ) : *it; } return joined; } // -------------------------------------------------------------------------- // // tdm datatypes // https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_header_tdx_data/ // define mapping of C++ supported datatypes to tdm datatypes // define mapping of locally supported datatypes to tdm datatypes // typedef short int eInt16Usi; // typedef int eInt32Usi; // typedef unsigned char eUInt8Usi; // typedef unsigned short int eUInt16Usi; // typedef unsigned int eUInt32Usi; // typedef float eFloat32Usi; // typedef double eFloat64Usi; // enum class tdmdatatype { // eInt16Usi, // eInt32Usi, // eUInt8Usi, // eUInt16Usi, // eUInt32Usi, // eFloat32Usi, // eFloat64Usi // }; // base class for all tdm datatypes class tdmdatatype { protected: short int sint16_; int sint32_; unsigned char uint8_; unsigned short int uint16_; unsigned int uint32_; float float32_; double float64_; public: tdmdatatype(): sint16_(0), sint32_(0), uint8_(0), uint16_(0), uint32_(0), float32_(0.0), float64_(0.0) {}; friend std::ostream& operator<<(std::ostream& out, const tdmdatatype& num) { return num.print(out); } virtual std::ostream& print(std::ostream& out) const { out<<"tdmdatatype"; return out; } }; class eInt16Usi: public tdmdatatype { public: eInt16Usi() { } eInt16Usi(short int num) { sint16_ = num; } // eInt16Usi& operator=(const eInt16Usi &num) // { // // self-assignment check // if ( this != &num) // { // this->sint16_ = num.sint16_; // } // return *this; // } friend std::ostream& operator<<(std::ostream& out, const eInt16Usi& num) { return num.print(out); } std::ostream& print(std::ostream& out) const override { out< tdm_datatypes = { {"eInt16Usi","DT_SHORT",2,"short_sequence",2,"signed 16 bit integer"}, {"eInt32Usi","DT_LONG",6,"long_sequence",4,"signed 32 bit integer"}, {"eUInt8Usi","DT_BYTE",5,"byte_sequence",1,"unsigned 8 bit integer"}, {"eUInt16Usi","DT_SHORT",2,"short_sequence",2,"unsigned 16 bit integer"}, {"eUInt32Usi","DT_LONG",6,"long_sequence",4,"unsigned 32 bit integer"}, {"eFloat32Usi","DT_FLOAT",3,"float_sequence",4,"32 bit float"}, {"eFloat64Usi","DT_DOUBLE",7,"double_sequence",8,"64 bit double"}, {"eStringUsi","DT_STRING",1,"string_sequence",0,"text"} }; // -------------------------------------------------------------------------- // // block of data struct block { std::string id_; unsigned long int byte_offset_; unsigned long int length_; unsigned long int block_offset_, block_size_; std::string value_type_; block () { id_ = std::string(""); byte_offset_ = 0; length_ = 0; block_offset_ = 0; block_size_ = 0; value_type_ = std::string(""); } const std::string get_info() { return get_info(defformat); } const std::string get_info(format& formatter) { formatter.set_columns({ std::make_pair("block-id",id_), std::make_pair("byteOffset",std::to_string(byte_offset_)), std::make_pair("length",std::to_string(length_)), std::make_pair("blockOffset",std::to_string(block_offset_)), std::make_pair("blockSize",std::to_string(block_size_)), std::make_pair("valueType",value_type_) }); return formatter.get_info(); } }; // -------------------------------------------------------------------------- // // tdm_root struct tdm_root { std::string id_; std::string name_; std::string description_; std::string title_; std::string author_; std::string timestamp_; // std::chrono::time_point timepoint_; // from string 2008-05-06T17:20:12.65074539184570313 // std::stringstream ss; // ss<<"2008-05-06T17:20:12.65074539184570313"; // std::cout< channelgroups_; const std::string get_info() { return get_info(defformat); } const std::string get_info(format& formatter) { formatter.set_columns({ std::make_pair("root-id",id_), std::make_pair("name",name_), std::make_pair("description",description_), std::make_pair("title",title_), std::make_pair("author",author_), std::make_pair("timestamp",timestamp_), std::make_pair("channelgroups",join_strings(channelgroups_)) }); return formatter.get_info(); } }; // -------------------------------------------------------------------------- // // tdm_channelgroup // https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_metadata_chngroup/ struct tdm_channelgroup { std::string id_; std::string name_; std::string description_; std::string root_; std::vector channels_; // referenced by id std::vector submatrices_; const std::string get_info() { return get_info(defformat); } const std::string get_info(format& formatter) { formatter.set_columns({ std::make_pair("group-id",id_), std::make_pair("name",name_), std::make_pair("description",description_), std::make_pair("root",root_), std::make_pair("channels",join_strings(channels_)), std::make_pair("submatrices",join_strings(submatrices_)) }); return formatter.get_info(); } }; // -------------------------------------------------------------------------- // // tdm_channel // https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_metadata_channel/ // waveform channel type 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; }; struct tdm_channel { std::string id_; std::string name_; std::string description_; std::string unit_string_; std::string datatype_; double minimum_, maximum_; std::string group_; std::vector local_columns_; // TODO waveform_channel wf_channel_; const std::string get_info() { return get_info(defformat); } const std::string get_info(format& formatter) { formatter.set_columns({ std::make_pair("channel-id",id_), std::make_pair("name",name_), std::make_pair("description",description_), std::make_pair("unit_string",unit_string_), std::make_pair("datatype",datatype_), std::make_pair("minimum",std::to_string(minimum_)), std::make_pair("maximum",std::to_string(maximum_)), std::make_pair("group",group_), std::make_pair("local_columns",join_strings(local_columns_)) }); return formatter.get_info(); } }; // -------------------------------------------------------------------------- // // submatrix // https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_tdxdata_submatrix/ struct submatrix { std::string id_; std::string name_; std::string description_; std::string measurement_; // -> tdm_channelgroup id std::vector local_columns_; // -> list of type "localcolumn" unsigned long int number_of_rows_; // -> number of values in channels const std::string get_info() { return get_info(defformat); } const std::string get_info(format& formatter) { formatter.set_columns({ std::make_pair("submatrix-id",id_), std::make_pair("name",name_), std::make_pair("description",description_), std::make_pair("measurement",measurement_), std::make_pair("local_columns",join_strings(local_columns_)), std::make_pair("number_of_rows",std::to_string(number_of_rows_)) }); return formatter.get_info(); } }; // -------------------------------------------------------------------------- // // localcolumn 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 id_; std::string name_; std::string description_; std::string measurement_quantity_; // -> tdm_channel std::string submatrix_; unsigned long int global_flag_; unsigned long int independent_; double minimum_, maximum_; // representation sequence_representation_; std::string sequence_representation_; std::vector generation_parameters_; // { offset, factor } std::string values_; // -> refers to usi:data -> _sequence std::string external_id_; const std::string get_info() { return get_info(defformat); } const std::string get_info(format& formatter) { formatter.set_columns({ std::make_pair("localcolumn-id",id_), std::make_pair("name",name_), std::make_pair("description",description_), std::make_pair("measurement_quantity",measurement_quantity_), std::make_pair("submatrix_",submatrix_), std::make_pair("minimum",std::to_string(minimum_)), std::make_pair("maximum",std::to_string(maximum_)), std::make_pair("sequence_representation",sequence_representation_), std::make_pair("values",values_), std::make_pair("external",external_id_) }); return formatter.get_info(); } }; #endif // -------------------------------------------------------------------------- //