PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Tests/test_phenotype.py

http://github.com/biopython/biopython
Python | 319 lines | 249 code | 48 blank | 22 comment | 20 complexity | 9253bbdc6f20989cd059de319f8e25e4 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. # Copyright 2014-2016 Marco Galardini. All rights reserved.
  2. # Adapted from test_Mymodule.py by Jeff Chang
  3. #
  4. # This file is part of the Biopython distribution and governed by your
  5. # choice of the "Biopython License Agreement" or the "BSD 3-Clause License".
  6. # Please see the LICENSE file that should have been included as part of this
  7. # package.
  8. """Tests for the Bio.phenotype module."""
  9. try:
  10. import numpy
  11. del numpy
  12. except ImportError:
  13. from Bio import MissingExternalDependencyError
  14. raise MissingExternalDependencyError(
  15. "Install NumPy if you want to use Bio.phenotype."
  16. ) from None
  17. import json
  18. import unittest
  19. from io import StringIO
  20. from Bio import BiopythonExperimentalWarning
  21. import warnings
  22. with warnings.catch_warnings():
  23. warnings.simplefilter("ignore", BiopythonExperimentalWarning)
  24. from Bio import phenotype
  25. # Example plate files
  26. SMALL_JSON_PLATE = "phenotype/SmallPlate.json"
  27. SMALL_JSON_PLATE_2 = "phenotype/SmallPlate_2.json"
  28. JSON_PLATE = "phenotype/Plate.json"
  29. JSON_PLATE_2 = "phenotype/Plate_2.json"
  30. JSON_PLATE_3 = "phenotype/Plate_3.json"
  31. JSON_BAD = "phenotype/BadPlate.json"
  32. SMALL_CSV_PLATES = "phenotype/SmallPlates.csv"
  33. CSV_PLATES = "phenotype/Plates.csv"
  34. class TestPhenoMicro(unittest.TestCase):
  35. """Tests for phenotype support."""
  36. def test_phenotype_IO_errors(self):
  37. """Test bad arguments to phenotype IO methods."""
  38. self.assertRaises(ValueError, phenotype.read, CSV_PLATES, "pm-csv")
  39. self.assertRaises(ValueError, phenotype.read, CSV_PLATES, "pm-json")
  40. self.assertRaises(ValueError, phenotype.read, CSV_PLATES, "pm-noformat")
  41. self.assertRaises(ValueError, phenotype.read, CSV_PLATES, "PM-CSV")
  42. self.assertRaises(TypeError, phenotype.read, CSV_PLATES, 1)
  43. self.assertRaises(KeyError, phenotype.read, JSON_BAD, "pm-json")
  44. def test_phenotype_IO(self):
  45. """Test basic functionalities of phenotype IO methods."""
  46. p1 = phenotype.read(SMALL_JSON_PLATE, "pm-json")
  47. p2 = next(phenotype.parse(SMALL_CSV_PLATES, "pm-csv"))
  48. handle = StringIO()
  49. c = phenotype.write([p1, p2], handle, "pm-json")
  50. self.assertEqual(c, 2)
  51. handle.flush()
  52. handle.seek(0)
  53. # Now ready to read back from the handle...
  54. try:
  55. records = list(phenotype.parse(handle, "pm-json"))
  56. except ValueError as e:
  57. # This is BAD. We can't read our own output.
  58. # I want to see the output when called from the test harness,
  59. # run_tests.py (which can be funny about new lines on Windows)
  60. handle.seek(0)
  61. raise ValueError(
  62. "%s\n\n%s\n\n%s" % (str(e), repr(handle.read()), repr(records))
  63. ) from None
  64. self.assertEqual(p1, records[0])
  65. handle.close()
  66. handle = StringIO()
  67. self.assertRaises(TypeError, phenotype.write, p1, handle, 1)
  68. self.assertRaises(ValueError, phenotype.write, p1, handle, "PM-JSON")
  69. self.assertRaises(ValueError, phenotype.write, p1, handle, "pm-csv")
  70. handle.close()
  71. def test_PlateRecord_errors(self):
  72. """Test bad arguments with PlateRecord objects."""
  73. self.assertRaises(
  74. ValueError, phenotype.phen_micro.PlateRecord, "test", [1, 2, 3]
  75. )
  76. self.assertRaises(TypeError, phenotype.phen_micro.PlateRecord, "test", 1)
  77. def test_PlateRecord(self):
  78. """Test basic functionalities of PlateRecord objects."""
  79. with open(SMALL_JSON_PLATE) as handle:
  80. j = json.load(handle)
  81. p = phenotype.phen_micro.PlateRecord(j["csv_data"]["Plate Type"])
  82. times = j["measurements"]["Hour"]
  83. for k in j["measurements"]:
  84. if k == "Hour":
  85. continue
  86. p[k] = phenotype.phen_micro.WellRecord(
  87. k,
  88. signals={times[i]: j["measurements"][k][i] for i in range(len(times))},
  89. )
  90. del j["measurements"]
  91. p.qualifiers = j
  92. self.assertEqual(p.id, "PM01")
  93. self.assertEqual(len(p), 24)
  94. self.assertEqual(p.qualifiers, j)
  95. self.assertRaises(ValueError, p._is_well, "a")
  96. self.assertEqual(p["A01"].id, "A01")
  97. self.assertRaises(KeyError, p.__getitem__, "test")
  98. self.assertEqual(len(p[1]), 12)
  99. self.assertEqual(len(p[1:2:2]), 12)
  100. self.assertEqual(p[1, 2], p["B03"])
  101. self.assertEqual(len(p[:, 1]), 2)
  102. self.assertEqual(len(p[:, 1:4:2]), 4)
  103. self.assertRaises(TypeError, p.__getitem__, 1, 2, 3)
  104. self.assertRaises(IndexError, p.__getitem__, 13)
  105. self.assertRaises(ValueError, p.__setitem__, "A02", p["A01"])
  106. self.assertRaises(ValueError, p.__setitem__, "A02", "a")
  107. p["A02"] = p["A02"]
  108. for w in p:
  109. pass
  110. self.assertEqual("A01" in p, True)
  111. self.assertEqual("test" in p, False)
  112. self.assertRaises(ValueError, next, p.get_row("test"))
  113. self.assertEqual(next(p.get_row("A")), p["A01"])
  114. self.assertRaises(ValueError, next, p.get_column("test"))
  115. self.assertEqual(next(p.get_column("12")), p["A12"])
  116. self.assertEqual(next(p.get_column("1")), p["A01"])
  117. self.assertRaises(ValueError, p.subtract_control, "A121")
  118. self.assertRaises(ValueError, p.subtract_control, wells=["A121"])
  119. p2 = p.subtract_control()
  120. self.assertEqual(p2.id, p.id)
  121. self.assertEqual(p2["A02"], p["A02"] - p["A01"])
  122. self.assertEqual(
  123. repr(p),
  124. "PlateRecord('WellRecord['A01'], WellRecord['A02'], "
  125. "WellRecord['A03'], ..., WellRecord['B12']')",
  126. )
  127. self.assertEqual(
  128. str(p),
  129. "Plate ID: PM01\nWell: 24\nRows: 2\nColumns: 12\n"
  130. "PlateRecord('WellRecord['A01'], WellRecord['A02'], "
  131. "WellRecord['A03'], ..., WellRecord['B12']')",
  132. )
  133. with open(SMALL_JSON_PLATE_2) as handle:
  134. j = json.load(handle)
  135. p1 = phenotype.phen_micro.PlateRecord(j["csv_data"]["Plate Type"])
  136. times = j["measurements"]["Hour"]
  137. for k in j["measurements"]:
  138. if k == "Hour":
  139. continue
  140. p1[k] = phenotype.phen_micro.WellRecord(
  141. k,
  142. signals={times[i]: j["measurements"][k][i] for i in range(len(times))},
  143. )
  144. del j["measurements"]
  145. p1.qualifiers = j
  146. self.assertRaises(TypeError, p.__add__, "a")
  147. self.assertRaises(TypeError, p.__sub__, "a")
  148. p3 = p + p1
  149. self.assertEqual(p3["A02"], p["A02"] + p1["A02"])
  150. p3 = p - p1
  151. self.assertEqual(p3["A02"], p["A02"] - p1["A02"])
  152. del p["A02"]
  153. self.assertRaises(ValueError, p.__add__, p1)
  154. self.assertRaises(ValueError, p.__sub__, p1)
  155. def test_bad_fit_args(self):
  156. """Test error handling of the fit method."""
  157. with open(JSON_PLATE) as handle:
  158. p = json.load(handle)
  159. times = p["measurements"]["Hour"]
  160. w = phenotype.phen_micro.WellRecord(
  161. "A10",
  162. signals={times[i]: p["measurements"]["A10"][i] for i in range(len(times))},
  163. )
  164. self.assertRaises(ValueError, w.fit, "wibble")
  165. self.assertRaises(ValueError, w.fit, ["wibble"])
  166. self.assertRaises(ValueError, w.fit, ("logistic", "wibble"))
  167. self.assertRaises(ValueError, w.fit, ("wibble", "logistic"))
  168. self.assertRaises(ValueError, w.fit, "logistic") # should be a list/tuple!
  169. def test_WellRecord(self):
  170. """Test basic functionalities of WellRecord objects."""
  171. with open(JSON_PLATE) as handle:
  172. p = json.load(handle)
  173. times = p["measurements"]["Hour"]
  174. w = phenotype.phen_micro.WellRecord(
  175. "A10",
  176. signals={times[i]: p["measurements"]["A10"][i] for i in range(len(times))},
  177. )
  178. w1 = phenotype.phen_micro.WellRecord(
  179. "H12",
  180. signals={times[i]: p["measurements"]["H12"][i] for i in range(len(times))},
  181. )
  182. # self.assertIsInstance(w.plate,
  183. # phenotype.phen_micro.PlateRecord)
  184. self.assertIsInstance(w.plate, phenotype.phen_micro.PlateRecord)
  185. self.assertEqual(w.id, "A10")
  186. self.assertEqual(len(w), len(times))
  187. self.assertEqual(len(w), 384)
  188. self.assertEqual(max(w), (95.75, 217.0))
  189. self.assertEqual(min(w), (0.0, 37.0))
  190. self.assertEqual(max(w, key=lambda x: x[1]), (16.75, 313.0)) # noqa: E731
  191. self.assertEqual(min(w, key=lambda x: x[1]), (0.25, 29.0)) # noqa: E731
  192. self.assertEqual(len(w[:]), 96)
  193. self.assertEqual(w[1], 29.0)
  194. self.assertEqual(w[12], 272.0)
  195. self.assertEqual(w[1:5], [29.0, 35.0, 39.0, 43.0])
  196. self.assertRaises(ValueError, w.__getitem__, "a")
  197. self.assertAlmostEqual(w[1:2:0.25][0], 29.0)
  198. self.assertAlmostEqual(w[1.3567], 33.7196)
  199. self.assertEqual(w.get_raw()[0], (0.0, 37.0))
  200. self.assertEqual(w.get_raw()[-1], (95.75, 217.0))
  201. self.assertEqual(w.get_times()[0], 0.0)
  202. self.assertEqual(w.get_times()[-1], 95.75)
  203. self.assertEqual(w.get_signals()[0], 37.0)
  204. self.assertEqual(w.get_signals()[-1], 217.0)
  205. self.assertEqual(
  206. repr(w),
  207. "WellRecord('(0.0, 37.0), (0.25, 29.0), (0.5, 32.0),"
  208. " (0.75, 30.0), (1.0, 29.0), ..., (95.75, 217.0)')",
  209. )
  210. self.assertEqual(
  211. str(w),
  212. "Well ID: A10\nTime points: 384\nMinum signal 0.25 at time 29.00\n"
  213. "Maximum signal 16.75 at time 313.00\n"
  214. "WellRecord('(0.0, 37.0), (0.25, 29.0), (0.5, 32.0), (0.75, 30.0), "
  215. "(1.0, 29.0), ..., (95.75, 217.0)')",
  216. )
  217. w.fit(None)
  218. self.assertEqual(w.area, None)
  219. self.assertEqual(w.model, None)
  220. self.assertEqual(w.lag, None)
  221. self.assertEqual(w.plateau, None)
  222. self.assertEqual(w.slope, None)
  223. self.assertEqual(w.v, None)
  224. self.assertEqual(w.y0, None)
  225. self.assertEqual(w.max, 313.0)
  226. self.assertEqual(w.min, 29.0)
  227. self.assertEqual(w.average_height, 217.82552083333334)
  228. self.assertRaises(TypeError, w.__add__, "a")
  229. w2 = w + w1
  230. self.assertEqual(w2.id, "A10")
  231. self.assertEqual(len(w2), len(times))
  232. self.assertEqual(len(w2), 384)
  233. self.assertEqual(max(w2), (95.75, 327.0))
  234. self.assertEqual(min(w2), (0.0, 63.0))
  235. self.assertEqual(max(w2, key=lambda x: x[1]), (18.25, 357.0)) # noqa: E731
  236. self.assertEqual(min(w2, key=lambda x: x[1]), (0.25, 55.0)) # noqa: E731
  237. self.assertEqual(w2[1], 71.0)
  238. self.assertEqual(w2[12], 316.0)
  239. self.assertEqual(w2[1:5], [71.0, 88.0, 94.0, 94.0])
  240. self.assertAlmostEqual(w2[1:2:0.25][0], 71.0)
  241. self.assertAlmostEqual(w2[1.3567], 77.7196)
  242. self.assertEqual(w2.get_raw()[0], (0.0, 63.0))
  243. self.assertEqual(w2.get_raw()[-1], (95.75, 327.0))
  244. self.assertEqual(w2.get_times()[0], 0.0)
  245. self.assertEqual(w2.get_times()[-1], 95.75)
  246. self.assertEqual(w2.get_signals()[0], 63.0)
  247. self.assertEqual(w2.get_signals()[-1], 327.0)
  248. self.assertRaises(TypeError, w.__sub__, "a")
  249. w2 = w - w1
  250. self.assertEqual(w2.id, "A10")
  251. self.assertEqual(len(w2), len(times))
  252. self.assertEqual(len(w2), 384)
  253. self.assertEqual(max(w2), (95.75, 107.0))
  254. self.assertEqual(min(w2), (0.0, 11.0))
  255. self.assertEqual(max(w2, key=lambda x: x[1]), (15.75, 274.0)) # noqa: E731
  256. self.assertEqual(min(w2, key=lambda x: x[1]), (3.25, -20.0)) # noqa: E731
  257. self.assertEqual(w2[1], -13.0)
  258. self.assertEqual(w2[12], 228.0)
  259. self.assertEqual(w2[1:5], [-13.0, -18.0, -16.0, -8.0])
  260. self.assertAlmostEqual(w2[1:2:0.25][0], -13.0)
  261. self.assertAlmostEqual(w2[1.3567], -10.2804)
  262. self.assertEqual(w2.get_raw()[0], (0.0, 11.0))
  263. self.assertEqual(w2.get_raw()[-1], (95.75, 107.0))
  264. self.assertEqual(w2.get_times()[0], 0.0)
  265. self.assertEqual(w2.get_times()[-1], 95.75)
  266. self.assertEqual(w2.get_signals()[0], 11.0)
  267. self.assertEqual(w2.get_signals()[-1], 107.0)
  268. w[1] = 1
  269. if __name__ == "__main__":
  270. runner = unittest.TextTestRunner(verbosity=2)
  271. unittest.main(testRunner=runner)