tdms 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +10 -0
  3. data/LICENSE.txt +25 -0
  4. data/README.md +34 -0
  5. data/Rakefile +15 -0
  6. data/demo.rb +16 -0
  7. data/doc/data_types.txt +23 -0
  8. data/doc/example_disasm.txt +47 -0
  9. data/doc/tdms_format.txt +101 -0
  10. data/doc/usage.txt +46 -0
  11. data/lib/tdms.rb +8 -0
  12. data/lib/tdms/aggregate.rb +71 -0
  13. data/lib/tdms/channel.rb +100 -0
  14. data/lib/tdms/datatypes.rb +173 -0
  15. data/lib/tdms/document.rb +114 -0
  16. data/lib/tdms/path.rb +58 -0
  17. data/lib/tdms/property.rb +17 -0
  18. data/lib/tdms/segment.rb +12 -0
  19. data/lib/tdms/streaming.rb +82 -0
  20. data/test/build_fixtures/README.txt +25 -0
  21. data/test/build_fixtures/type_01_int8_one_segment.vi +0 -0
  22. data/test/build_fixtures/type_01_int8_three_segments.vi +0 -0
  23. data/test/build_fixtures/type_01_int8_two_channels_one_segment.vi +0 -0
  24. data/test/build_fixtures/type_02_int16_one_segment.vi +0 -0
  25. data/test/build_fixtures/type_02_int16_three_segments.vi +0 -0
  26. data/test/build_fixtures/type_02_int16_two_channels_one_segment.vi +0 -0
  27. data/test/build_fixtures/type_03_int32_one_segment.vi +0 -0
  28. data/test/build_fixtures/type_03_int32_three_segments.vi +0 -0
  29. data/test/build_fixtures/type_03_int32_two_channels_one_segment.vi +0 -0
  30. data/test/build_fixtures/type_04_int64_one_segment.vi +0 -0
  31. data/test/build_fixtures/type_04_int64_three_segments.vi +0 -0
  32. data/test/build_fixtures/type_04_int64_two_channels_one_segment.vi +0 -0
  33. data/test/build_fixtures/type_05_uint8_one_segment.vi +0 -0
  34. data/test/build_fixtures/type_05_uint8_three_segments.vi +0 -0
  35. data/test/build_fixtures/type_05_uint8_two_channels_one_segment.vi +0 -0
  36. data/test/build_fixtures/type_06_uint16_one_segment.vi +0 -0
  37. data/test/build_fixtures/type_06_uint16_three_segments.vi +0 -0
  38. data/test/build_fixtures/type_06_uint16_two_channels_one_segment.vi +0 -0
  39. data/test/build_fixtures/type_07_uint32_one_segment.vi +0 -0
  40. data/test/build_fixtures/type_07_uint32_three_segments.vi +0 -0
  41. data/test/build_fixtures/type_07_uint32_two_channels_one_segment.vi +0 -0
  42. data/test/build_fixtures/type_08_uint64_one_segment.vi +0 -0
  43. data/test/build_fixtures/type_08_uint64_three_segments.vi +0 -0
  44. data/test/build_fixtures/type_08_uint64_two_channels_one_segment.vi +0 -0
  45. data/test/build_fixtures/type_09_single_one_segment.vi +0 -0
  46. data/test/build_fixtures/type_09_single_three_segments.vi +0 -0
  47. data/test/build_fixtures/type_09_single_two_channels_one_segment.vi +0 -0
  48. data/test/build_fixtures/type_0a_double_one_segment.vi +0 -0
  49. data/test/build_fixtures/type_0a_double_three_segments.vi +0 -0
  50. data/test/build_fixtures/type_0a_double_two_channels_one_segment.vi +0 -0
  51. data/test/build_fixtures/type_20_string_one_segment.vi +0 -0
  52. data/test/build_fixtures/type_20_string_three_segments.vi +0 -0
  53. data/test/build_fixtures/type_20_string_two_channels_one_segment.vi +0 -0
  54. data/test/build_fixtures/type_21_boolean_one_segment.vi +0 -0
  55. data/test/build_fixtures/type_21_boolean_three_segments.vi +0 -0
  56. data/test/build_fixtures/type_21_boolean_two_channels_one_segment.vi +0 -0
  57. data/test/build_fixtures/type_44_datetime_one_segment.vi +0 -0
  58. data/test/build_fixtures/type_44_timestamp_three_segments.vi +0 -0
  59. data/test/build_fixtures/type_44_timestamp_two_channels_one_segment.vi +0 -0
  60. data/test/fixtures/example.tdms +0 -0
  61. data/test/fixtures/type_01_int8_one_segment.tdms +0 -0
  62. data/test/fixtures/type_01_int8_three_segments.tdms +0 -0
  63. data/test/fixtures/type_01_int8_two_channels_one_segment.tdms +0 -0
  64. data/test/fixtures/type_02_int16_one_segment.tdms +0 -0
  65. data/test/fixtures/type_02_int16_three_segments.tdms +0 -0
  66. data/test/fixtures/type_02_int16_two_channels_one_segment.tdms +0 -0
  67. data/test/fixtures/type_03_int32_one_segment.tdms +0 -0
  68. data/test/fixtures/type_03_int32_three_segments.tdms +0 -0
  69. data/test/fixtures/type_03_int32_two_channels_one_segment.tdms +0 -0
  70. data/test/fixtures/type_04_int64_one_segment.tdms +0 -0
  71. data/test/fixtures/type_04_int64_three_segments.tdms +0 -0
  72. data/test/fixtures/type_04_int64_two_channels_one_segment.tdms +0 -0
  73. data/test/fixtures/type_05_uint8_one_segment.tdms +0 -0
  74. data/test/fixtures/type_05_uint8_three_segments.tdms +0 -0
  75. data/test/fixtures/type_05_uint8_two_channels_one_segment.tdms +0 -0
  76. data/test/fixtures/type_06_uint16_one_segment.tdms +0 -0
  77. data/test/fixtures/type_06_uint16_three_segments.tdms +0 -0
  78. data/test/fixtures/type_06_uint16_two_channels_one_segment.tdms +0 -0
  79. data/test/fixtures/type_07_uint32_one_segment.tdms +0 -0
  80. data/test/fixtures/type_07_uint32_three_segments.tdms +0 -0
  81. data/test/fixtures/type_07_uint32_two_channels_one_segment.tdms +0 -0
  82. data/test/fixtures/type_08_uint64_one_segment.tdms +0 -0
  83. data/test/fixtures/type_08_uint64_three_segments.tdms +0 -0
  84. data/test/fixtures/type_08_uint64_two_channels_one_segment.tdms +0 -0
  85. data/test/fixtures/type_09_single_one_segment.tdms +0 -0
  86. data/test/fixtures/type_09_single_three_segments.tdms +0 -0
  87. data/test/fixtures/type_09_single_two_channels_one_segment.tdms +0 -0
  88. data/test/fixtures/type_0a_double_one_segment.tdms +0 -0
  89. data/test/fixtures/type_0a_double_three_segments.tdms +0 -0
  90. data/test/fixtures/type_0a_double_two_channels_one_segment.tdms +0 -0
  91. data/test/fixtures/type_19_single_with_unit_one_segment.tdms +0 -0
  92. data/test/fixtures/type_19_single_with_unit_three_segments.tdms +0 -0
  93. data/test/fixtures/type_19_single_with_unit_two_channels_one_segment.tdms +0 -0
  94. data/test/fixtures/type_1a_double_with_unit_one_segment.tdms +0 -0
  95. data/test/fixtures/type_1a_double_with_unit_three_segments.tdms +0 -0
  96. data/test/fixtures/type_1a_double_with_unit_two_channels_one_segment.tdms +0 -0
  97. data/test/fixtures/type_20_double_two_channels_one_segment.tdms +0 -0
  98. data/test/fixtures/type_20_string_one_segment.tdms +0 -0
  99. data/test/fixtures/type_20_string_three_segments.tdms +0 -0
  100. data/test/fixtures/type_20_string_two_channels_one_segment.tdms +0 -0
  101. data/test/fixtures/type_20_string_two_segments.tdms +0 -0
  102. data/test/fixtures/type_21_boolean_one_segment.tdms +0 -0
  103. data/test/fixtures/type_21_boolean_three_segments.tdms +0 -0
  104. data/test/fixtures/type_21_boolean_two_channels_one_segment.tdms +0 -0
  105. data/test/fixtures/type_44_timestamp_one_segment.tdms +0 -0
  106. data/test/fixtures/type_44_timestamp_three_segments.tdms +0 -0
  107. data/test/fixtures/type_44_timestamp_two_channels_one_segment.tdms +0 -0
  108. data/test/read_type_01_int8_test.rb +58 -0
  109. data/test/read_type_02_int16_test.rb +58 -0
  110. data/test/read_type_03_int32_test.rb +58 -0
  111. data/test/read_type_04_int64_test.rb +64 -0
  112. data/test/read_type_05_uint8_test.rb +56 -0
  113. data/test/read_type_06_uint16_test.rb +58 -0
  114. data/test/read_type_07_uint32_test.rb +58 -0
  115. data/test/read_type_08_uint64_test.rb +58 -0
  116. data/test/read_type_09_single_test.rb +58 -0
  117. data/test/read_type_0a_double_test.rb +58 -0
  118. data/test/read_type_19_single_with_unit_test.rb +58 -0
  119. data/test/read_type_1a_double_with_unit_test.rb +58 -0
  120. data/test/read_type_20_string_test.rb +60 -0
  121. data/test/read_type_21_boolean_test.rb +56 -0
  122. data/test/read_type_44_timestamp_test.rb +60 -0
  123. data/test/test_helper.rb +9 -0
  124. metadata +284 -0
@@ -0,0 +1,25 @@
1
+ This directory contains VIs for LabVIEW 2010 that are used to
2
+ build the test fixtures.
3
+
4
+ LabVIEW 2010 saves floats with units (tdsTypeSingleFloatWithUnit,
5
+ tdsTypeDoubleFloatWithUnit, tdsTypeExtendedTypeWithUnit) with the
6
+ channel data type as floats without units.
7
+ These fixtures were made by hand:
8
+
9
+ tdsTypeSingleFloatWithUnit
10
+ Fixtures type_19_*.tdms are the same as type_09_*.tdms but the
11
+ channel data type was edited from tdsTypeSingleFloat (0x09) to
12
+ tdsTypeSingleFloatWithUnit (0x19).
13
+
14
+ tdsTypeDoubleFloatWithUnit
15
+ Fixtures type_1a_*.tdms are the same as type_0a_*.tdms but the
16
+ channel data type was edited from tdsTypeDoubleFloat (0x0A) to
17
+ tdsTypeDoubleFloatWithUnit (0x1A).
18
+
19
+ LabVIEW 2010 saves booleans (tdsTypeBoolean) as 8-bit unsigned
20
+ integers (tdsTypeU8). These fixtures were made by hand:
21
+
22
+ tdsTypeBoolean
23
+ Each type_21_*.tdms fixture was made by running the corresponding
24
+ VI but the channel data type was edited from tdsTypeU8 (0x05)
25
+ to tdsTypeBoolean (0x21).
@@ -0,0 +1,58 @@
1
+ class ReadType01Int8Test < Test::Unit::TestCase
2
+
3
+ def test_reads_one_int8_channel_in_one_segment
4
+ filename = fixture_filename("type_01_int8_one_segment")
5
+ doc = Tdms::File.parse(filename)
6
+
7
+ assert_equal 1, doc.segments.size
8
+ assert_equal 1, doc.segments[0].objects.size
9
+ assert_equal Tdms::DataType::Int8::Id, doc.segments[0].objects[0].data_type_id
10
+
11
+ chan = doc.channels.find {|ch| ch.path == "/'int8_group'/'int8_channel'" }
12
+ assert_equal 5, chan.values.size
13
+
14
+ expected = [-128, -64, 0, 63, 127]
15
+ assert_equal expected, chan.values.to_a
16
+ end
17
+
18
+ def test_reads_two_int8_channels_in_one_segment
19
+ filename = fixture_filename("type_01_int8_two_channels_one_segment")
20
+ doc = Tdms::File.parse(filename)
21
+
22
+ assert_equal 1, doc.segments.size
23
+ assert_equal 2, doc.segments[0].objects.size
24
+ assert_equal Tdms::DataType::Int8::Id, doc.segments[0].objects[0].data_type_id
25
+ assert_equal Tdms::DataType::Int8::Id, doc.segments[0].objects[1].data_type_id
26
+
27
+ chan = doc.channels.find {|ch| ch.path == "/'int8_group'/'int8_channel_a'" }
28
+ assert_equal 5, chan.values.size
29
+ expected = [-128, -64, 0, 63, 127]
30
+ assert_equal expected, chan.values.to_a
31
+
32
+ chan = doc.channels.find {|ch| ch.path == "/'int8_group'/'int8_channel_b'" }
33
+ assert_equal 5, chan.values.size
34
+ expected = [127, 63, 0, -64, -128]
35
+ assert_equal expected, chan.values.to_a
36
+ end
37
+
38
+ def test_reads_one_int8_channel_across_three_segments
39
+ filename = fixture_filename("type_01_int8_three_segments")
40
+ doc = Tdms::File.parse(filename)
41
+
42
+ assert_equal 3, doc.segments.size
43
+ assert_equal 1, doc.segments[0].objects.size
44
+ assert_equal 1, doc.segments[1].objects.size
45
+ assert_equal 1, doc.segments[2].objects.size
46
+ assert_equal Tdms::DataType::Int8::Id, doc.segments[0].objects[0].data_type_id
47
+ assert_equal Tdms::DataType::Int8::Id, doc.segments[1].objects[0].data_type_id
48
+ assert_equal Tdms::DataType::Int8::Id, doc.segments[2].objects[0].data_type_id
49
+
50
+ chan = doc.channels.find {|ch| ch.path == "/'int8_group'/'int8_channel'" }
51
+ assert_equal 15, chan.values.size
52
+ expected = [-128, -64, 0, 63, 127,
53
+ -128, -64, 0, 63, 127,
54
+ -128, -64, 0, 63, 127]
55
+ assert_equal expected, chan.values.to_a
56
+ end
57
+
58
+ end
@@ -0,0 +1,58 @@
1
+ class ReadType02Int16Test < Test::Unit::TestCase
2
+
3
+ def test_reads_one_int16_channel_in_one_segment
4
+ filename = fixture_filename("type_02_int16_one_segment")
5
+ doc = Tdms::File.parse(filename)
6
+
7
+ assert_equal 1, doc.segments.size
8
+ assert_equal 1, doc.segments[0].objects.size
9
+ assert_equal Tdms::DataType::Int16::Id, doc.segments[0].objects[0].data_type_id
10
+
11
+ chan = doc.channels.find {|ch| ch.path == "/'int16_group'/'int16_channel'" }
12
+ assert_equal 5, chan.values.size
13
+
14
+ expected = [-32_768, -16_384, 0, 16_383, 32_767]
15
+ assert_equal expected, chan.values.to_a
16
+ end
17
+
18
+ def test_reads_two_int16_channels_in_one_segment
19
+ filename = fixture_filename("type_02_int16_two_channels_one_segment")
20
+ doc = Tdms::File.parse(filename)
21
+
22
+ assert_equal 1, doc.segments.size
23
+ assert_equal 2, doc.segments[0].objects.size
24
+ assert_equal Tdms::DataType::Int16::Id, doc.segments[0].objects[0].data_type_id
25
+ assert_equal Tdms::DataType::Int16::Id, doc.segments[0].objects[1].data_type_id
26
+
27
+ chan = doc.channels.find {|ch| ch.path == "/'int16_group'/'int16_channel_a'" }
28
+ assert_equal 5, chan.values.size
29
+ expected = [-32_768, -16_384, 0, 16_383, 32_767]
30
+ assert_equal expected, chan.values.to_a
31
+
32
+ chan = doc.channels.find {|ch| ch.path == "/'int16_group'/'int16_channel_b'" }
33
+ assert_equal 5, chan.values.size
34
+ expected = [32_767, 16_383, 0, -16_384, -32_768]
35
+ assert_equal expected, chan.values.to_a
36
+ end
37
+
38
+ def test_reads_one_int16_channel_across_three_segments
39
+ filename = fixture_filename("type_02_int16_three_segments")
40
+ doc = Tdms::File.parse(filename)
41
+
42
+ assert_equal 3, doc.segments.size
43
+ assert_equal 1, doc.segments[0].objects.size
44
+ assert_equal 1, doc.segments[1].objects.size
45
+ assert_equal 1, doc.segments[2].objects.size
46
+ assert_equal Tdms::DataType::Int16::Id, doc.segments[0].objects[0].data_type_id
47
+ assert_equal Tdms::DataType::Int16::Id, doc.segments[1].objects[0].data_type_id
48
+ assert_equal Tdms::DataType::Int16::Id, doc.segments[2].objects[0].data_type_id
49
+
50
+ chan = doc.channels.find {|ch| ch.path == "/'int16_group'/'int16_channel'" }
51
+ assert_equal 15, chan.values.size
52
+ expected = [-32_768, -16_384, 0, 16_383, 32_767,
53
+ -32_768, -16_384, 0, 16_383, 32_767,
54
+ -32_768, -16_384, 0, 16_383, 32_767]
55
+ assert_equal expected, chan.values.to_a
56
+ end
57
+
58
+ end
@@ -0,0 +1,58 @@
1
+ class ReadType03Int32Test < Test::Unit::TestCase
2
+
3
+ def test_reads_one_int32_channel_in_one_segment
4
+ filename = fixture_filename("type_03_int32_one_segment")
5
+ doc = Tdms::File.parse(filename)
6
+
7
+ assert_equal 1, doc.segments.size
8
+ assert_equal 1, doc.segments[0].objects.size
9
+ assert_equal Tdms::DataType::Int32::Id, doc.segments[0].objects[0].data_type_id
10
+
11
+ chan = doc.channels.find {|ch| ch.path == "/'int32_group'/'int32_channel'" }
12
+ assert_equal 5, chan.values.size
13
+
14
+ expected = [-2_147_483_648, -1_073_741_824, 0, 10_737_41_823, 2_147_483_647]
15
+ assert_equal expected, chan.values.to_a
16
+ end
17
+
18
+ def test_reads_two_int32_channels_in_one_segment
19
+ filename = fixture_filename("type_03_int32_two_channels_one_segment")
20
+ doc = Tdms::File.parse(filename)
21
+
22
+ assert_equal 1, doc.segments.size
23
+ assert_equal 2, doc.segments[0].objects.size
24
+ assert_equal Tdms::DataType::Int32::Id, doc.segments[0].objects[0].data_type_id
25
+ assert_equal Tdms::DataType::Int32::Id, doc.segments[0].objects[1].data_type_id
26
+
27
+ chan = doc.channels.find {|ch| ch.path == "/'int32_group'/'int32_channel_a'" }
28
+ assert_equal 5, chan.values.size
29
+ expected = [-2_147_483_648, -1_073_741_824, 0, 10_737_41_823, 2_147_483_647]
30
+ assert_equal expected, chan.values.to_a
31
+
32
+ chan = doc.channels.find {|ch| ch.path == "/'int32_group'/'int32_channel_b'" }
33
+ assert_equal 5, chan.values.size
34
+ expected = [2_147_483_647, 1_073_741_823, 0, -1_073_741_824, -2_147_483_648]
35
+ assert_equal expected, chan.values.to_a
36
+ end
37
+
38
+ def test_reads_one_int32_channel_across_three_segments
39
+ filename = fixture_filename("type_03_int32_three_segments")
40
+ doc = Tdms::File.parse(filename)
41
+
42
+ assert_equal 3, doc.segments.size
43
+ assert_equal 1, doc.segments[0].objects.size
44
+ assert_equal 1, doc.segments[1].objects.size
45
+ assert_equal 1, doc.segments[2].objects.size
46
+ assert_equal Tdms::DataType::Int32::Id, doc.segments[0].objects[0].data_type_id
47
+ assert_equal Tdms::DataType::Int32::Id, doc.segments[1].objects[0].data_type_id
48
+ assert_equal Tdms::DataType::Int32::Id, doc.segments[2].objects[0].data_type_id
49
+
50
+ chan = doc.channels.find {|ch| ch.path == "/'int32_group'/'int32_channel'" }
51
+ assert_equal 15, chan.values.size
52
+ expected = [-2_147_483_648, -1_073_741_824, 0, 10_737_41_823, 2_147_483_647,
53
+ -2_147_483_648, -1_073_741_824, 0, 10_737_41_823, 2_147_483_647,
54
+ -2_147_483_648, -1_073_741_824, 0, 10_737_41_823, 2_147_483_647]
55
+ assert_equal expected, chan.values.to_a
56
+ end
57
+
58
+ end
@@ -0,0 +1,64 @@
1
+ class ReadType04Int64Test < Test::Unit::TestCase
2
+
3
+ def test_reads_one_int64_channel_in_one_segment
4
+ filename = fixture_filename("type_04_int64_one_segment")
5
+ doc = Tdms::File.parse(filename)
6
+
7
+ assert_equal 1, doc.segments.size
8
+ assert_equal 1, doc.segments[0].objects.size
9
+ assert_equal Tdms::DataType::Int64::Id, doc.segments[0].objects[0].data_type_id
10
+
11
+ chan = doc.channels.find {|ch| ch.path == "/'int64_group'/'int64_channel'" }
12
+ assert_equal 5, chan.values.size
13
+
14
+ expected = [-9_223_372_036_854_775_808, -4_611_686_018_427_387_904, 0,
15
+ 4_611_686_018_427_387_903, 9_223_372_036_854_775_807]
16
+ assert_equal expected, chan.values.to_a
17
+ end
18
+
19
+ def test_reads_two_int64_channels_in_one_segment
20
+ filename = fixture_filename("type_04_int64_two_channels_one_segment")
21
+ doc = Tdms::File.parse(filename)
22
+
23
+ assert_equal 1, doc.segments.size
24
+ assert_equal 2, doc.segments[0].objects.size
25
+ assert_equal Tdms::DataType::Int64::Id, doc.segments[0].objects[0].data_type_id
26
+ assert_equal Tdms::DataType::Int64::Id, doc.segments[0].objects[1].data_type_id
27
+
28
+ chan = doc.channels.find {|ch| ch.path == "/'int64_group'/'int64_channel_a'" }
29
+ assert_equal 5, chan.values.size
30
+ expected = [-9_223_372_036_854_775_808, -4_611_686_018_427_387_904, 0,
31
+ 4_611_686_018_427_387_903, 9_223_372_036_854_775_807]
32
+ assert_equal expected, chan.values.to_a
33
+
34
+ chan = doc.channels.find {|ch| ch.path == "/'int64_group'/'int64_channel_b'" }
35
+ assert_equal 5, chan.values.size
36
+ expected = [9_223_372_036_854_775_807, 4_611_686_018_427_387_903, 0,
37
+ -4_611_686_018_427_387_904, -9_223_372_036_854_775_808]
38
+ assert_equal expected, chan.values.to_a
39
+ end
40
+
41
+ def test_reads_one_int64_channel_across_three_segments
42
+ filename = fixture_filename("type_04_int64_three_segments")
43
+ doc = Tdms::File.parse(filename)
44
+
45
+ assert_equal 3, doc.segments.size
46
+ assert_equal 1, doc.segments[0].objects.size
47
+ assert_equal 1, doc.segments[1].objects.size
48
+ assert_equal 1, doc.segments[2].objects.size
49
+ assert_equal Tdms::DataType::Int64::Id, doc.segments[0].objects[0].data_type_id
50
+ assert_equal Tdms::DataType::Int64::Id, doc.segments[1].objects[0].data_type_id
51
+ assert_equal Tdms::DataType::Int64::Id, doc.segments[2].objects[0].data_type_id
52
+
53
+ chan = doc.channels.find {|ch| ch.path == "/'int64_group'/'int64_channel'" }
54
+ assert_equal 15, chan.values.size
55
+ expected = [-9_223_372_036_854_775_808, -4_611_686_018_427_387_904, 0,
56
+ 4_611_686_018_427_387_903, 9_223_372_036_854_775_807,
57
+ -9_223_372_036_854_775_808, -4_611_686_018_427_387_904, 0,
58
+ 4_611_686_018_427_387_903, 9_223_372_036_854_775_807,
59
+ -9_223_372_036_854_775_808, -4_611_686_018_427_387_904, 0,
60
+ 4_611_686_018_427_387_903, 9_223_372_036_854_775_807,]
61
+ assert_equal expected, chan.values.to_a
62
+ end
63
+
64
+ end