Compare commits

...

36 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
afac245cdd add timestamp insertion for build on Darwin 2021-09-16 14:09:39 +02:00
e1331cc6e6 * allowing for missing value-id (and consequently external_id, as well) in local_column (refer to issue #12) => resulting in empty channel in output
* simplify get_channel_overview(...) by removing full group info
* add build-timestamp to version/help message of CLI binary
* simplify/unify group/channel/submatrix/localcolumn overview of CLI
binary
2021-09-16 14:03:38 +02:00
b5d32f1ccd fix unescaped hash in shell redirection 2021-09-16 10:20:00 +02:00
Mario Fink
53fea5f738 bump missing new version in pip/setup.py 2021-09-02 13:10:23 +02:00
Mario Fink
c407abe517 * README.md: add install notes regarding pip install
* pip-release: extract proper part of README.md for pip package
* bump version 1.0.3
2021-09-02 13:05:46 +02:00
f8f779136b bump pip package version 1.0.2 2021-06-11 09:34:20 +02:00
35c5ac9e75 * setup.py: remove extra linkargs for win32
* tdm_termite.cpp: explicit cast to unsigned int
2021-06-11 09:24:44 +02:00
d2453427c7 pip/setup.py: introduce platform dependency in build 2021-06-11 08:42:32 +02:00
6b7e0258b3 introduce platform dependent compile/link options for setup.py 2021-06-10 22:30:20 +02:00
Mario Fink
dc23b1e753 setup.py: fix compilation with MSVC 2021-06-10 19:17:25 +02:00
Mario Fink
1e2b344104 * check versions vs. git tags
* neglect -Wunused-variable for MSVC compiler
2021-06-10 13:27:40 +02:00
30 changed files with 885 additions and 318 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/*.pxd
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)
[![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
@ -160,19 +159,21 @@ make cython-requirements
make cython-install
```
That makes the module available for import as a `import tdm_termite` .
which makes the module available for import by `import tdm_termite` .
#### Installation with pip
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
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
```Shell
python3 -m pip install TDMtermite
python3 -m pip install tdmtermite
```
Note, that _python3_setuptools_ and _gcc version >= 10.2.0_ are required to
successfully install and use it.
##### Unix
Note, that _python3_setuptools_ and _gcc version >= 10.2.0_ are required to
successfully install and use it.
## Usage
@ -223,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:
```Python
import tdm_termite
import tdmtermite
```
This will import the module. The TDM files are provided by creating an instance of
the _tdm_termite_ class:
the _tdmtermite_ class:
```Python
# create 'tdm_termite' instance object
# create 'tdmtermite' instance object
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:
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:
```Python
@ -253,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:
```Python
import tdm_termite
import tdmtermite
import re
# create 'tdm_termite' instance object
# create 'tdmtermite' instance object
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 :
print("failed to load/decode TDM files: " + str(e))
@ -292,8 +293,8 @@ to simply extract all data of the TDM datatset and dump it to files in a given
(existing!) directory, do
```Python
import tdm_termite
jack = tdm_termite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx')
import tdmtermite
jack = tdmtermite.tdmtermite(b'samples/SineData.tdm',b'samples/SineData.tdx')
jack.write_all(b"./my_tdm_data_directory/")
```

View File

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

View File

@ -1,35 +0,0 @@
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import os
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_link_args=['-std=c++17'],
)
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)
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 float eFloat32Usi;
typedef double eFloat64Usi;
typedef char eStringUsi;
class tdmdatatype
{
@ -26,12 +27,13 @@ protected:
eUInt32Usi uint32_; // 4
eFloat32Usi float32_; // 5
eFloat64Usi float64_; // 6
short int dtidx_; // \in \{0,...,6\}
eStringUsi string_; // 7
short int dtidx_; // \in \{0,...,7\}
public:
tdmdatatype(): sint16_(0), sint32_(0),
uint8_(0), uint16_(0), uint32_(0),
float32_(0.0), float64_(0.0),
float32_(0.0), float64_(0.0), string_(0),
dtidx_(0) { };
// every supported datatype gets its own constructor
tdmdatatype(eInt16Usi num): sint16_(num), dtidx_(0) {};
@ -41,6 +43,7 @@ public:
tdmdatatype(eUInt32Usi num): uint32_(num), dtidx_(4) {};
tdmdatatype(eFloat32Usi num): float32_(num), dtidx_(5) {};
tdmdatatype(eFloat64Usi num): float64_(num), dtidx_(6) {};
tdmdatatype(eStringUsi num): string_(num), dtidx_(7) {};
// identify type
short int& dtype() { return dtidx_; }
@ -55,6 +58,7 @@ public:
this->uint32_ = num.uint32_;
this->float32_ = num.float32_;
this->float64_ = num.float64_;
this->string_ = num.string_;
this->dtidx_ = num.dtidx_;
}
@ -70,6 +74,7 @@ public:
this->uint32_ = num.uint32_;
this->float32_ = num.float32_;
this->float64_ = num.float64_;
this->string_ = num.string_;
this->dtidx_ = num.dtidx_;
}
@ -119,6 +124,12 @@ public:
this->dtidx_ = 6;
return *this;
}
tdmdatatype& operator=(const eStringUsi &num)
{
this->string_ = num;
this->dtidx_ = 7;
return *this;
}
// obtain number as double
double as_double()
@ -131,6 +142,7 @@ public:
else if ( dtidx_ == 4 ) num = (double)uint32_;
else if ( dtidx_ == 5 ) num = (double)float32_;
else if ( dtidx_ == 6 ) num = (double)float64_;
else if ( dtidx_ == 7 ) num = (double)(int)string_;
return num;
}
@ -144,6 +156,7 @@ public:
else if ( num.dtidx_ == 4 ) out<<num.uint32_;
else if ( num.dtidx_ == 5 ) out<<num.float32_;
else if ( num.dtidx_ == 6 ) out<<num.float64_;
else if ( num.dtidx_ == 7 ) out<<num.string_;
return out;
}
@ -332,7 +345,7 @@ const std::vector<tdm_datatype> tdm_datatypes = {
{"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"}
{"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
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
int num = 1;
machine_endianness_ = ( *(char*)&num == 1 );
if ( machine_endianness_ != endianness_ ) throw std::runtime_error("endianness mismatch");
machine_endianness_ = this->detect_endianness();
// if ( machine_endianness_ != endianness_ )
// {
// 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
for (pugi::xml_node anode: tdmincl.child("file").children())
@ -445,9 +464,14 @@ void tdm_termite::process_localcolumns(bool showlog, pugi::xml_document& xml_doc
{
locc.values_ = vl.at(0);
}
else if ( vl.size() == 0 )
{
//std::cerr<<"localcolumn ("<<locc.id_<<","<<locc.name_<<") misses any value-ids"<<"\n";
locc.values_ = "none";
}
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>
@ -460,7 +484,7 @@ void tdm_termite::process_localcolumns(bool showlog, pugi::xml_document& xml_doc
{
throw std::runtime_error(std::string("measurement_quantity: ")
+ locc.measurement_quantity_
+ std::string(" is ambiguous") );
+ std::string(" is missing/ambiguous") );
}
std::string dt = tdmchannels_.at(locc.measurement_quantity_).datatype_;
std::string sequence_type;
@ -482,8 +506,10 @@ void tdm_termite::process_localcolumns(bool showlog, pugi::xml_document& xml_doc
if ( locc.external_id_.empty() )
{
throw std::logic_error( std::string("no external id found for ")
+ sequence_type + std::string(" with ") + locc.values_ );
//throw std::logic_error( std::string("no external id found for ")
// + sequence_type + std::string(" with ") + locc.values_ );
//std::cerr<<"no external id found for "<<sequence_type<<" with "<<locc.values_<<"\n";
locc.external_id_ = "none";
}
}
@ -508,8 +534,8 @@ std::string tdm_termite::get_channel_overview(format chformatter)
// compose header
chformatter.set_header(true);
tdm_channelgroup grp;
channels_summary += grp.get_info(chformatter);
//tdm_channelgroup grp;
//channels_summary += grp.get_info(chformatter);
tdm_channel chn;
channels_summary += chn.get_info(chformatter);
std::string rule; // = std::string("#");
@ -526,8 +552,9 @@ std::string tdm_termite::get_channel_overview(format chformatter)
it!=tdmchannels_.end(); ++it)
{
// get corresponding group
tdm_channelgroup grp = tdmchannelgroups_.at(it->second.group_);
channels_summary += grp.get_info(chformatter);
// 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");
@ -619,7 +646,7 @@ std::vector<tdmdatatype> tdm_termite::get_channel(std::string& id)
// retrieve full channel info
tdm_channel chn = tdmchannels_.at(id);
// extract (first) "localcolumn" for channel
// extract (first) "localcolumn" for channel TODO there should only be a single!! local_column!!
if ( chn.local_columns_.size() != 1 )
{
throw std::runtime_error(std::string("invalid local_columns_ of channel: ") + id);
@ -636,8 +663,28 @@ std::vector<tdmdatatype> tdm_termite::get_channel(std::string& id)
}
// use "values" id to map to external block
if ( loccol.external_id_ == "none" )
{
//throw std::runtime_error(std::string("missing external_id in local_column ")+loccol.id_);
//std::cerr<<"missing external_id in local_column "<<loccol.id_<<"\n";
return std::vector<tdmdatatype>(0);
}
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
std::vector<tdmdatatype> datavec(blk.length_);
@ -691,6 +738,10 @@ std::vector<tdmdatatype> tdm_termite::get_channel(std::string& id)
{
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
{
throw std::runtime_error(std::string("unsupported/unknown datatype") + blk.value_type_);
@ -852,7 +903,7 @@ void tdm_termite::print_group(std::string &id, const char* filename, bool includ
for ( std::string chn: chngrp.channels_ )
{
std::vector<tdmdatatype> chndat = this->get_channel(chn);
if ( chndat.size() > maxrows ) maxrows = chndat.size();
if ( chndat.size() > maxrows ) maxrows = (unsigned int)chndat.size();
allchns.push_back(chndat);
}
@ -917,7 +968,7 @@ void tdm_termite::check_filename_path(const char* filename)
if ( !std::filesystem::is_directory(pt) )
{
throw std::runtime_error(std::string("directory does not exist: ") + pt.c_str() );
throw std::runtime_error( std::string("directory does not exist: ") + pt.u8string() );
}
}
@ -987,6 +1038,10 @@ void tdm_termite::check_datatype_consistency()
{
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
{
throw std::logic_error("missing datatype validation");
@ -1016,7 +1071,15 @@ void tdm_termite::convert_data_to_type(std::vector<unsigned char> &buffer,
for ( unsigned long int j = 0; j < sizeof(datatype); j++ )
{
dfcast[j] = (int)buffer[i*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];
}
else
{
dfcast[j] = (int)buffer[(i+1)*sizeof(datatype)-(j+1)];
}
}
// save number in channel

View File

@ -64,6 +64,29 @@ class tdm_termite
std::vector<unsigned char> tdxbuffer_;
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"))"
std::vector<std::string> extract_ids(std::string idstring)
{

104
makefile
View File

@ -13,15 +13,19 @@ HPP = $(wildcard lib/*.hpp)
CC = g++ -std=c++17
# 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
LIBB := 3rdparty/
LIB := $(foreach dir,$(shell ls $(LIBB)),-I $(LIBB)$(dir))
# 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")
GHSH := $(shell git rev-parse HEAD | head -c8)
GVSN := $(shell cat python/VERSION | tr -d ' \n')
# current timestamp
TMS = $(shell date +%Y%m%dT%H%M%S)
# define install location
INST := /usr/local/bin
@ -31,33 +35,39 @@ OST := $(shell uname)
CWD := $(shell pwd)
# --------------------------------------------------------------------------- #
# CLI tool
# C++ and CLI tool
$(EXE) : main.o $(SRC).o
# check tags and build executable
exec: check-tags $(GVSN) $(EXE)
# build executable
$(EXE): $(SRC).o main.o
$(CC) $(OPT) $^ -o $@
install : $(EXE)
cp $< $(INST)/
uninstall : $(INST)/$(EXE)
rm $<
$(SRC).o : lib/$(SRC).cpp lib/$(SRC).hpp $(HPP)
$(CC) -c $(OPT) $(LIB) $< -o $@
# 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
@if [ $(OST) = "Linux" ]; then\
sed -i 's/TAGSTRING/$(GTAG)/g' $<.cpp; \
sed -i 's/HASHSTRING/$(GHSH)/g' $<.cpp; \
sed -i 's/TIMESTAMPSTRING/$(TMS)/g' $<.cpp; \
fi
@if [ $(OST) = "Darwin" ]; then\
sed -i '' 's/TAGSTRING/$(GTAG)/g' $<.cpp; \
sed -i '' 's/HASHSTRING/$(GHSH)/g' $<.cpp; \
sed -i '' 's/TIMESTAMPSTRING/$(TMS)/g' $<.cpp; \
fi
$(CC) -c $(OPT) $(LIB) -I lib/ $<.cpp -o $@
@rm $<.cpp
$(SRC).o : lib/$(SRC).cpp lib/$(SRC).hpp $(HPP)
$(CC) -c $(OPT) $(LIB) $< -o $@
install: $(EXE)
cp $< $(INST)/
uninstall : $(INST)/$(EXE)
rm $<
tdmtest : tdmtest.o
$(CC) $(OPT) $^ -o $@
@ -66,38 +76,19 @@ tdmtest.o : src/test.cpp lib/$(SRC).hpp $(HPP)
$(CC) -c $(OPT) $(LIB) -I lib/ $< -o $@
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 :
@ps aux | head -n1
@ps aux | grep $(EXE) | grep -v "grep"
$(GTAG):
@echo "consistent versions check successful: building $(GTAG)"
# --------------------------------------------------------------------------- #
# python/cython module
cython-requirements: cython/requirements.txt
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
check-tags:
@echo "latest git tag: $(GTAG)"
@echo "latest git hash: $(GHSH)"
@echo "python version: $(GVSN)"
# --------------------------------------------------------------------------- #
# docker
@ -114,17 +105,32 @@ docker-clean:
docker image remove tdmtermite
# --------------------------------------------------------------------------- #
# pip
# check process
pip-publish: cython-build
cd pip/ && make pip-publish
pip-test:
cd pip/ && make pip-test
checkps :
@ps aux | head -n1
@ps aux | grep $(EXE) | grep -v "grep"
# --------------------------------------------------------------------------- #
# python
clean : cpp-clean cython-clean
cd pip/ && make pip-clean
python-build: check-tags $(GVSN)
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 | head -n316 | tail -n306 > ./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 = 0.5
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,36 +0,0 @@
from setuptools import setup, Extension
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="TDMtermite",
version="1.0.0", #version,
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=['-std=c++17','-Wno-unused-variable'],
extra_link_args=['-std=c++17'],
)],
)

View File

@ -1,4 +1,4 @@
include *.hpp
include lib/*.hpp
include *.cpp
include *.pyx
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 re
# create 'tdm_termite' instance object
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 :
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
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
grpids = jack.get_channelgroup_ids()
# iterate through groups

View File

@ -1,12 +1,12 @@
import tdm_termite
import tdmtermite
# import numpy as np
import json
import re
# create 'tdm_termite' instance object
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 :
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
from libcpp.string cimport string
from libcpp.vector cimport vector
from libcpp cimport bool
cdef extern from "tdm_termite.cpp":
cdef extern from "lib/tdm_termite.cpp":
pass
cdef extern from "tdm_termite.hpp":
cdef cppclass tdm_termite:
cdef extern from "lib/tdm_termite.hpp":
cdef cppclass cpptdmtermite "tdm_termite":
# constructor(s)
tdm_termite() except +
tdm_termite(string tdmfile, string tdxfile) except +
cpptdmtermite() except +
cpptdmtermite(string tdmfile, string tdxfile) except +
# provide TDM files
void submit_files(string tdmfile, string tdxfile) except+
# get list of channel(-group) ids
vector[string] get_channelgroup_ids() except+
vector[string] get_channel_ids() except+
# get data of specific channel
vector[double] get_channel_as_double(string id) except+
# get meta-data
string get_channelgroup_info(string id) except+
string get_channel_info(string id) except+
# print a channel(-group)
void print_group(string id, const char* filename, bool include_meta,
char delimiter, string column_header) except+

View File

@ -1,51 +1,52 @@
# distutils: language = c++
# cython: language_level = 3
from tdmtermite cimport cpptdmtermite
from tdm_termite cimport tdm_termite
import json as jn
# import numpy as np
cdef class tdmtermite:
# C++ instance of class => stack allocated (requires nullary constructor!)
cdef tdm_termite cpp_tdm
cdef cpptdmtermite cpptdm
# constructor
def __cinit__(self, string tdmfile, string tdxfile):
self.cpp_tdm = tdm_termite(tdmfile,tdxfile)
self.cpptdm = cpptdmtermite(tdmfile,tdxfile)
# provide TDM files
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
def get_channelgroup_ids(self):
return self.cpp_tdm.get_channelgroup_ids()
return self.cpptdm.get_channelgroup_ids()
def get_channel_ids(self):
return self.cpp_tdm.get_channel_ids()
return self.cpptdm.get_channel_ids()
# get data of specific channel
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)
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())
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())
# print a channel(-group)
def print_channelgroup(self, string id, const char* filename, bool include_meta,
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,
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
def write_all(self, string outputdir) :
grpids = self.cpp_tdm.get_channelgroup_ids()
grpids = self.cpptdm.get_channelgroup_ids()
for id in grpids :
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;
}

View File

@ -11,11 +11,12 @@
const std::string gittag("TAGSTRING");
const std::string githash("HASHSTRING");
const std::string timestamp("TIMESTAMPSTRING");
void show_usage()
{
std::cout<<"\n"
<<"tdmtermite ["<<gittag<<"-g"<<githash<<"] (github.com/RecordEvolution/TDMtermite.git)"
<<"tdmtermite ["<<gittag<<"-g"<<githash<<"-"<<timestamp<<"] (https://github.com/RecordEvolution/TDMtermite.git)"
<<"\n\n"
<<"Decode TDM/TDX files and dump data as *.csv"
<<"\n\n"
@ -78,7 +79,7 @@ optkeys parse_args(int argc, char* argv[], bool showargs = false)
else if ( std::string(argv[1]) == std::string("--version")
|| std::string(argv[1]) == std::string("-v") )
{
std::cout<<"tdmtermite "<<gittag<<"-g"<<githash<<"\n";
std::cout<<"tdmtermite "<<gittag<<"-g"<<githash<<"-"<<timestamp<<"\n";
}
else
{
@ -284,13 +285,13 @@ int main(int argc, char* argv[])
if ( showroot ) std::cout<<"\n"<<jack.get_root().get_info()<<"\n";
// get complete channel(-group) overview
format grpformatter(26,false,false,' ');
format grpformatter(16,false,false,' ');
if (listgroups) std::cout<<"\n"<<jack.get_overview<tdm_channelgroup>(grpformatter)<<"\n";
format chformatter(14,false,false,' ');
format chformatter(16,false,false,' ');
if (listchannels) std::cout<<"\n"<<jack.get_channel_overview(chformatter)<<"\n";
// get complete submatrix/localcolumns overview
format formatter(18,false,false,' ');
format formatter(16,false,false,' ');
if (listblocks) std::cout<<jack.get_overview<block>(formatter)<<"\n";
if (listsubmatrices) std::cout<<jack.get_overview<submatrix>(formatter)<<"\n";
if (listlocalcolumns) std::cout<<jack.get_overview<localcolumn>(formatter)<<"\n";