test_dimension_scales.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. # This file is part of h5py, a Python interface to the HDF5 library.
  2. #
  3. # http://www.h5py.org
  4. #
  5. # Copyright 2008-2013 Andrew Collette and contributors
  6. #
  7. # License: Standard 3-clause BSD; see "license.txt" for full license terms
  8. # and contributor agreement.
  9. import numpy as np
  10. from .common import TestCase, is_main_thread, make_name
  11. from h5py import File
  12. import h5py
  13. class BaseDataset(TestCase):
  14. """
  15. data is a 3-dimensional dataset with dimensions [z, y, x]
  16. The z dimension is labeled. It does not have any attached scales.
  17. The y dimension is not labeled. It has one attached scale.
  18. The x dimension is labeled. It has two attached scales.
  19. data2 is a 3-dimensional dataset with no associated dimension scales.
  20. """
  21. def setUp(self):
  22. self.f = File(self.mktemp(), 'w')
  23. self.f['data'] = np.ones((4, 3, 2), 'f')
  24. self.f['data2'] = np.ones((4, 3, 2), 'f')
  25. self.f['x1'] = np.ones((2), 'f')
  26. h5py.h5ds.set_scale(self.f['x1'].id)
  27. h5py.h5ds.attach_scale(self.f['data'].id, self.f['x1'].id, 2)
  28. self.f['x2'] = np.ones((2), 'f')
  29. h5py.h5ds.set_scale(self.f['x2'].id, b'x2 name')
  30. h5py.h5ds.attach_scale(self.f['data'].id, self.f['x2'].id, 2)
  31. self.f['y1'] = np.ones((3), 'f')
  32. h5py.h5ds.set_scale(self.f['y1'].id, b'y1 name')
  33. h5py.h5ds.attach_scale(self.f['data'].id, self.f['y1'].id, 1)
  34. self.f['z1'] = np.ones((4), 'f')
  35. h5py.h5ds.set_label(self.f['data'].id, 0, b'z')
  36. h5py.h5ds.set_label(self.f['data'].id, 2, b'x')
  37. def tearDown(self):
  38. if self.f:
  39. self.f.close()
  40. class TestH5DSBindings(BaseDataset):
  41. """
  42. Feature: Datasets can be created from existing data
  43. """
  44. def test_create_dimensionscale(self):
  45. """ Create a dimension scale from existing dataset """
  46. self.assertTrue(h5py.h5ds.is_scale(self.f['x1'].id))
  47. self.assertEqual(h5py.h5ds.get_scale_name(self.f['x1'].id), b'')
  48. self.assertEqual(self.f['x1'].attrs['CLASS'], b"DIMENSION_SCALE")
  49. self.assertEqual(h5py.h5ds.get_scale_name(self.f['x2'].id), b'x2 name')
  50. def test_attach_dimensionscale(self):
  51. self.assertTrue(
  52. h5py.h5ds.is_attached(self.f['data'].id, self.f['x1'].id, 2)
  53. )
  54. self.assertFalse(
  55. h5py.h5ds.is_attached(self.f['data'].id, self.f['x1'].id, 1))
  56. self.assertEqual(h5py.h5ds.get_num_scales(self.f['data'].id, 0), 0)
  57. self.assertEqual(h5py.h5ds.get_num_scales(self.f['data'].id, 1), 1)
  58. self.assertEqual(h5py.h5ds.get_num_scales(self.f['data'].id, 2), 2)
  59. def test_detach_dimensionscale(self):
  60. name = make_name()
  61. self.f[name] = np.ones((4, 3, 2), 'f')
  62. ds = self.f[name]
  63. h5py.h5ds.attach_scale(ds.id, self.f['x1'].id, 2)
  64. h5py.h5ds.attach_scale(ds.id, self.f['x2'].id, 2)
  65. self.assertTrue(h5py.h5ds.is_attached(ds.id, self.f['x1'].id, 2))
  66. self.assertEqual(h5py.h5ds.get_num_scales(ds.id, 2), 2)
  67. h5py.h5ds.detach_scale(ds.id, self.f['x1'].id, 2)
  68. self.assertFalse(h5py.h5ds.is_attached(ds.id, self.f['x1'].id, 2))
  69. self.assertEqual(h5py.h5ds.get_num_scales(ds.id, 2), 1)
  70. def test_label_dimensionscale(self):
  71. self.assertEqual(h5py.h5ds.get_label(self.f['data'].id, 0), b'z')
  72. self.assertEqual(h5py.h5ds.get_label(self.f['data'].id, 1), b'')
  73. self.assertEqual(h5py.h5ds.get_label(self.f['data'].id, 2), b'x')
  74. def test_iter_dimensionscales(self):
  75. def func(dsid):
  76. res = h5py.h5ds.get_scale_name(dsid)
  77. if res == b'x2 name':
  78. return dsid
  79. res = h5py.h5ds.iterate(self.f['data'].id, 2, func, 0)
  80. self.assertEqual(h5py.h5ds.get_scale_name(res), b'x2 name')
  81. class TestDimensionManager(BaseDataset):
  82. def test_make_scale(self):
  83. # test recreating or renaming an existing scale:
  84. self.f['x1'].make_scale(b'foobar')
  85. self.assertEqual(self.f['data'].dims[2]['foobar'], self.f['x1'])
  86. # test creating entirely new scale:
  87. self.f['data2'].make_scale(b'foobaz')
  88. self.f['data'].dims[2].attach_scale(self.f['data2'])
  89. self.assertEqual(self.f['data'].dims[2]['foobaz'], self.f['data2'])
  90. def test_get_dimension(self):
  91. with self.assertRaises(IndexError):
  92. self.f['data'].dims[3]
  93. def test_len(self):
  94. self.assertEqual(len(self.f['data'].dims), 3)
  95. self.assertEqual(len(self.f['data2'].dims), 3)
  96. def test_iter(self):
  97. dims = self.f['data'].dims
  98. self.assertEqual(
  99. [d for d in dims],
  100. [dims[0], dims[1], dims[2]]
  101. )
  102. def test_repr(self):
  103. ds = self.f.create_dataset(make_name(), (2,3), "f4")
  104. self.assertIsInstance(repr(ds.dims), str)
  105. if is_main_thread():
  106. self.f.close()
  107. self.assertIsInstance(repr(ds.dims), str)
  108. class TestDimensionsHighLevel(BaseDataset):
  109. def test_len(self):
  110. self.assertEqual(len(self.f['data'].dims[0]), 0)
  111. self.assertEqual(len(self.f['data'].dims[1]), 1)
  112. self.assertEqual(len(self.f['data'].dims[2]), 2)
  113. self.assertEqual(len(self.f['data2'].dims[0]), 0)
  114. self.assertEqual(len(self.f['data2'].dims[1]), 0)
  115. self.assertEqual(len(self.f['data2'].dims[2]), 0)
  116. def test_get_label(self):
  117. self.assertEqual(self.f['data'].dims[2].label, 'x')
  118. self.assertEqual(self.f['data'].dims[1].label, '')
  119. self.assertEqual(self.f['data'].dims[0].label, 'z')
  120. self.assertEqual(self.f['data2'].dims[2].label, '')
  121. self.assertEqual(self.f['data2'].dims[1].label, '')
  122. self.assertEqual(self.f['data2'].dims[0].label, '')
  123. def test_set_label(self):
  124. self.f['data'].dims[0].label = 'foo'
  125. self.assertEqual(self.f['data'].dims[2].label, 'x')
  126. self.assertEqual(self.f['data'].dims[1].label, '')
  127. self.assertEqual(self.f['data'].dims[0].label, 'foo')
  128. def test_attach_detach_scale(self):
  129. name = make_name('data3')
  130. self.f[name] = self.f['data'][...]
  131. ds = self.f[name]
  132. ds.dims[2].attach_scale(self.f["x1"])
  133. ds.dims[2].attach_scale(self.f["x2"])
  134. self.assertEqual(len(ds.dims[2]), 2)
  135. self.assertEqual(ds.dims[2][0], self.f["x1"])
  136. self.assertEqual(ds.dims[2][1], self.f["x2"])
  137. ds.dims[2].detach_scale(self.f["x1"])
  138. self.assertEqual(len(ds.dims[2]), 1)
  139. self.assertEqual(ds.dims[2][0], self.f["x2"])
  140. ds.dims[2].detach_scale(self.f["x2"])
  141. self.assertEqual(len(ds.dims[2]), 0)
  142. def test_get_dimension_scale(self):
  143. self.assertEqual(self.f['data'].dims[2][0], self.f['x1'])
  144. with self.assertRaises(RuntimeError):
  145. self.f['data2'].dims[2][0], self.f['x2']
  146. self.assertEqual(self.f['data'].dims[2][''], self.f['x1'])
  147. self.assertEqual(self.f['data'].dims[2]['x2 name'], self.f['x2'])
  148. def test_get_items(self):
  149. self.assertEqual(
  150. self.f['data'].dims[2].items(),
  151. [('', self.f['x1']), ('x2 name', self.f['x2'])]
  152. )
  153. def test_get_keys(self):
  154. self.assertEqual(self.f['data'].dims[2].keys(), ['', 'x2 name'])
  155. def test_get_values(self):
  156. self.assertEqual(
  157. self.f['data'].dims[2].values(),
  158. [self.f['x1'], self.f['x2']]
  159. )
  160. def test_iter(self):
  161. self.assertEqual([i for i in self.f['data'].dims[2]], ['', 'x2 name'])
  162. def test_repr(self):
  163. ds = self.f["data"]
  164. self.assertEqual(repr(ds.dims[2])[1:16], '"x" dimension 2')
  165. if is_main_thread():
  166. self.f.close()
  167. self.assertIsInstance(repr(ds.dims), str)
  168. def test_attributes(self):
  169. self.f["data2"].attrs["DIMENSION_LIST"] = self.f["data"].attrs[
  170. "DIMENSION_LIST"]
  171. self.assertEqual(len(self.f['data2'].dims[0]), 0)
  172. self.assertEqual(len(self.f['data2'].dims[1]), 1)
  173. self.assertEqual(len(self.f['data2'].dims[2]), 2)
  174. def test_is_scale(self):
  175. """Test Dataset.is_scale property"""
  176. self.assertTrue(self.f['x1'].is_scale)
  177. self.assertTrue(self.f['x2'].is_scale)
  178. self.assertTrue(self.f['y1'].is_scale)
  179. self.assertFalse(self.f['z1'].is_scale)
  180. self.assertFalse(self.f['data'].is_scale)
  181. self.assertFalse(self.f['data2'].is_scale)