test_h5t.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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. import h5py
  11. from h5py import h5t
  12. from .common import TestCase, ut
  13. class TestCompound(ut.TestCase):
  14. """
  15. Feature: Compound types can be created from Python dtypes
  16. """
  17. def test_ref(self):
  18. """ Reference types are correctly stored in compound types (issue 144)
  19. """
  20. dt = np.dtype([('a', h5py.ref_dtype), ('b', '<f4')])
  21. tid = h5t.py_create(dt, logical=True)
  22. t1, t2 = tid.get_member_type(0), tid.get_member_type(1)
  23. self.assertEqual(t1, h5t.STD_REF_OBJ)
  24. self.assertEqual(t2, h5t.IEEE_F32LE)
  25. self.assertEqual(tid.get_member_offset(0), 0)
  26. self.assertEqual(tid.get_member_offset(1), h5t.STD_REF_OBJ.get_size())
  27. def test_out_of_order_offsets(self):
  28. size = 20
  29. type_dict = {
  30. 'names': ['f1', 'f2', 'f3'],
  31. 'formats': ['<f4', '<i4', '<f8'],
  32. 'offsets': [0, 16, 8]
  33. }
  34. expected_dtype = np.dtype(type_dict)
  35. tid = h5t.create(h5t.COMPOUND, size)
  36. for name, offset, dt in zip(
  37. type_dict["names"], type_dict["offsets"], type_dict["formats"]
  38. ):
  39. tid.insert(
  40. name.encode("utf8") if isinstance(name, str) else name,
  41. offset,
  42. h5t.py_create(dt)
  43. )
  44. self.assertEqual(tid.dtype, expected_dtype)
  45. self.assertEqual(tid.dtype.itemsize, size)
  46. class TestTypeFloatID(TestCase):
  47. """Test TypeFloatID."""
  48. def test_custom_float_promotion(self):
  49. """Custom floats are correctly promoted to standard floats on read."""
  50. # This test uses the low-level API, so we need names as byte strings
  51. test_filename = self.mktemp().encode()
  52. dataset = b'DS1'
  53. dataset2 = b'DS2'
  54. dataset3 = b'DS3'
  55. dataset4 = b'DS4'
  56. dataset5 = b'DS5'
  57. dims = (4, 7)
  58. wdata = np.array([[-1.50066626e-09, 1.40062184e-09, 1.81216819e-10,
  59. 4.01087163e-10, 4.27917257e-10, -7.04858394e-11,
  60. 5.74800652e-10],
  61. [-1.50066626e-09, 4.86579665e-10, 3.42879503e-10,
  62. 5.12045517e-10, 5.10226528e-10, 2.24190444e-10,
  63. 3.93356459e-10],
  64. [-1.50066626e-09, 5.24778443e-10, 8.19454726e-10,
  65. 1.28966349e-09, 1.68483894e-10, 5.71276360e-11,
  66. -1.08684617e-10],
  67. [-1.50066626e-09, -1.08343556e-10, -1.58934199e-10,
  68. 8.52196536e-10, 6.18456397e-10, 6.16637408e-10,
  69. 1.31694833e-09]], dtype=np.float32)
  70. wdata2 = np.array([[-1.50066626e-09, 5.63886715e-10, -8.74251782e-11,
  71. 1.32558853e-10, 1.59161573e-10, 2.29420039e-10,
  72. -7.24185156e-11],
  73. [-1.50066626e-09, 1.87810656e-10, 7.74889486e-10,
  74. 3.95630195e-10, 9.42236511e-10, 8.38554115e-10,
  75. -8.71978045e-11],
  76. [-1.50066626e-09, 6.20275387e-10, 7.34871719e-10,
  77. 6.64840627e-10, 2.64662958e-10, 1.05319486e-09,
  78. 1.68256520e-10],
  79. [-1.50066626e-09, 1.67347025e-10, 5.12045517e-10,
  80. 3.36513040e-10, 1.02545528e-10, 1.28784450e-09,
  81. 4.06089384e-10]], dtype=np.float32)
  82. # Create a new file using the default properties.
  83. fid = h5py.h5f.create(test_filename)
  84. # Create the dataspace. No maximum size parameter needed.
  85. space = h5py.h5s.create_simple(dims)
  86. # create a custom type with larger bias
  87. mytype = h5t.IEEE_F16LE.copy()
  88. mytype.set_fields(14, 9, 5, 0, 9)
  89. mytype.set_size(2)
  90. mytype.set_ebias(53)
  91. mytype.lock()
  92. dset = h5py.h5d.create(fid, dataset, mytype, space)
  93. dset.write(h5py.h5s.ALL, h5py.h5s.ALL, wdata)
  94. del dset
  95. # create a custom type with larger exponent
  96. mytype2 = h5t.IEEE_F16LE.copy()
  97. mytype2.set_fields(15, 9, 6, 0, 9)
  98. mytype2.set_size(2)
  99. mytype2.set_ebias(53)
  100. mytype2.lock()
  101. dset = h5py.h5d.create(fid, dataset2, mytype2, space)
  102. dset.write(h5py.h5s.ALL, h5py.h5s.ALL, wdata2)
  103. del dset
  104. # create a custom type which reimplements 16-bit floats
  105. mytype3 = h5t.IEEE_F16LE.copy()
  106. mytype3.set_fields(15, 10, 5, 0, 10)
  107. mytype3.set_size(2)
  108. mytype3.set_ebias(15)
  109. mytype3.lock()
  110. dset = h5py.h5d.create(fid, dataset3, mytype3, space)
  111. dset.write(h5py.h5s.ALL, h5py.h5s.ALL, wdata2)
  112. del dset
  113. # create a custom type with larger bias
  114. mytype4 = h5t.IEEE_F16LE.copy()
  115. mytype4.set_fields(15, 10, 5, 0, 10)
  116. mytype4.set_size(2)
  117. mytype4.set_ebias(258)
  118. mytype4.lock()
  119. dset = h5py.h5d.create(fid, dataset4, mytype4, space)
  120. dset.write(h5py.h5s.ALL, h5py.h5s.ALL, wdata2)
  121. del dset
  122. # create a dataset with long doubles
  123. dset = h5py.h5d.create(fid, dataset5, h5t.NATIVE_LDOUBLE, space)
  124. dset.write(h5py.h5s.ALL, h5py.h5s.ALL, wdata2)
  125. # Explicitly close and release resources.
  126. del space
  127. del dset
  128. del fid
  129. f = h5py.File(test_filename, 'r')
  130. # ebias promotion to float32
  131. values = f[dataset][:]
  132. np.testing.assert_array_equal(values, wdata)
  133. self.assertEqual(values.dtype, np.dtype('<f4'))
  134. # esize promotion to float32
  135. values = f[dataset2][:]
  136. np.testing.assert_array_equal(values, wdata2)
  137. self.assertEqual(values.dtype, np.dtype('<f4'))
  138. # regular half floats
  139. dset = f[dataset3]
  140. try:
  141. self.assertEqual(dset.dtype, np.dtype('<f2'))
  142. except AttributeError:
  143. self.assertEqual(dset.dtype, np.dtype('<f4'))
  144. # ebias promotion to float64
  145. dset = f[dataset4]
  146. self.assertEqual(dset.dtype, np.dtype('<f8'))
  147. # long double floats
  148. dset = f[dataset5]
  149. self.assertEqual(dset.dtype, np.longdouble)