Compare commits

...

25 Commits

Author SHA1 Message Date
04d523d9be comply with PEP 625: lower case distribution filenames; bump version 2.1.3 2025-02-13 19:26:33 +01:00
48580caab0 github actions: on push tag only 2025-02-12 23:49:52 +01:00
32e36aae00 github actions: fix workflow with strategy.job-index; bump version 2.1.2 2025-02-12 23:46:04 +01:00
f531b0fe90 bump version 2.1.1 2025-02-12 00:06:47 +01:00
511b665643 Fix actions in /.github/workflows/ 2025-02-10 00:27:08 +01:00
5b6ca45f18 Fix bump actions in /.github/workflows: build binary distribution 2024-09-17 23:31:03 +02:00
3dd3cf1446 Fix bump actions in /.github/workflows: build binary distribution: fix comment whitespace 2024-09-17 23:27:47 +02:00
b91f273cb8 Fix bump actions in /.github/workflows: build source distribution 2024-09-17 23:18:01 +02:00
fe741b698c Fix bump actions in /.github/workflows 2024-09-13 11:02:26 +02:00
d53e057dca Bump * ubuntu from 20.04 to 24.04
* windows-2019 to windows-2022
     * actions/setup-python to v5
     * actions/checkout to v5        in /.github/workflows
2024-09-12 13:12:34 +02:00
6c1fd021c2 Bump actions/upload-artifact from 2 to 4 in /.github/workflows 2024-09-12 11:52:15 +02:00
Mario Fink
177f368fdf
Merge pull request #19 from RecordEvolution/dependabot/github_actions/dot-github/workflows/actions/download-artifact-4.1.7
Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows
2024-09-12 11:44:26 +02:00
dependabot[bot]
73ff748ff4
Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 4.1.7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v2...v4.1.7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-03 22:06:02 +00:00
193d9ac010 bump version 2.0.2 2024-06-12 17:22:48 +02:00
b4136c0b03 fix badges 2024-06-12 17:06:22 +02:00
Mario Fink
759c88dfb4 tdm_termite.hpp: remove unused bit/endian include in C++20, add python build files to gitignore 2021-10-21 15:12:13 +02:00
Mario Fink
dec58d4668 github action workflow pypi: add branch master for trigger 2021-10-21 15:05:14 +02:00
Mario Fink
e0e293c4d4 README: add github action workflow badge for building wheels, version 2.0.1 2021-10-21 15:00:10 +02:00
Mario Fink
050256763c * improve runtime detection of endianness
* support decoding of TDM/TDX data with endianness mismatch w.r.t.
  architecture => issue #16
* generate/provide bigEndian TDM/TDX example
2021-10-19 19:48:44 +02:00
Mario Fink
b005987531 * README.md: adjust python examples to renaming of module
* bump new major version 2.0.0
2021-10-19 17:17:54 +02:00
Mario Fink
f64b51c968 * tidy up and simplify python/cython/pypi setup and directory structure
* rename python modules with consistent nomenclature (breaking changes!)
2021-10-19 17:12:43 +02:00
cf2799b383 bump version 1.0.5 2021-09-22 17:31:47 +02:00
ef16fd3228 experimental support for DT_STRING datatype 2021-09-22 17:29:07 +02:00
337fbf9745 correction of exception message for multiple value-ids 2021-09-16 15:34:02 +02:00
4d0feb4716 bump version v1.0.4 2021-09-16 15:25:26 +02:00
29 changed files with 843 additions and 338 deletions

100
.github/workflows/pypi-deploy.yml vendored Normal file
View File

@ -0,0 +1,100 @@
name: CI Build Wheel
on:
push:
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
jobs:
build_setup:
name: Prepare environment for wheel builds
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v2
- name: Prepare wheel build
run: make -C python/ setup
- name: Store wheel configuration files
uses: actions/upload-artifact@v4.6.0
with:
name: wheel-config
path: python/
- name: Display files
run: ls -lR
build_wheels:
name: Build binary wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [build_setup]
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.1.2
- name: Get wheel configuration files
uses: actions/download-artifact@v4.1.7
with:
name: wheel-config
path: python/
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
working-directory: python/
- name: Store binary wheels
uses: actions/upload-artifact@v4.6.0
with:
name: binary-wheels-${{matrix.os}}-${{ strategy.job-index }}
path: python/wheelhouse/*.whl
build_sdist:
name: Build source distribution
runs-on: ubuntu-24.04
needs: [build_setup]
steps:
- uses: actions/checkout@v2
- name: Install cython
run: python -m pip install cython==0.29.24
- name: Get wheel configuration files
uses: actions/download-artifact@v4.1.7
with:
name: wheel-config
path: python/
- name: Build sdist
run: python setup.py sdist
working-directory: python/
- name: Store source wheels
uses: actions/upload-artifact@v4.6.0
with:
name: source-wheels
path: python/dist/*.tar.gz
- name: Display files
run: ls -lR
upload_pypi:
name: Upload wheels to PyPI
runs-on: ubuntu-24.04
needs: [build_wheels, build_sdist]
steps:
- name: Get source wheels
uses: actions/download-artifact@v4.1.7
with:
name: source-wheels
path: dist/
- name: Get binary wheels
uses: actions/download-artifact@v4.1.7
with:
path: dist/
pattern: binary-wheels-*
merge-multiple: true
- name: Display files
run: ls -lR
- uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.TDMTERMITE_GITHUB_WORKFLOW_PYPI_API_TOKEN }}

7
.gitignore vendored
View File

@ -23,3 +23,10 @@ pip/*.cpp
pip/*.pyx pip/*.pyx
pip/*.pxd pip/*.pxd
pip/LICENSE pip/LICENSE
python/3rdparty/
python/LICENSE
python/README.md
python/TDMtermite.cpp
python/lib/

View File

@ -1,9 +1,8 @@
[![Total alerts](https://img.shields.io/lgtm/alerts/g/RecordEvolution/TDMtermite.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/RecordEvolution/TDMtermite/alerts/)
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/RecordEvolution/TDMtermite.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/RecordEvolution/TDMtermite/context:cpp)
[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/RecordEvolution/TDMtermite.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/RecordEvolution/TDMtermite/context:python)
[![LICENSE](https://img.shields.io/github/license/RecordEvolution/TDMtermite)](https://img.shields.io/github/license/RecordEvolution/TDMtermite) [![LICENSE](https://img.shields.io/github/license/RecordEvolution/TDMtermite)](https://img.shields.io/github/license/RecordEvolution/TDMtermite)
[![STARS](https://img.shields.io/github/stars/RecordEvolution/TDMtermite)](https://img.shields.io/github/stars/RecordEvolution/TDMtermite) [![STARS](https://img.shields.io/github/stars/RecordEvolution/TDMtermite)](https://img.shields.io/github/stars/RecordEvolution/TDMtermite)
![CI Build Wheel](https://github.com/RecordEvolution/TDMtermite/actions/workflows/pypi-deploy.yml/badge.svg?branch=&event=push)
[![PYPI](https://img.shields.io/pypi/v/TDMtermite.svg)](https://pypi.org/project/tdmtermite/)
# TDMtermite # TDMtermite
@ -165,10 +164,10 @@ which makes the module available for import by `import tdm_termite` .
#### Installation with pip #### Installation with pip
The package is also available via the [Python Package Index](https://pypi.org) at The package is also available via the [Python Package Index](https://pypi.org) at
[TDMtermite](https://pypi.org/project/TDMtermite/). To install the latest version simply do [TDMtermite](https://pypi.org/project/tdmtermite/). To install the latest version simply do
```Shell ```Shell
python3 -m pip install TDMtermite python3 -m pip install tdmtermite
``` ```
##### Unix ##### Unix
@ -225,21 +224,21 @@ To be able to use the Python module _tdm_termite_, it first has to be built loca
or installed on the system. In the Python interpreter, simply do: or installed on the system. In the Python interpreter, simply do:
```Python ```Python
import tdm_termite import tdmtermite
``` ```
This will import the module. The TDM files are provided by creating an instance of This will import the module. The TDM files are provided by creating an instance of
the _tdm_termite_ class: the _tdmtermite_ class:
```Python ```Python
# create 'tdm_termite' instance object # create 'tdmtermite' instance object
try : try :
jack = tdm_termite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx') jack = tdmtermite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx')
except RuntimeError as e: except RuntimeError as e:
print("failed to load/decode TDM files: " + str(e)) print("failed to load/decode TDM files: " + str(e))
``` ```
After initializing the _tdm_termite_ object, it can be used to extract any of the After initializing the _tdmtermite_ object, it can be used to extract any of the
available data. For instance, to list the included channelgroups and channels: available data. For instance, to list the included channelgroups and channels:
```Python ```Python
@ -255,12 +254,12 @@ As a use case, we have a look at listing the ids of all channelgroups and printi
their data to separate files: their data to separate files:
```Python ```Python
import tdm_termite import tdmtermite
import re import re
# create 'tdm_termite' instance object # create 'tdmtermite' instance object
try : try :
jack = tdm_termite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx') jack = tdmtermite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx')
except RuntimeError as e : except RuntimeError as e :
print("failed to load/decode TDM files: " + str(e)) print("failed to load/decode TDM files: " + str(e))
@ -294,8 +293,8 @@ to simply extract all data of the TDM datatset and dump it to files in a given
(existing!) directory, do (existing!) directory, do
```Python ```Python
import tdm_termite import tdmtermite
jack = tdm_termite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx') jack = tdmtermite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx')
jack.write_all(b"./my_tdm_data_directory/") jack.write_all(b"./my_tdm_data_directory/")
``` ```

View File

@ -1 +0,0 @@
Cython==0.29.21

View File

@ -1,47 +0,0 @@
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import os
import sys
print("building on platform: "+sys.platform)
os.system("git tag > gittags.log")
with open ("gittags.log","r") as gt:
taglst = gt.readlines()
os.remove("gittags.log")
if len(taglst) > 0 :
version = taglst[-1].replace('\n','').replace('v','')
else:
version = 'unkown'
print("building version: "+version)
if sys.platform == "linux" or sys.platform == "darwin" :
cmpargs = ['-std=c++17','-Wno-unused-variable']
lnkargs = ['-std=c++17','-Wno-unused-variable']
elif sys.platform == "win32" :
cmpargs = ['/EHsc','/std:c++17']
lnkargs = []
else :
raise RuntimeError("unknown platform")
extensions = Extension(
name="tdm_termite",
sources=["cython/py_tdm_termite.pyx"],
# libraries=[""],
# library_dirs=["lib"],
include_dirs=["lib","3rdparty/pugixml"],
language='c++',
#extra_compile_args=['-std=c++17','-Wno-unused-variable'],
extra_compile_args= cmpargs,
extra_link_args= lnkargs,
)
setup(
version=version,
description='TDMtermite cython extension',
author='Record Evolution GmbH',
author_email='mario.fink@record-evolution.de',
url='https://github.com/RecordEvolution/TDMtermite.git',
name="tdm_termite",
ext_modules=cythonize(extensions)
)

View File

@ -14,6 +14,7 @@ typedef unsigned short int eUInt16Usi;
typedef unsigned int eUInt32Usi; typedef unsigned int eUInt32Usi;
typedef float eFloat32Usi; typedef float eFloat32Usi;
typedef double eFloat64Usi; typedef double eFloat64Usi;
typedef char eStringUsi;
class tdmdatatype class tdmdatatype
{ {
@ -26,12 +27,13 @@ protected:
eUInt32Usi uint32_; // 4 eUInt32Usi uint32_; // 4
eFloat32Usi float32_; // 5 eFloat32Usi float32_; // 5
eFloat64Usi float64_; // 6 eFloat64Usi float64_; // 6
short int dtidx_; // \in \{0,...,6\} eStringUsi string_; // 7
short int dtidx_; // \in \{0,...,7\}
public: public:
tdmdatatype(): sint16_(0), sint32_(0), tdmdatatype(): sint16_(0), sint32_(0),
uint8_(0), uint16_(0), uint32_(0), uint8_(0), uint16_(0), uint32_(0),
float32_(0.0), float64_(0.0), float32_(0.0), float64_(0.0), string_(0),
dtidx_(0) { }; dtidx_(0) { };
// every supported datatype gets its own constructor // every supported datatype gets its own constructor
tdmdatatype(eInt16Usi num): sint16_(num), dtidx_(0) {}; tdmdatatype(eInt16Usi num): sint16_(num), dtidx_(0) {};
@ -41,6 +43,7 @@ public:
tdmdatatype(eUInt32Usi num): uint32_(num), dtidx_(4) {}; tdmdatatype(eUInt32Usi num): uint32_(num), dtidx_(4) {};
tdmdatatype(eFloat32Usi num): float32_(num), dtidx_(5) {}; tdmdatatype(eFloat32Usi num): float32_(num), dtidx_(5) {};
tdmdatatype(eFloat64Usi num): float64_(num), dtidx_(6) {}; tdmdatatype(eFloat64Usi num): float64_(num), dtidx_(6) {};
tdmdatatype(eStringUsi num): string_(num), dtidx_(7) {};
// identify type // identify type
short int& dtype() { return dtidx_; } short int& dtype() { return dtidx_; }
@ -55,6 +58,7 @@ public:
this->uint32_ = num.uint32_; this->uint32_ = num.uint32_;
this->float32_ = num.float32_; this->float32_ = num.float32_;
this->float64_ = num.float64_; this->float64_ = num.float64_;
this->string_ = num.string_;
this->dtidx_ = num.dtidx_; this->dtidx_ = num.dtidx_;
} }
@ -70,6 +74,7 @@ public:
this->uint32_ = num.uint32_; this->uint32_ = num.uint32_;
this->float32_ = num.float32_; this->float32_ = num.float32_;
this->float64_ = num.float64_; this->float64_ = num.float64_;
this->string_ = num.string_;
this->dtidx_ = num.dtidx_; this->dtidx_ = num.dtidx_;
} }
@ -119,6 +124,12 @@ public:
this->dtidx_ = 6; this->dtidx_ = 6;
return *this; return *this;
} }
tdmdatatype& operator=(const eStringUsi &num)
{
this->string_ = num;
this->dtidx_ = 7;
return *this;
}
// obtain number as double // obtain number as double
double as_double() double as_double()
@ -131,6 +142,7 @@ public:
else if ( dtidx_ == 4 ) num = (double)uint32_; else if ( dtidx_ == 4 ) num = (double)uint32_;
else if ( dtidx_ == 5 ) num = (double)float32_; else if ( dtidx_ == 5 ) num = (double)float32_;
else if ( dtidx_ == 6 ) num = (double)float64_; else if ( dtidx_ == 6 ) num = (double)float64_;
else if ( dtidx_ == 7 ) num = (double)(int)string_;
return num; return num;
} }
@ -144,6 +156,7 @@ public:
else if ( num.dtidx_ == 4 ) out<<num.uint32_; else if ( num.dtidx_ == 4 ) out<<num.uint32_;
else if ( num.dtidx_ == 5 ) out<<num.float32_; else if ( num.dtidx_ == 5 ) out<<num.float32_;
else if ( num.dtidx_ == 6 ) out<<num.float64_; else if ( num.dtidx_ == 6 ) out<<num.float64_;
else if ( num.dtidx_ == 7 ) out<<num.string_;
return out; return out;
} }
@ -332,7 +345,7 @@ const std::vector<tdm_datatype> tdm_datatypes = {
{"eFloat32Usi","DT_FLOAT",3,"float_sequence",4,"32 bit float"}, {"eFloat32Usi","DT_FLOAT",3,"float_sequence",4,"32 bit float"},
{"eFloat64Usi","DT_DOUBLE",7,"double_sequence",8,"64 bit double"}, {"eFloat64Usi","DT_DOUBLE",7,"double_sequence",8,"64 bit double"},
// {"eStringUsi","DT_STRING",1,"string_sequence",0,"text"} {"eStringUsi","DT_STRING",1,"string_sequence",1,"text"}
}; };

View File

@ -194,12 +194,31 @@ void tdm_termite::process_include(bool showlog, pugi::xml_document& xml_doc)
// check endianness // check endianness
std::string endianness(tdmincl.child("file").attribute("byteOrder").value()); std::string endianness(tdmincl.child("file").attribute("byteOrder").value());
endianness_ = endianness.compare("littleEndian") == 0 ? true : false; // endianness_ = endianness.compare("littleEndian") == 0 ? true : false;
if ( endianness.compare("littleEndian") == 0 )
{
endianness_ = true;
}
else if ( endianness.compare("bigEndian") == 0 )
{
endianness_ = false;
}
else
{
throw std::runtime_error(std::string("unsupported endianness: ") + endianness);
}
// obtain machine's endianness // obtain machine's endianness
int num = 1; machine_endianness_ = this->detect_endianness();
machine_endianness_ = ( *(char*)&num == 1 ); // if ( machine_endianness_ != endianness_ )
if ( machine_endianness_ != endianness_ ) throw std::runtime_error("endianness mismatch"); // {
// std::stringstream ss;
// ss<<"endianness mismatch: "<<"TDM = "<<(endianness_?"little":"big")
// <<" , "
// <<"Arch = "<<(machine_endianness_?"little":"big");
// // std::cout<<ss.str()<<"\n";
// // throw std::runtime_error(ss.str());
// }
// list block of massdata // list block of massdata
for (pugi::xml_node anode: tdmincl.child("file").children()) for (pugi::xml_node anode: tdmincl.child("file").children())
@ -452,7 +471,7 @@ void tdm_termite::process_localcolumns(bool showlog, pugi::xml_document& xml_doc
} }
else else
{ {
throw std::logic_error("localcolumn with out/multiple values id(s)"); throw std::logic_error("localcolumn with multiple values id(s)");
} }
// add external id referring to block in <usi:include> // add external id referring to block in <usi:include>
@ -652,6 +671,20 @@ std::vector<tdmdatatype> tdm_termite::get_channel(std::string& id)
} }
block blk = tdx_blocks_.at(loccol.external_id_); block blk = tdx_blocks_.at(loccol.external_id_);
// find corresponding submatrix
if ( submatrices_.count(loccol.submatrix_) != 1 )
{
throw std::runtime_error(std::string("no associated submatrix for localcolumn found: ") + loccol.id_);
}
submatrix subm = submatrices_.at(loccol.submatrix_);
if ( subm.number_of_rows_ != blk.length_ )
{
std::stringstream ss;
ss<<"number of rows in submatrix "<<subm.id_<<" ("<<subm.number_of_rows_<<") "
<<" does not agree with length of associated block "<<blk.id_<<" ("<<blk.length_<<")";
throw std::runtime_error(ss.str());
}
// declare vector of appropriate length // declare vector of appropriate length
std::vector<tdmdatatype> datavec(blk.length_); std::vector<tdmdatatype> datavec(blk.length_);
@ -705,6 +738,10 @@ std::vector<tdmdatatype> tdm_termite::get_channel(std::string& id)
{ {
this->convert_data_to_type<eFloat64Usi>(tdxblk,datavec); this->convert_data_to_type<eFloat64Usi>(tdxblk,datavec);
} }
else if ( blk.value_type_ == std::string("eStringUsi") )
{
this->convert_data_to_type<eStringUsi>(tdxblk,datavec);
}
else else
{ {
throw std::runtime_error(std::string("unsupported/unknown datatype") + blk.value_type_); throw std::runtime_error(std::string("unsupported/unknown datatype") + blk.value_type_);
@ -1001,6 +1038,10 @@ void tdm_termite::check_datatype_consistency()
{ {
if ( el.size_ != sizeof(eFloat64Usi) ) throw std::logic_error("invalid representation of eFloat64Usi"); if ( el.size_ != sizeof(eFloat64Usi) ) throw std::logic_error("invalid representation of eFloat64Usi");
} }
else if ( el.name_ == "eStringUsi" )
{
if ( el.size_ != sizeof(eStringUsi) ) throw std::logic_error("invalid representation of eStringUsi");
}
else else
{ {
throw std::logic_error("missing datatype validation"); throw std::logic_error("missing datatype validation");
@ -1029,9 +1070,17 @@ void tdm_termite::convert_data_to_type(std::vector<unsigned char> &buffer,
uint8_t* dfcast = reinterpret_cast<uint8_t*>(&df); uint8_t* dfcast = reinterpret_cast<uint8_t*>(&df);
for ( unsigned long int j = 0; j < sizeof(datatype); j++ ) for ( unsigned long int j = 0; j < sizeof(datatype); j++ )
{
// matching byte order between TDM/TDX and machine's architecture ?
if ( machine_endianness_ == endianness_ )
{ {
dfcast[j] = (int)buffer[i*sizeof(datatype)+j]; dfcast[j] = (int)buffer[i*sizeof(datatype)+j];
} }
else
{
dfcast[j] = (int)buffer[(i+1)*sizeof(datatype)-(j+1)];
}
}
// save number in channel // save number in channel
channel[i] = df; channel[i] = df;

View File

@ -64,6 +64,29 @@ class tdm_termite
std::vector<unsigned char> tdxbuffer_; std::vector<unsigned char> tdxbuffer_;
std::ifstream *tdx_ifstream_; std::ifstream *tdx_ifstream_;
// find machine's endianness at runtime
// detect machine endianness (C++20 !!)
// if ( std::endian::native == std::endian::little )
// {
// machine_endianness_ = true;
// }
// else if ( std::endian::native == std::endian::big )
// {
// machine_endianness_ = false;
// }
// else
// {
// throw std::runtime_error("mixed endianness architecture is not supported");
// }
bool detect_endianness()
{
// int num = 1;
// machine_endianness_ = ( *(char*)&num == 1 );
std::uint32_t num = 0x11223344;
uint8_t* dfc = reinterpret_cast<uint8_t*>(&num);
return ( dfc[0] == 0x44 );
}
// extract list of identifiers from e.g. "#xpointer(id("usi12") id("usi13"))" // extract list of identifiers from e.g. "#xpointer(id("usi12") id("usi13"))"
std::vector<std::string> extract_ids(std::string idstring) std::vector<std::string> extract_ids(std::string idstring)
{ {

112
makefile
View File

@ -13,18 +13,16 @@ HPP = $(wildcard lib/*.hpp)
CC = g++ -std=c++17 CC = g++ -std=c++17
# compiler options and optimization flags # compiler options and optimization flags
OPT = -O3 -Wall -Werror -Wunused-variable -Wsign-compare OPT = -O3 -Wall -Wconversion -Wpedantic -Wunused-variable -Wsign-compare
# include 3rd party libraries paths # include 3rd party libraries paths
LIBB := 3rdparty/ LIBB := 3rdparty/
LIB := $(foreach dir,$(shell ls $(LIBB)),-I $(LIBB)$(dir)) LIB := $(foreach dir,$(shell ls $(LIBB)),-I $(LIBB)$(dir))
# determine git version/commit tag # determine git version/commit tag
GTAG := $(shell git tag | tail -n1) GTAG := $(shell git tag -l --sort=version:refname | tail -n1 | sed "s/$^v//g")
GTAGV := $(shell git tag | tail -n1 | tr -d 'v')
GHSH := $(shell git rev-parse HEAD | head -c8) GHSH := $(shell git rev-parse HEAD | head -c8)
PIPYVS := $(shell grep "version" pip/setup.py | tr -d 'version=,\#\" ') GVSN := $(shell cat python/VERSION | tr -d ' \n')
PICGVS := $(shell grep "version" pip/setup.cfg | tr -d 'version=,\#\" ')
# current timestamp # current timestamp
TMS = $(shell date +%Y%m%dT%H%M%S) TMS = $(shell date +%Y%m%dT%H%M%S)
@ -37,31 +35,20 @@ OST := $(shell uname)
CWD := $(shell pwd) CWD := $(shell pwd)
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# version/tag check # C++ and CLI tool
checkversion: # check tags and build executable
@echo "git tag: "$(GTAG) exec: check-tags $(GVSN) $(EXE)
@echo "git head: "$(GHSH)
@echo "pip setup.py version: "$(PIPYVS)
@echo "pip setup.cfg version: "$(PICGVS)
$(GTAGV): # build executable
@echo "check consistent versions (git tag vs. setup.py): "$(GTAG)" <-> "$(PIPYVS)" " $(EXE): $(SRC).o main.o
# --------------------------------------------------------------------------- #
# CLI tool
$(EXE) : main.o $(SRC).o
$(CC) $(OPT) $^ -o $@ $(CC) $(OPT) $^ -o $@
install : $(EXE) $(SRC).o : lib/$(SRC).cpp lib/$(SRC).hpp $(HPP)
cp $< $(INST)/ $(CC) -c $(OPT) $(LIB) $< -o $@
uninstall : $(INST)/$(EXE)
rm $<
# build main.cpp object file and include git version/commit tag # build main.cpp object file and include git version/commit tag
main.o : src/main.cpp lib/$(SRC).hpp $(HPP) main.o: src/main.cpp lib/$(SRC).hpp $(HPP)
@cp $< $<.cpp @cp $< $<.cpp
@if [ $(OST) = "Linux" ]; then\ @if [ $(OST) = "Linux" ]; then\
sed -i 's/TAGSTRING/$(GTAG)/g' $<.cpp; \ sed -i 's/TAGSTRING/$(GTAG)/g' $<.cpp; \
@ -76,8 +63,11 @@ main.o : src/main.cpp lib/$(SRC).hpp $(HPP)
$(CC) -c $(OPT) $(LIB) -I lib/ $<.cpp -o $@ $(CC) -c $(OPT) $(LIB) -I lib/ $<.cpp -o $@
@rm $<.cpp @rm $<.cpp
$(SRC).o : lib/$(SRC).cpp lib/$(SRC).hpp $(HPP) install: $(EXE)
$(CC) -c $(OPT) $(LIB) $< -o $@ cp $< $(INST)/
uninstall : $(INST)/$(EXE)
rm $<
tdmtest : tdmtest.o tdmtest : tdmtest.o
$(CC) $(OPT) $^ -o $@ $(CC) $(OPT) $^ -o $@
@ -86,38 +76,19 @@ tdmtest.o : src/test.cpp lib/$(SRC).hpp $(HPP)
$(CC) -c $(OPT) $(LIB) -I lib/ $< -o $@ $(CC) -c $(OPT) $(LIB) -I lib/ $< -o $@
cpp-clean : cpp-clean :
rm -f $(EXE) *.o src/main.cpp.cpp tdmtest rm -vf $(EXE)
rm -vf *.o src/main.cpp.cpp tdmtest
# --------------------------------------------------------------------------- # #-----------------------------------------------------------------------------#
# check process # versions
checkps : $(GTAG):
@ps aux | head -n1 @echo "consistent versions check successful: building $(GTAG)"
@ps aux | grep $(EXE) | grep -v "grep"
# --------------------------------------------------------------------------- # check-tags:
# python/cython module @echo "latest git tag: $(GTAG)"
@echo "latest git hash: $(GHSH)"
cython-requirements: cython/requirements.txt @echo "python version: $(GVSN)"
python3 -m pip install -r $<
cython-help : cython/setup.py
python3 $< --help
cython-list : cython/setup.py
python3 $< --name --description --author --author-email --url
cython-build : cython/setup.py cython/tdm_termite.pxd cython/py_tdm_termite.pyx $(HPP) lib/tdm_termite.cpp
python3 $< build_ext --inplace
cp -v tdm_termite.cpython-*.so python/
cython-install : cython/setup.py cython/tdm_termite.pxd cython/py_tdm_termite.pyx $(HPP) lib/tdm_termite.cpp
python3 $< install
cython-clean :
rm -vf cython/py_tdm_termite.c* cython/tdm_termite.c*
rm -vf tdm_termite.cpython-*.so python/tdm_termite.cpython-*.so
rm -rf build
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# docker # docker
@ -134,17 +105,32 @@ docker-clean:
docker image remove tdmtermite docker image remove tdmtermite
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# pip # check process
pip-publish: $(PIPYVS) cython-build checkps :
cd pip/ && make pip-publish @ps aux | head -n1
@ps aux | grep $(EXE) | grep -v "grep"
pip-test:
cd pip/ && make pip-test
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# python
clean : cpp-clean cython-clean python-build: check-tags $(GVSN)
cd pip/ && make pip-clean make -C python/ build-inplace
cp python/TDMtermite*.so ./ -v
python-install: check-tags $(GVSN)
make -C python/ install
python-clean:
make -C python/ clean
rm -vf TDMtermite*.so
python-test:
PYTHONPATH=./ python python/examples/usage.py
# --------------------------------------------------------------------------- #
# clean
clean : cpp-clean python-clean
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #

View File

@ -1,15 +0,0 @@
FROM debian:bullseye
RUN DEBIAN_FRONTEND=noninteractive \
apt-get update && apt-get upgrade -y && apt-get install -y \
python3 \
python3-pip \
python3-setuptools
# RUN python3 -m pip install -i https://test.pypi.org/simple/ TDMtermite-RecordEvolution==0.6.7 && \
# python3 -m pip install --upgrade TDMtermite-RecordEvolution
RUN python3 -m pip install TDMtermite
# CMD ["sleep","3600"]
CMD ["python3","-m","pip","freeze"]

View File

@ -1,25 +0,0 @@
FROM quay.io/pypa/manylinux2010_x86_64
RUN yum -y install \
git \
python34-devel \
gcc-c++ \
python34-tkinter \
make \
python34-pip \
RUN sudo yum -y install rh-python36-python-devel.x86_64 rh-python35-python-devel.x86_64 python27-python-devel.x86_64
ENV PATH /opt/rh/python27/root/usr/bin:/opt/rh/rh-python35/root/usr/bin/:/opt/rh/rh-python36/root/usr/bin/:$PATH
RUN python3.6 -m pip install --user --upgrade cython wheel twine auditwheel
WORKDIR /home/${USERNAME}/neuron-yale
RUN git checkout setuppy \
&& python3.6 setup.py bdist_wheel
# repair wheel? see : https://malramsay.com/post/perils_of_packaging/
RUN python3.6 -m pip install --user --upgrade auditwheel
RUN LD_LIBRARY_PATH=`pwd`/_install/lib auditwheel repair dist/NEURON-7.8-cp36-cp36m-linux_x86_64.whl

View File

@ -1,4 +0,0 @@
[build-system]
requires = [
"setuptools"
]

View File

@ -1,62 +0,0 @@
# --------------------------------------------------------------------------- #
pip-publish: pip-sdist pip-upload
pip-sdist: ../cython/py_tdm_termite.pyx ../cython/tdm_termite.pxd ../cython/py_tdm_termite.cpp
cp -v ../cython/py_tdm_termite.pyx ../cython/tdm_termite.pxd ./
cp -v ../cython/py_tdm_termite.cpp ./
cp -v ../lib/*.hpp ../lib/*.cpp ./
cp -v ../3rdparty/pugixml/* ./
cat ../README.md | grep '^# TDMtermite' -A 50000 > ./README.md
cp -v ../LICENSE ./
# cython py_tdm_termite.pyx -o py_tdm_termite.cpp
python3 setup.py sdist
pip-setup:
apt-get install -y python3-setuptools \
python3-pip \
python3-venv
python3 -m pip install --upgrade build
python3 -m pip install twine wheel auditwheel cython
python3 -m pip install --user --upgrade twine
pip-build:
#python3 -m build
# python3 setup.py sdist bdist_wheel
python3 setup.py bdist_wheel
# actually it seems we have to use CentOS container
# docker run -i -t -v `pwd`:/io quay.io/pypa/manylinux1_x86_64 /bin/bash
# see https://github.com/neuronsimulator/nrn/issues/329 for setup of the container
pip-audit:
auditwheel repair $(shell find dist/ -name "*-cp38-cp38-linux_x86_64.whl")
# username: __token__
# password: API-token including "pypi-"
# !! RUN AS ROOT!! (only for bdist_wheel + auditwheel)
pip-upload-test:
python3 -m twine upload --repository testpypi dist/$(shell ls -t dist/ | head -n1)
pip-upload:
python3 -m twine upload dist/$(shell ls -t dist/ | head -n1)
pip-test-install:
python3 -m pip install --index-url https://test.pypi.org/simple --no-deps TDMtermite-RecordEvolution
# python3 -m pip install -i https://test.pypi.org/simple/ TDMtermite-RecordEvolution==0.5
pip-test:
docker build . --tag tdmtermite-piptest
docker run -it --rm tdmtermite-piptest
pip-clean:
rm -rvf dist/
rm -rvf *.egg-info
rm -rvf build/
rm -rvf cython/
rm -rvf wheelhouse/
rm -vf *.pyx *.pxd
rm -vf *.cpp *.c *.hpp
rm -vf README.md LICENSE
# --------------------------------------------------------------------------- #

View File

@ -1,21 +0,0 @@
[metadata]
name = TDMtermite-RecordEvolution
version = 1.0.1
author = Record Evolution GmbH
author_email = mario.fink@record-evolution.de
maintainer = Record Evolution GmbH
license = MIT
description = Extract and read data from National Instruments LabVIEW tdx/tdm files and export them as csv files
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/RecordEvolution/TDMtermite.git
project_urls =
Bug Tracker = https://github.com/RecordEvolution/TDMtermite/issues
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
[options]
packages = find:
python_requires = >=3.6

View File

@ -1,49 +0,0 @@
from setuptools import setup, Extension
import sys
print("building on platform: "+sys.platform)
if sys.platform == "linux" or sys.platform == "darwin" :
cmpargs = ['-std=c++17','-Wno-unused-variable']
lnkargs = ['-std=c++17','-Wno-unused-variable']
elif sys.platform == "win32" :
cmpargs = ['/EHsc','/std:c++17']
lnkargs = []
else :
raise RuntimeError("unknown platform")
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="TDMtermite",
version="1.0.3",
author="Record Evolution GmbH",
author_email="mario.fink@record-evolution.de",
maintainer="Record Evolution GmbH",
license="MIT",
description="Extract and read data from National Instruments LabVIEW tdx/tdm files and export them as csv files",
keywords="TDM/TDX NationalInstruments LabVIEW decode",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/RecordEvolution/TDMtermite.git",
project_urls={
"Bug Tracker": "https://github.com/RecordEvolution/TDMtermite/issues",
},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
ext_modules=[Extension("tdm_termite",
["py_tdm_termite.cpp"],
# libraries_dirs = ["cython/"],
# include_dirs = ["3rdparty/pugixml/","lib/"],
# depends = ["../lib/tdm_termite.hpp"]
language = 'c++',
extra_compile_args = cmpargs,
extra_link_args = lnkargs,
)
],
)

View File

@ -1,4 +1,4 @@
include *.hpp include lib/*.hpp
include *.cpp include *.cpp
include *.pyx include *.pyx
include *.pxd include *.pxd

1
python/VERSION Normal file
View File

@ -0,0 +1 @@
2.1.3

View File

@ -1,11 +1,11 @@
import tdm_termite import tdmtermite
import json import json
import re import re
# create 'tdm_termite' instance object # create 'tdm_termite' instance object
try : try :
jack = tdm_termite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx') jack = tdmtermite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx')
except RuntimeError as e : except RuntimeError as e :
print("failed to load/decode TDM files: " + str(e)) print("failed to load/decode TDM files: " + str(e))

View File

@ -1,9 +1,9 @@
import tdm_termite import tdmtermite
# create 'tdm_termite' instance object # create 'tdm_termite' instance object
try : try :
jack = tdm_termite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx') jack = tdmtermite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx')
# list ids of channelgroups # list ids of channelgroups
grpids = jack.get_channelgroup_ids() grpids = jack.get_channelgroup_ids()
# iterate through groups # iterate through groups

View File

@ -1,12 +1,12 @@
import tdm_termite import tdmtermite
# import numpy as np # import numpy as np
import json import json
import re import re
# create 'tdm_termite' instance object # create 'tdm_termite' instance object
try : try :
jack = tdm_termite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx') jack = tdmtermite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx')
except RuntimeError as e : except RuntimeError as e :
print("failed to load/decode TDM files: " + str(e)) print("failed to load/decode TDM files: " + str(e))

60
python/makefile Normal file
View File

@ -0,0 +1,60 @@
setup:
cat ../README.md | grep '^# TDMtermite' -A 50000 > ./README.md
#pandoc -f markdown -t rst -o README.rst README.md
#python -m rstvalidator README.rst
cp -r ../lib ./
cp -r ../3rdparty ./
cp -v ../LICENSE ./
setup-clean:
rm -vf README.md README.rst LICENSE
rm -rf lib/ 3rdparty/
build: setup
python setup.py build
build-inplace: setup
python setup.py build_ext --inplace
build-install: setup
python setup.py install
build-sdist: setup
python setup.py sdist
python -m twine check dist/*
build-bdist: setup
python setup.py bdist
python -m twine check dist/*
build-clean:
python setup.py clean --all
rm -vf tdmtermite*.so tdmtermite*.cpp
rm -rvf dist/ tdmtermite.egg-info/
cibuildwheel-build: setup
cibuildwheel --platform linux
cibuildwheel-clean:
rm -rvf wheelhouse/
pypi-audit:
auditwheel repair $(shell find dist/ -name "*-linux_x86_64.whl")
# username: __token__
# password: API-token including "pypi-"
pypi-upload-test:
python -m twine upload --repository testpypi dist/$(shell ls -t dist/ | head -n1)
pypi-install-test:
python -m pip install --index-url https://test.pypi.org/simple --no-deps TDMtermite-RecordEvolution
# python3 -m pip install -i https://test.pypi.org/simple/ TDMtermite-RecordEvolution==0.5
pypi-upload:
python -m twine upload dist/$(shell ls -t dist/ | head -n1)
clean: setup build-clean cibuildwheel-clean setup-clean
run-example:
PYTHONPATH=$(pwd) python examples/usage.py

6
python/pyproject.toml Normal file
View File

@ -0,0 +1,6 @@
[build-system]
requires = ["setuptools", "wheel","Cython"]
build-backend = "setuptools.build_meta"
[tool.cibuildwheel]
before-all = ""

23
python/setup.cfg Normal file
View File

@ -0,0 +1,23 @@
[metadata]
name = tdmtermite
description = Extract and read data from National Instruments LabVIEW tdx/tdm files and export them as csv files
long_description = file: README.md
# long_description_content_type = text/x-rst
long_description_content_type = text/markdown
version = file: VERSION
author = Record Evolution GmbH
author_email = mario.fink@record-evolution.de
maintainer = Record Evolution GmbH
url= https://github.com/RecordEvolution/TDMtermite.git
license = MIT License
license_files = LICENSE
keywords = TDM, TDX, National Instruments, DIAdem, LabVIEW, Measurement Studio, SignalExpress
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Topic :: Scientific/Engineering
Topic :: Software Development :: Libraries :: Python Modules
[options]

23
python/setup.py Normal file
View File

@ -0,0 +1,23 @@
from setuptools import Extension, setup
from Cython.Build import cythonize
import sys
print("building on platform: "+sys.platform)
cmpArgs = {
"linux": ['-std=c++17','-Wno-unused-variable'],
"darwin": ['-std=c++17','-Wno-unused-variable'],
"win32": ['/EHsc','/std:c++17']
}
extension = Extension(
"tdmtermite",
language='c++',
sources=["tdmtermite.pyx"],
include_dirs=["lib","3rdparty/pugixml"],
extra_compile_args=cmpArgs[sys.platform]
)
setup(
ext_modules=cythonize(extension,language_level=3)
)

View File

@ -1,28 +1,34 @@
# cython: language_level = 3
# use some C++ STL libraries # use some C++ STL libraries
from libcpp.string cimport string from libcpp.string cimport string
from libcpp.vector cimport vector from libcpp.vector cimport vector
from libcpp cimport bool from libcpp cimport bool
cdef extern from "tdm_termite.cpp": cdef extern from "lib/tdm_termite.cpp":
pass pass
cdef extern from "tdm_termite.hpp": cdef extern from "lib/tdm_termite.hpp":
cdef cppclass tdm_termite:
cdef cppclass cpptdmtermite "tdm_termite":
# constructor(s) # constructor(s)
tdm_termite() except + cpptdmtermite() except +
tdm_termite(string tdmfile, string tdxfile) except + cpptdmtermite(string tdmfile, string tdxfile) except +
# provide TDM files # provide TDM files
void submit_files(string tdmfile, string tdxfile) except+ void submit_files(string tdmfile, string tdxfile) except+
# get list of channel(-group) ids # get list of channel(-group) ids
vector[string] get_channelgroup_ids() except+ vector[string] get_channelgroup_ids() except+
vector[string] get_channel_ids() except+ vector[string] get_channel_ids() except+
# get data of specific channel # get data of specific channel
vector[double] get_channel_as_double(string id) except+ vector[double] get_channel_as_double(string id) except+
# get meta-data # get meta-data
string get_channelgroup_info(string id) except+ string get_channelgroup_info(string id) except+
string get_channel_info(string id) except+ string get_channel_info(string id) except+
# print a channel(-group) # print a channel(-group)
void print_group(string id, const char* filename, bool include_meta, void print_group(string id, const char* filename, bool include_meta,
char delimiter, string column_header) except+ char delimiter, string column_header) except+

View File

@ -1,51 +1,52 @@
# distutils: language = c++ # distutils: language = c++
# cython: language_level = 3
from tdmtermite cimport cpptdmtermite
from tdm_termite cimport tdm_termite
import json as jn import json as jn
# import numpy as np
cdef class tdmtermite: cdef class tdmtermite:
# C++ instance of class => stack allocated (requires nullary constructor!) # C++ instance of class => stack allocated (requires nullary constructor!)
cdef tdm_termite cpp_tdm cdef cpptdmtermite cpptdm
# constructor # constructor
def __cinit__(self, string tdmfile, string tdxfile): def __cinit__(self, string tdmfile, string tdxfile):
self.cpp_tdm = tdm_termite(tdmfile,tdxfile) self.cpptdm = cpptdmtermite(tdmfile,tdxfile)
# provide TDM files # provide TDM files
def submit_files(self,string tdmfile, string tdxfile): def submit_files(self,string tdmfile, string tdxfile):
self.cpp_tdm.submit_files(tdmfile,tdxfile) self.cpptdm.submit_files(tdmfile,tdxfile)
# get list of channel(-group) ids # get list of channel(-group) ids
def get_channelgroup_ids(self): def get_channelgroup_ids(self):
return self.cpp_tdm.get_channelgroup_ids() return self.cpptdm.get_channelgroup_ids()
def get_channel_ids(self): def get_channel_ids(self):
return self.cpp_tdm.get_channel_ids() return self.cpptdm.get_channel_ids()
# get data of specific channel # get data of specific channel
def get_channel(self, string id): def get_channel(self, string id):
return self.cpp_tdm.get_channel_as_double(id) return self.cpptdm.get_channel_as_double(id)
# get meta-data of channel(-group) (as dictionary) # get meta-data of channel(-group) (as dictionary)
def get_channelgroup_info(self, string id): def get_channelgroup_info(self, string id):
grpstr = self.cpp_tdm.get_channelgroup_info(id) grpstr = self.cpptdm.get_channelgroup_info(id)
return jn.loads(grpstr.decode()) return jn.loads(grpstr.decode())
def get_channel_info(self, string id): def get_channel_info(self, string id):
chnstr = self.cpp_tdm.get_channel_info(id) chnstr = self.cpptdm.get_channel_info(id)
return jn.loads(chnstr.decode()) return jn.loads(chnstr.decode())
# print a channel(-group) # print a channel(-group)
def print_channelgroup(self, string id, const char* filename, bool include_meta, def print_channelgroup(self, string id, const char* filename, bool include_meta,
char delimiter, string column_header): char delimiter, string column_header):
self.cpp_tdm.print_group(id,filename,include_meta,delimiter,column_header) self.cpptdm.print_group(id,filename,include_meta,delimiter,column_header)
def print_channel(self, string id, const char* filename, def print_channel(self, string id, const char* filename,
bool include_meta): bool include_meta):
self.cpp_tdm.print_channel(id,filename,include_meta) self.cpptdm.print_channel(id,filename,include_meta)
# print all data grouped by channelgroups # print all data grouped by channelgroups
def write_all(self, string outputdir) : def write_all(self, string outputdir) :
grpids = self.cpp_tdm.get_channelgroup_ids() grpids = self.cpptdm.get_channelgroup_ids()
for id in grpids : for id in grpids :
grpfile = outputdir.decode() + "/channelgroup_" + id.decode() + ".csv" grpfile = outputdir.decode() + "/channelgroup_" + id.decode() + ".csv"
self.cpp_tdm.print_group(id,grpfile.encode(),True,ord(','),"".encode()) self.cpptdm.print_group(id,grpfile.encode(),True,ord(','),"".encode())

369
samples/SineData-be.tdm Executable file
View File

@ -0,0 +1,369 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<usi:tdm xmlns:usi="http://www.ni.com/Schemas/USI/1_0" version="1.0">
<usi:documentation>
<usi:exporter>National Instruments USI</usi:exporter>
<usi:exporterVersion>1.5</usi:exporterVersion>
</usi:documentation>
<usi:model modelName="National Instruments USI generated meta file" modelVersion="1.0">
<usi:include nsUri="http://www.ni.com/DataModels/USI/TDM/1_0"/>
</usi:model>
<usi:include>
<file byteOrder="bigEndian" url="SineData-be.tdx">
<block byteOffset="0" id="inc0" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="8000" id="inc1" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="16000" id="inc2" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="24000" id="inc3" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="32000" id="inc4" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="40000" id="inc5" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="48000" id="inc6" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="56000" id="inc7" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="64000" id="inc8" length="1000" valueType="eFloat64Usi"/>
<block byteOffset="72000" id="inc9" length="1000" valueType="eFloat64Usi"/>
</file>
</usi:include>
<usi:data>
<double_sequence id="usi1">
<values external="inc0"/>
</double_sequence>
<double_sequence id="usi2">
<values external="inc1"/>
</double_sequence>
<double_sequence id="usi3">
<values external="inc2"/>
</double_sequence>
<double_sequence id="usi4">
<values external="inc3"/>
</double_sequence>
<double_sequence id="usi5">
<values external="inc4"/>
</double_sequence>
<double_sequence id="usi6">
<values external="inc5"/>
</double_sequence>
<double_sequence id="usi7">
<values external="inc6"/>
</double_sequence>
<double_sequence id="usi8">
<values external="inc7"/>
</double_sequence>
<double_sequence id="usi9">
<values external="inc8"/>
</double_sequence>
<double_sequence id="usi10">
<values external="inc9"/>
</double_sequence>
<tdm_root id="usi11">
<name>SineData.TDM</name>
<description>Sine signals of various amplitudes and frequencies.</description>
<title>SineData</title>
<author>National Instruments</author>
<datetime>2008-05-06T17:20:12.65074539184570313</datetime>
<channelgroups>#xpointer(id("usi12") id("usi13"))</channelgroups>
</tdm_root>
<tdm_channelgroup id="usi12">
<name>Amplitudes</name>
<description>Sine Signals of various amplitudes.</description>
<root>#xpointer(id("usi11"))</root>
<instance_attributes>
<double_attribute name="Frequency">1</double_attribute>
</instance_attributes>
<channels>#xpointer(id("usi14") id("usi15") id("usi16") id("usi17") id("usi18"))</channels>
<submatrices>#xpointer(id("usi24") id("usi25") id("usi26") id("usi27") id("usi28"))</submatrices>
</tdm_channelgroup>
<tdm_channelgroup id="usi13">
<name>Frequencies</name>
<description>Sine signals of various frequencies.</description>
<root>#xpointer(id("usi11"))</root>
<instance_attributes>
<double_attribute name="Amplitude">1</double_attribute>
</instance_attributes>
<channels>#xpointer(id("usi19") id("usi20") id("usi21") id("usi22") id("usi23"))</channels>
<submatrices>#xpointer(id("usi29") id("usi30") id("usi31") id("usi32") id("usi33"))</submatrices>
</tdm_channelgroup>
<tdm_channel id="usi14">
<name>A = 1</name>
<group>#xpointer(id("usi12"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-0.999997146387718</minimum>
<maximum>0.999999682931835</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">0</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi34"))</local_columns>
</tdm_channel>
<tdm_channel id="usi15">
<name>A = 2</name>
<group>#xpointer(id("usi12"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-1.99999429277544</minimum>
<maximum>1.99999936586367</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">1</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi35"))</local_columns>
</tdm_channel>
<tdm_channel id="usi16">
<name>A = 4</name>
<group>#xpointer(id("usi12"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-3.99998858555087</minimum>
<maximum>3.99999873172734</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">2</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi36"))</local_columns>
</tdm_channel>
<tdm_channel id="usi17">
<name>A = 8</name>
<group>#xpointer(id("usi12"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-7.99997717110174</minimum>
<maximum>7.99999746345468</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">3</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi37"))</local_columns>
</tdm_channel>
<tdm_channel id="usi18">
<name>A = 16</name>
<group>#xpointer(id("usi12"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-15.9999543422035</minimum>
<maximum>15.9999949269094</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">4</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi38"))</local_columns>
</tdm_channel>
<tdm_channel id="usi19">
<name>F = 1</name>
<group>#xpointer(id("usi13"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-0.999997146387718</minimum>
<maximum>0.999999682931835</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">0</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi39"))</local_columns>
</tdm_channel>
<tdm_channel id="usi20">
<name>F = 2</name>
<group>#xpointer(id("usi13"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-0.999999230697499</minimum>
<maximum>0.999995986891472</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">1</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi40"))</local_columns>
</tdm_channel>
<tdm_channel id="usi21">
<name>F = 4</name>
<group>#xpointer(id("usi13"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-0.999999230697499</minimum>
<maximum>0.99994907791452</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">2</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi41"))</local_columns>
</tdm_channel>
<tdm_channel id="usi22">
<name>F = 8</name>
<group>#xpointer(id("usi13"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-0.999999230697499</minimum>
<maximum>0.999996490345607</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">3</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi42"))</local_columns>
</tdm_channel>
<tdm_channel id="usi23">
<name>F = 16</name>
<group>#xpointer(id("usi13"))</group>
<datatype>DT_DOUBLE</datatype>
<minimum>-0.999999230697499</minimum>
<maximum>0.999993076284592</maximum>
<instance_attributes>
<long_attribute name="NI_ArrayColumn">4</long_attribute>
<long_attribute name="NI_ChannelLength">1000</long_attribute>
<long_attribute name="NI_DataType">10</long_attribute>
</instance_attributes>
<local_columns>#xpointer(id("usi43"))</local_columns>
</tdm_channel>
<submatrix id="usi24">
<name>Untitled</name>
<measurement>#xpointer(id("usi12"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi34"))</local_columns>
</submatrix>
<submatrix id="usi25">
<name>Untitled</name>
<measurement>#xpointer(id("usi12"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi35"))</local_columns>
</submatrix>
<submatrix id="usi26">
<name>Untitled</name>
<measurement>#xpointer(id("usi12"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi36"))</local_columns>
</submatrix>
<submatrix id="usi27">
<name>Untitled</name>
<measurement>#xpointer(id("usi12"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi37"))</local_columns>
</submatrix>
<submatrix id="usi28">
<name>Untitled</name>
<measurement>#xpointer(id("usi12"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi38"))</local_columns>
</submatrix>
<submatrix id="usi29">
<name>Untitled</name>
<measurement>#xpointer(id("usi13"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi39"))</local_columns>
</submatrix>
<submatrix id="usi30">
<name>Untitled</name>
<measurement>#xpointer(id("usi13"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi40"))</local_columns>
</submatrix>
<submatrix id="usi31">
<name>Untitled</name>
<measurement>#xpointer(id("usi13"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi41"))</local_columns>
</submatrix>
<submatrix id="usi32">
<name>Untitled</name>
<measurement>#xpointer(id("usi13"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi42"))</local_columns>
</submatrix>
<submatrix id="usi33">
<name>Untitled</name>
<measurement>#xpointer(id("usi13"))</measurement>
<number_of_rows>1000</number_of_rows>
<local_columns>#xpointer(id("usi43"))</local_columns>
</submatrix>
<localcolumn id="usi34">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi14"))</measurement_quantity>
<submatrix>#xpointer(id("usi24"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi1"))</values>
</localcolumn>
<localcolumn id="usi35">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi15"))</measurement_quantity>
<submatrix>#xpointer(id("usi25"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi2"))</values>
</localcolumn>
<localcolumn id="usi36">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi16"))</measurement_quantity>
<submatrix>#xpointer(id("usi26"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi3"))</values>
</localcolumn>
<localcolumn id="usi37">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi17"))</measurement_quantity>
<submatrix>#xpointer(id("usi27"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi4"))</values>
</localcolumn>
<localcolumn id="usi38">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi18"))</measurement_quantity>
<submatrix>#xpointer(id("usi28"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi5"))</values>
</localcolumn>
<localcolumn id="usi39">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi19"))</measurement_quantity>
<submatrix>#xpointer(id("usi29"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi6"))</values>
</localcolumn>
<localcolumn id="usi40">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi20"))</measurement_quantity>
<submatrix>#xpointer(id("usi30"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi7"))</values>
</localcolumn>
<localcolumn id="usi41">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi21"))</measurement_quantity>
<submatrix>#xpointer(id("usi31"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi8"))</values>
</localcolumn>
<localcolumn id="usi42">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi22"))</measurement_quantity>
<submatrix>#xpointer(id("usi32"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi9"))</values>
</localcolumn>
<localcolumn id="usi43">
<name>Untitled</name>
<measurement_quantity>#xpointer(id("usi23"))</measurement_quantity>
<submatrix>#xpointer(id("usi33"))</submatrix>
<global_flag>15</global_flag>
<independent>0</independent>
<sequence_representation>explicit</sequence_representation>
<values>#xpointer(id("usi10"))</values>
</localcolumn>
</usi:data>
</usi:tdm>

BIN
samples/SineData-be.tdx Normal file

Binary file not shown.

63
samples/swapbyteorder.cpp Normal file
View File

@ -0,0 +1,63 @@
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
int main(int argc, char* argv[])
{
for ( int i = 0; i < argc; i++ )
{
std::cout<<argv[i]<<"\n";
}
if ( argc < 3 )
{
std::cout<<"missing file argument\n";
return 1;
}
std::ifstream fin(argv[1],std::ifstream::binary);
std::vector<unsigned char> tdxbuf((std::istreambuf_iterator<char>(fin)),
(std::istreambuf_iterator<char>()));
fin.close();
std::cout<<"length of buffer: "<<tdxbuf.size()<<"\n";
unsigned long int dtsize = 8;
if ( tdxbuf.size()%dtsize != 0 )
{
std::cout<<"mismatch between datatype size and length of buffer\n";
return 1;
}
unsigned long int nums = tdxbuf.size()/dtsize;
std::cout<<"number of entities: "<<nums<<"\n";
std::vector<unsigned char> tdxbufrev(tdxbuf.size());
for ( unsigned long int i = 0; i < nums; i++ )
{
for ( unsigned long int j = 0; j < dtsize; j++ )
{
tdxbufrev[i*dtsize+j] = tdxbuf[(i+1)*dtsize-(j+1)];
}
}
std::ofstream fou(argv[2],std::ifstream::binary);
for ( unsigned char ch: tdxbufrev)
{
fou<<ch;
}
fou.close();
return 0;
}