complete cython interface, python example usage.py

This commit is contained in:
Mario Fink 2021-01-26 13:21:54 +01:00
parent 52115139bb
commit 00528e9460
7 changed files with 145 additions and 6 deletions

View File

@ -1,7 +1,8 @@
# distutils: language = c++ # distutils: language = c++
from tdm_reaper cimport tdm_reaper from tdm_reaper cimport tdm_reaper
# import numpy as np import json as jsn
import numpy as np
# import re # import re
# import os # import os
@ -14,6 +15,26 @@ cdef class tdmreaper:
def __cinit__(self, string tdmfile, string tdxfile): def __cinit__(self, string tdmfile, string tdxfile):
self.cpp_tdm = tdm_reaper(tdmfile,tdxfile) self.cpp_tdm = tdm_reaper(tdmfile,tdxfile)
# provide TDM files
def submit_files(self,string tdmfile, string tdxfile):
self.cpp_tdm.submit_files(tdmfile,tdxfile)
# get list of channel(-group) ids
def get_channelgroup_ids(self):
return self.cpp_tdm.get_channelgroup_ids()
def get_channel_ids(self):
return self.cpp_tdm.get_channel_ids()
# get data of specific channel
def get_channel(self, string id):
return self.cpp_tdm.get_channel_as_double(id)
# get meta-data of channel(-group)
def get_channelgroup_info(self, string id):
return self.cpp_tdm.get_channelgroup_info(id)
def get_channel_info(self, string id):
return self.cpp_tdm.get_channel_info(id)
# def set_file(self, string rawfile): # def set_file(self, string rawfile):
# if not os.path.isfile(rawfile) : # if not os.path.isfile(rawfile) :
# raise ValueError("'" + str(rawfile) + "' does not exist") # raise ValueError("'" + str(rawfile) + "' does not exist")

View File

@ -2,8 +2,8 @@
# 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_reaper.cpp": cdef extern from "tdm_reaper.cpp":
pass pass
@ -13,7 +13,17 @@ cdef extern from "tdm_reaper.hpp":
# constructor(s) # constructor(s)
tdm_reaper() except + tdm_reaper() except +
tdm_reaper(string tdmfile, string tdxfile) except + tdm_reaper(string tdmfile, string tdxfile) except +
# set new file for decoding # 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+
# void set_file(string) # void set_file(string)
# # perform conversion (pass any C++ exceptions to Python) # # perform conversion (pass any C++ exceptions to Python)
# void setup_and_conversion() except + # void setup_and_conversion() except +

View File

@ -160,6 +160,17 @@ struct tdm_channelgroup {
return formatter.get_info(); return formatter.get_info();
} }
const std::string get_json()
{
std::stringstream ss;
ss<<"{"<<"\"group-id\":\""<<id_
<<"\",\"name\":\""<<name_
<<"\",\"description\":\""<<description_
<<"\",\"root\":\""<<root_
<<"\",\"channels\":\""<<join_strings(channels_)<<"\"}";
return ss.str();
}
}; };
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
@ -216,6 +227,20 @@ struct tdm_channel {
return formatter.get_info(); return formatter.get_info();
} }
const std::string get_json()
{
std::stringstream ss;
ss<<"{"<<"\"channel-id\":\""<<id_
<<"\",\"name\":\""<<name_
<<"\",\"description\":\""<<description_
<<"\",\"unit_string\":\""<<unit_string_
<<"\",\"datatype\":\""<<datatype_
<<"\",\"minimum\":\""<<minimum_
<<"\",\"maximum\":\""<<maximum_
<<"\",\"group\":\""<<group_<<"\"}";
return ss.str();
}
}; };
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //

View File

@ -104,6 +104,20 @@ public:
return *this; return *this;
} }
// obtain number as double
double as_double()
{
double num;
if ( dtidx_ == 0 ) num = (double)sint16_;
else if ( dtidx_ == 1 ) num = (double)sint32_;
else if ( dtidx_ == 2 ) num = (double)uint8_;
else if ( dtidx_ == 3 ) num = (double)uint16_;
else if ( dtidx_ == 4 ) num = (double)uint32_;
else if ( dtidx_ == 5 ) num = (double)float32_;
else if ( dtidx_ == 6 ) num = (double)float64_;
return num;
}
// define custom stream operator to print the correct type // define custom stream operator to print the correct type
friend std::ostream& operator<<(std::ostream& out, const tdmdatatype& num) friend std::ostream& operator<<(std::ostream& out, const tdmdatatype& num)
{ {

View File

@ -177,6 +177,34 @@ public:
// extract channel by id // extract channel by id
std::vector<tdmdatatype> get_channel(std::string& id); std::vector<tdmdatatype> get_channel(std::string& id);
// additional methods for Cython/Python compatibiliy
//
// extract and return any channel as datatype double
std::vector<double> get_channel_as_double(std::string id)
{
std::vector<tdmdatatype> tdmchn = this->get_channel(id);
std::vector<double> chn;
for ( tdmdatatype el: tdmchn ) chn.push_back(el.as_double());
return chn;
}
// get channel(-group) meta-data
std::string get_channelgroup_info(std::string id)
{
if ( tdmchannelgroups_.count(id) == 1 ) {
return tdmchannelgroups_.at(id).get_json();
} else {
throw std::runtime_error(std::string("channelgroup does not exist: ") + id);
}
}
std::string get_channel_info(std::string id)
{
if ( tdmchannels_.count(id) == 1 ) {
return tdmchannels_.at(id).get_json();
} else {
throw std::runtime_error(std::string("channel does not exist: ") + id);
}
}
// dump a single channel/entire group (identified by id) to file // dump a single channel/entire group (identified by id) to file
void print_channel(std::string &id, const char* filename, bool include_meta = true); void print_channel(std::string &id, const char* filename, bool include_meta = true);
void print_group(std::string &id, const char* filename, bool include_meta = true, char sep = ' '); void print_group(std::string &id, const char* filename, bool include_meta = true, char sep = ' ');

View File

@ -79,13 +79,14 @@ cython-list : cython/setup.py
cython-build : cython/setup.py cython/tdm_reaper.pxd cython/py_tdm_reaper.pyx $(HPP) lib/tdm_reaper.cpp cython-build : cython/setup.py cython/tdm_reaper.pxd cython/py_tdm_reaper.pyx $(HPP) lib/tdm_reaper.cpp
python3 $< build_ext --inplace python3 $< build_ext --inplace
# python3 $< build_ext cp -v tdm_reaper.cpython-*.so python/
cython-install : cython/setup.py cython/tdm_reaper.pyx cython/tdm_reaper.pyx cython-install : cython/setup.py cython/tdm_reaper.pyx cython/tdm_reaper.pyx
python3 $< install python3 $< install
clean-cython : clean-cython :
rm -vf cython/py_tdm_reaper.cpp tdm_reaper.cpython-*.so rm -vf cython/py_tdm_reaper.cpp
rm -vf tdm_reaper.cpython-*.so python/tdm_reaper.cpython-*.so
rm -rf build rm -rf build
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #

40
python/usage.py Normal file
View File

@ -0,0 +1,40 @@
import tdm_reaper
import numpy as np
import json
# create 'tdm_reaper' instance object
try :
jack = tdm_reaper.tdmreaper(b'samples/SineData.tdm',b'samples/SineData.tdx')
except RuntimeError as e:
print("failed to load/decode TDM files: " + str(e))
# list ids of channelgroups
grpids = jack.get_channelgroup_ids()
grpids = [x.decode() for x in grpids]
print("list of channelgroups: ",grpids)
# obtain meta data of channelgroups
for grp in grpids[0:2] :
grpinfostr = jack.get_channelgroup_info(grp.encode())
grpinfostr = grpinfostr.decode()
grpinfo = json.loads(grpinfostr)
print( json.dumps(grpinfo,sort_keys=False,indent=4) )
# list ids of channels
chnids = jack.get_channel_ids()
chnids = [x.decode() for x in chnids]
print("list of channels: ",chnids)
# get (meta-)data of channels
for chn in chnids[0:3] :
# obtain meta-data
chninfostr = jack.get_channel_info(chn.encode())
chninfostr = chninfostr.decode()
chninfo = json.loads(chninfostr)
print( json.dumps(chninfo,sort_keys=False,indent=4) )
# channel data
chndata = jack.get_channel(chn.encode())
print(str(chndata[0:6]) + " ...")