-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #56 from adamreeve/tdms-writing
Implement writing TDMS files
- Loading branch information
Showing
18 changed files
with
1,243 additions
and
264 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
npTDMS API Reference | ||
==================== | ||
|
||
Reading TDMS Files | ||
------------------ | ||
|
||
.. module:: nptdms | ||
|
||
.. autoclass:: TdmsFile | ||
:members: | ||
|
||
.. automethod:: __init__ | ||
|
||
.. autoclass:: TdmsObject | ||
:members: | ||
|
||
Writing TDMS Files | ||
------------------ | ||
|
||
.. autoclass:: TdmsWriter | ||
:members: | ||
|
||
.. automethod:: __init__ | ||
|
||
.. autoclass:: RootObject | ||
:members: | ||
|
||
.. automethod:: __init__ | ||
|
||
.. autoclass:: GroupObject | ||
:members: | ||
|
||
.. automethod:: __init__ | ||
|
||
.. autoclass:: ChannelObject | ||
:members: | ||
|
||
.. automethod:: __init__ | ||
|
||
Data Types for Property Values | ||
------------------------------ | ||
|
||
.. module:: nptdms.types | ||
|
||
.. autoclass:: Int8 | ||
|
||
.. autoclass:: Int16 | ||
|
||
.. autoclass:: Int32 | ||
|
||
.. autoclass:: Int64 | ||
|
||
.. autoclass:: Uint8 | ||
|
||
.. autoclass:: Uint16 | ||
|
||
.. autoclass:: Uint32 | ||
|
||
.. autoclass:: Uint64 | ||
|
||
.. autoclass:: SingleFloat | ||
|
||
.. autoclass:: DoubleFloat | ||
|
||
.. autoclass:: String | ||
|
||
.. autoclass:: Boolean | ||
|
||
.. autoclass:: TimeStamp | ||
|
||
Indices and Tables | ||
------------------ | ||
|
||
* :ref:`genindex` | ||
* :ref:`modindex` | ||
* :ref:`search` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,18 @@ | ||
Welcome to npTDMS's documentation | ||
================================= | ||
|
||
npTDMS is a Python module for reading binary TDMS files produced by LabView, | ||
and is based on the | ||
`file format documentation <http://zone.ni.com/devzone/cda/tut/p/id/5696>`_ | ||
released by NI. | ||
|
||
Data is read from file directly into memory and is then interpreted as a | ||
NumPy array, so reading files should be very fast. | ||
|
||
Installation | ||
============ | ||
|
||
npTDMS is available from the Python Package Index, so the easiest way to | ||
install it is by running (as root):: | ||
|
||
pip install npTDMS | ||
|
||
Alternatively, after downloading the source code you can extract it and | ||
change into the new directory, then run:: | ||
|
||
python setup.py install | ||
|
||
Quick Start | ||
=========== | ||
|
||
Typical usage might look like:: | ||
|
||
#!/usr/bin/env python | ||
|
||
from nptdms import TdmsFile | ||
tdms_file = TdmsFile("path_to_file.tdms") | ||
channel = tdms_file.object('Group', 'Channel1') | ||
data = channel.data | ||
time = channel.time_track() | ||
# do stuff with data | ||
|
||
tdmsinfo Program | ||
================ | ||
|
||
npTDMS comes with a command line program, ``tdmsinfo``, which | ||
lists the contents of a TDMS file. | ||
Usage looks like:: | ||
|
||
tdmsinfo [--properties] tdms_file | ||
|
||
Passing the ``--properties`` or ``-p`` argument will include TDMS object | ||
properties in the printed information. | ||
|
||
What Doesn't Work | ||
================= | ||
|
||
Reading TDMS files with XML headers or files with | ||
extended floating point data currently does not work. | ||
|
||
Reference | ||
========= | ||
|
||
.. module:: nptdms.tdms | ||
|
||
.. autoclass:: TdmsFile | ||
:members: | ||
|
||
.. automethod:: __init__ | ||
|
||
.. autoclass:: TdmsObject | ||
:members: | ||
|
||
Indices and tables | ||
================== | ||
|
||
* :ref:`genindex` | ||
* :ref:`modindex` | ||
* :ref:`search` | ||
npTDMS is a cross-platform Python package for reading and writing TDMS files as produced by LabVIEW, | ||
and is built on top of the `numpy <http://www.numpy.org/>`__ package. | ||
Data read from a TDMS file is stored in numpy arrays, | ||
and numpy arrays are also used when writing TDMS file. | ||
|
||
Contents | ||
======== | ||
|
||
.. toctree:: | ||
quickstart | ||
reading | ||
writing | ||
apireference | ||
tdmsinfo | ||
limitations |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Limitations | ||
=========== | ||
|
||
npTDMS currently doesn't support reading TDMS files with XML headers, | ||
or files with extended floating point data. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
Installation and Quick Start | ||
============================ | ||
|
||
npTDMS is available from the Python Package Index, so the easiest way to | ||
install it is by running (as root):: | ||
|
||
pip install npTDMS | ||
|
||
Or you can install npTDMS as a non-root user inside your home directory:: | ||
|
||
pip install --user npTDMS | ||
|
||
Alternatively, after downloading the source code you can extract it and | ||
change into the new directory, then run:: | ||
|
||
python setup.py install | ||
|
||
Typical usage when reading a TDMS file might look like:: | ||
|
||
from nptdms import TdmsFile | ||
|
||
tdms_file = TdmsFile("path_to_file.tdms") | ||
channel = tdms_file.object('Group', 'Channel1') | ||
data = channel.data | ||
# do stuff with data | ||
|
||
And to write a TDMS file:: | ||
|
||
from nptdms import TdmsWriter, ChannelObject | ||
import numpy | ||
|
||
with TdmsWriter("path_to_file.tdms") as tdms_writer: | ||
data_array = numpy.linspace(0, 1, 10) | ||
channel = ChannelObject('Group', 'Channel1', data_array) | ||
tdms_writer.write_segment([channel]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
Reading TDMS files | ||
================== | ||
|
||
To read a TDMS file, create an instance of the :py:class:`nptdms.TdmsFile` | ||
class, passing the path to the file, or an already opened file to the ``__init__`` method:: | ||
|
||
tdms_file = TdmsFile("my_file.tdms") | ||
|
||
This will read the contents of the TDMS file, then the various objects | ||
in the file can be accessed using the | ||
:py:meth:`nptdms.TdmsFile.object` method. | ||
An object in a TDMS file is either the root object, a group object, or a channel | ||
object. | ||
Only channel objects contain data, but any object may have properties associated with it. | ||
|
||
The object returned by the ``object`` method is an instance of :py:class:`nptdms.TdmsObject`. | ||
If this is a channel containing data, you can access the data as a numpy array using its | ||
``data`` attribute:: | ||
|
||
channel_object = tdms_file.object("group_name", "channel_name") | ||
data = channel_object.data | ||
|
||
If the array is waveform data and has the ``wf_start_offset`` and ``wf_increment`` | ||
properties, you can get an array of relative time values for the data using the | ||
:py:meth:`nptdms.TdmsObject.time_track` method:: | ||
|
||
time = channel_object.time_track() | ||
|
||
You can also access the properties of an object using the :py:meth:`nptdms.TdmsObject.property` method, | ||
or the :py:attr:`nptdms.TdmsObject.properties` dictionary, for example:: | ||
|
||
# Iterate over all properties and print them | ||
for name, value in channel_object.properties.items(): | ||
print("{0}: {1}".format(name, value)) | ||
|
||
# Get a single property value | ||
property_value = channel_object.property("my_property_name") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
The tdmsinfo Command | ||
==================== | ||
|
||
npTDMS comes with a command line program, ``tdmsinfo``, which | ||
lists the contents of a TDMS file. | ||
Usage looks like:: | ||
|
||
tdmsinfo [--properties] tdms_file | ||
|
||
Passing the ``--properties`` or ``-p`` argument will include TDMS object | ||
properties in the printed information. | ||
|
||
The output of tdmsinfo including properties will look something like:: | ||
|
||
/ | ||
properties: | ||
name: test_file | ||
/'group_1' | ||
properties: | ||
group_property: property value | ||
/'group_1'/'channel_a' | ||
data type: tdsTypeU8 | ||
properties: | ||
wf_start_time: 2016-12-3014:56:00+00:00 | ||
wf_increment: 0.0005 | ||
wf_samples: 2000 | ||
|
||
There is also a ``--debug`` or ``-d`` argument that will output debug information | ||
to stderr, which can be useful when debugging a problem with a TDMS file. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
Writing TDMS files | ||
================== | ||
|
||
npTDMS has rudimentary support for writing TDMS files. | ||
The full set of optimisations supported by the TDMS file format for | ||
speeding up the writing of files and minimising file size are not | ||
implemented by npTDMS, but the basic functionality required to | ||
write TDMS files is available. | ||
|
||
To write a TDMS file, the :py:class:`nptdms.TdmsWriter` class is used, which | ||
should be used as a context manager. | ||
The ``__init__`` method accepts the path to the file to create, or a file | ||
that has already been opened in binary write mode:: | ||
|
||
with TdmsWriter("my_file.tdms") as tdms_writer: | ||
# write data | ||
|
||
The :py:meth:`nptdms.TdmsWriter.write_segment` method is used to write | ||
a segment of data to the TDMS file. Because the TDMS file format is designed | ||
for streaming data applications, it supports writing data one segment at a time | ||
as data becomes available. | ||
If you don't require this functionality you can simple call ``write_segment`` once | ||
with all of your data. | ||
|
||
The ``write_segment`` method takes a list of objects, each of which must be an | ||
instance of one of: | ||
|
||
- :py:class:`nptdms.RootObject`. This is the TDMS root object, and there may only be one root object in a segment. | ||
- :py:class:`nptdms.GroupObject`. This is used to group the channel objects. | ||
- :py:class:`nptdms.ChannelObject`. An object that contains data. | ||
- :py:class:`nptdms.TdmsObject`. A TDMS object that was read from a TDMS file using :py:class:`nptdms.TdmsFile`. | ||
|
||
Each of ``RootObject``, ``GroupObject`` and ``ChannelObject`` | ||
may optionally have properties associated with them, which | ||
are passed into the ``__init__`` method as a dictionary. | ||
The data types supported as property values are: | ||
|
||
- Integers | ||
- Floating point values | ||
- Strings | ||
- datetime objects | ||
- Boolean values | ||
|
||
For more control over the data type used to represent a property value, for example | ||
to use an unsigned integer type, you can pass an instance of one of the data types | ||
from the :py:mod:`nptdms.types` module. | ||
|
||
A complete example of writing a TDMS file with various object types and properties | ||
is given below:: | ||
|
||
from nptdms import TdmsWriter, RootObject, GroupObject, ChannelObject | ||
|
||
root_object = RootObject(properties={ | ||
"prop1": "foo", | ||
"prop2": 3, | ||
}) | ||
group_object = GroupObject("group_1", properties={ | ||
"prop1": 1.2345, | ||
"prop2": False, | ||
}) | ||
data = np.array([1.0, 2.0, 3.0, 4.0, 5.0]) | ||
channel_object = ChannelObject("group_1", "channel_1", data, properties={}) | ||
|
||
with TdmsWriter("my_file.tdms") as tdms_writer: | ||
tdms_writer.write_segment([ | ||
root_object, | ||
group_object, | ||
channel_object]) | ||
|
||
You could also read a TDMS file and then re-write it by passing :py:class:`nptdms.TdmsObject` | ||
instances to the ``write_segment`` method. If you want | ||
to only copy certain objects for example, you could do something like:: | ||
|
||
from nptdms import TdmsFile, TdmsWriter | ||
|
||
original_file = TdmsFile("original_file.tdms") | ||
|
||
with TdmsWriter("copied_file.tdms") as copied_file: | ||
objects_to_copy = [obj for obj in original_file.objects.values() if include_object(obj)] | ||
copied_file.write_segment(objects_to_copy) |
Oops, something went wrong.