ashs_test.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. # pylint: disable=missing-module-docstring
  2. import os
  3. import re
  4. import pandas
  5. import pytest
  6. from freesurfer_volume_reader.ashs import (
  7. IntracranialVolumeFile,
  8. HippocampalSubfieldsVolumeFile,
  9. )
  10. from conftest import SUBJECTS_DIR, assert_volume_frames_equal
  11. @pytest.mark.parametrize(
  12. ("volume_file_path", "expected_subject"),
  13. [
  14. ("bert_icv.txt", "bert"),
  15. ("final/bert_icv.txt", "bert"),
  16. ("ashs/subjects/bert/final/bert_icv.txt", "bert"),
  17. (
  18. "ashs/subjects/alice/final/long_subject_name_42_icv.txt",
  19. "long_subject_name_42",
  20. ),
  21. ],
  22. )
  23. def test_intracranial_volume_file_init(volume_file_path, expected_subject):
  24. volume_file = IntracranialVolumeFile(path=volume_file_path)
  25. assert os.path.abspath(volume_file_path) == volume_file.absolute_path
  26. assert expected_subject == volume_file.subject
  27. @pytest.mark.parametrize(
  28. "volume_file_path", ["_icv.txt", "bert_ICV.txt", "bert_icv.csv", "bert_ICV.txt.zip"]
  29. )
  30. def test_intracranial_volume_file_init_invalid_filename(volume_file_path):
  31. with pytest.raises(Exception):
  32. IntracranialVolumeFile(path=volume_file_path)
  33. @pytest.mark.parametrize(
  34. ("volume_file_path", "expected_volume"),
  35. [
  36. (os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt"), 1234560),
  37. (os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt"), 1.23456e06),
  38. (os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt"), 1.23456e06),
  39. (
  40. os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt"),
  41. float("1.23456e+06"),
  42. ),
  43. (os.path.join(SUBJECTS_DIR, "alice", "final", "alice_icv.txt"), 1543200),
  44. ],
  45. )
  46. def test_intracranial_volume_file_read_volume_mm3(volume_file_path, expected_volume):
  47. volume_file = IntracranialVolumeFile(path=volume_file_path)
  48. assert expected_volume == pytest.approx(volume_file.read_volume_mm3())
  49. @pytest.mark.parametrize(
  50. "volume_file_path", [os.path.join(SUBJECTS_DIR, "noone", "final", "noone_icv.txt")]
  51. )
  52. def test_intracranial_volume_file_read_volume_mm3_not_found(volume_file_path):
  53. volume_file = IntracranialVolumeFile(path=volume_file_path)
  54. with pytest.raises(FileNotFoundError):
  55. volume_file.read_volume_mm3()
  56. @pytest.mark.parametrize(
  57. ("volume_file_path", "expected_series"),
  58. [
  59. (
  60. os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt"),
  61. pandas.Series(
  62. data=[1234560.0],
  63. name="intercranial_volume_mm^3",
  64. index=pandas.Index(data=["bert"], name="subject"),
  65. ),
  66. ),
  67. (
  68. os.path.join(SUBJECTS_DIR, "alice", "final", "alice_icv.txt"),
  69. pandas.Series(
  70. data=[1543200.0],
  71. name="intercranial_volume_mm^3",
  72. index=pandas.Index(data=["alice"], name="subject"),
  73. ),
  74. ),
  75. ],
  76. )
  77. def test_intracranial_volume_file_read_volume_series_single(
  78. volume_file_path, expected_series
  79. ):
  80. volume_file = IntracranialVolumeFile(path=volume_file_path)
  81. pandas.testing.assert_series_equal(
  82. left=expected_series,
  83. right=volume_file.read_volume_series(),
  84. check_dtype=True,
  85. check_names=True,
  86. )
  87. @pytest.mark.parametrize(
  88. ("volume_file_paths", "expected_series"),
  89. [
  90. (
  91. [
  92. os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt"),
  93. os.path.join(SUBJECTS_DIR, "alice", "final", "alice_icv.txt"),
  94. ],
  95. pandas.Series(
  96. data=[1234560.0, 1543200.0],
  97. name="intercranial_volume_mm^3",
  98. index=pandas.Index(data=["bert", "alice"], name="subject"),
  99. ),
  100. )
  101. ],
  102. )
  103. def test_intracranial_volume_file_read_volume_series_concat(
  104. volume_file_paths, expected_series
  105. ):
  106. volume_series = pandas.concat(
  107. IntracranialVolumeFile(path=p).read_volume_series() for p in volume_file_paths
  108. )
  109. pandas.testing.assert_series_equal(
  110. left=expected_series, right=volume_series, check_dtype=True, check_names=True
  111. )
  112. @pytest.mark.parametrize(
  113. "volume_file_path", [os.path.join(SUBJECTS_DIR, "bert", "final", "BERT_icv.txt")]
  114. )
  115. def test_intracranial_volume_file_read_volume_series_not_found(volume_file_path):
  116. volume_file = IntracranialVolumeFile(path=volume_file_path)
  117. with pytest.raises(FileNotFoundError):
  118. volume_file.read_volume_series()
  119. @pytest.mark.parametrize(
  120. ("root_dir_path", "expected_file_paths"),
  121. [
  122. (
  123. os.path.join(SUBJECTS_DIR, "bert"),
  124. {os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt")},
  125. ),
  126. (
  127. os.path.join(SUBJECTS_DIR, "alice"),
  128. {os.path.join(SUBJECTS_DIR, "alice", "final", "alice_icv.txt")},
  129. ),
  130. (
  131. SUBJECTS_DIR,
  132. {
  133. os.path.join(SUBJECTS_DIR, "alice", "final", "alice_icv.txt"),
  134. os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt"),
  135. },
  136. ),
  137. ],
  138. )
  139. def test_intracranial_volume_file_find(root_dir_path, expected_file_paths):
  140. volume_files_iterator = IntracranialVolumeFile.find(root_dir_path=root_dir_path)
  141. assert expected_file_paths == set(f.absolute_path for f in volume_files_iterator)
  142. @pytest.mark.parametrize(
  143. ("root_dir_path", "filename_pattern", "expected_file_paths"),
  144. [
  145. (
  146. SUBJECTS_DIR,
  147. r"^\w{4,6}_icv.txt$",
  148. {
  149. os.path.join(SUBJECTS_DIR, "alice", "final", "alice_icv.txt"),
  150. os.path.join(SUBJECTS_DIR, "bert", "final", "bert_icv.txt"),
  151. },
  152. ),
  153. (
  154. SUBJECTS_DIR,
  155. r"^\w{5,6}_icv.txt$",
  156. {os.path.join(SUBJECTS_DIR, "alice", "final", "alice_icv.txt")},
  157. ),
  158. (SUBJECTS_DIR, r"^\w{7,}_icv.txt$", set()),
  159. ],
  160. )
  161. def test_intracranial_volume_file_find_pattern(
  162. root_dir_path, filename_pattern, expected_file_paths
  163. ):
  164. volume_files_iterator = IntracranialVolumeFile.find(
  165. root_dir_path=root_dir_path, filename_regex=re.compile(filename_pattern)
  166. )
  167. assert expected_file_paths == set(f.absolute_path for f in volume_files_iterator)
  168. @pytest.mark.parametrize(
  169. ("volume_file_path", "expected_attrs"),
  170. [
  171. (
  172. "ashs/final/bert_left_heur_volumes.txt",
  173. {"subject": "bert", "hemisphere": "left", "correction": None},
  174. ),
  175. (
  176. "ashs/final/bert_left_corr_nogray_volumes.txt",
  177. {"subject": "bert", "hemisphere": "left", "correction": "nogray"},
  178. ),
  179. (
  180. "ashs/final/bert_left_corr_usegray_volumes.txt",
  181. {"subject": "bert", "hemisphere": "left", "correction": "usegray"},
  182. ),
  183. (
  184. "ashs/final/bert_right_heur_volumes.txt",
  185. {"subject": "bert", "hemisphere": "right", "correction": None},
  186. ),
  187. (
  188. "ashs/final/bert_right_corr_nogray_volumes.txt",
  189. {"subject": "bert", "hemisphere": "right", "correction": "nogray"},
  190. ),
  191. (
  192. "ashs/final/bert_right_corr_usegray_volumes.txt",
  193. {"subject": "bert", "hemisphere": "right", "correction": "usegray"},
  194. ),
  195. (
  196. "somewhere/else/bert_right_heur_volumes.txt",
  197. {"subject": "bert", "hemisphere": "right", "correction": None},
  198. ),
  199. (
  200. "somewhere/else/bert_right_corr_nogray_volumes.txt",
  201. {"subject": "bert", "hemisphere": "right", "correction": "nogray"},
  202. ),
  203. (
  204. "bert_right_heur_volumes.txt",
  205. {"subject": "bert", "hemisphere": "right", "correction": None},
  206. ),
  207. (
  208. "/foo/bar/alice_20190503_right_corr_nogray_volumes.txt",
  209. {
  210. "subject": "alice_20190503",
  211. "hemisphere": "right",
  212. "correction": "nogray",
  213. },
  214. ),
  215. ],
  216. )
  217. def test_hippocampal_subfields_volume_file_init(volume_file_path, expected_attrs):
  218. volume_file = HippocampalSubfieldsVolumeFile(path=volume_file_path)
  219. assert os.path.abspath(volume_file_path) == volume_file.absolute_path
  220. for attr, value in expected_attrs.items():
  221. assert value == getattr(volume_file, attr)
  222. @pytest.mark.parametrize(
  223. "volume_file_path",
  224. [
  225. "bert_middle_heur_volumes.txt",
  226. "bert_right_hear_volumes.txt",
  227. "bert_right_heur_volumes.nii",
  228. "bert_left_lfseg_corr_usegray.nii.gz",
  229. ],
  230. )
  231. def test_hippocampal_subfields_volume_file_init_invalid(volume_file_path):
  232. with pytest.raises(Exception):
  233. HippocampalSubfieldsVolumeFile(path=volume_file_path)
  234. @pytest.mark.parametrize(
  235. ("volume_file_path", "expected_volumes"),
  236. [
  237. (
  238. os.path.join(
  239. SUBJECTS_DIR, "bert", "final", "bert_left_corr_nogray_volumes.txt"
  240. ),
  241. {
  242. "CA1": 678.901,
  243. "CA2+3": 123.456,
  244. "DG": 901.234,
  245. "ERC": 789.012,
  246. "PHC": 2345.876,
  247. "PRC": 2345.678,
  248. "SUB": 457.789,
  249. },
  250. )
  251. ],
  252. )
  253. def test_hippocampal_subfields_volume_file_read_volumes_mm3(
  254. volume_file_path, expected_volumes
  255. ):
  256. volume_file = HippocampalSubfieldsVolumeFile(path=volume_file_path)
  257. assert expected_volumes == volume_file.read_volumes_mm3()
  258. def test_hippocampal_subfields_volume_file_read_volumes_mm3_not_found():
  259. volume_file = HippocampalSubfieldsVolumeFile(
  260. path=os.path.join(
  261. SUBJECTS_DIR, "nobert", "final", "bert_left_corr_nogray_volumes.txt"
  262. )
  263. )
  264. with pytest.raises(FileNotFoundError):
  265. volume_file.read_volumes_mm3()
  266. @pytest.mark.parametrize(
  267. ("volume_file_path", "expected_dataframe"),
  268. [
  269. (
  270. os.path.join(SUBJECTS_DIR, "alice", "final", "alice_left_heur_volumes.txt"),
  271. pandas.DataFrame(
  272. {
  273. "subfield": ["CA1", "CA2+3", "DG", "ERC", "PHC", "PRC", "SUB"],
  274. "volume_mm^3": [
  275. 679.904,
  276. 124.459,
  277. 902.237,
  278. 789.012,
  279. 2346.879,
  280. 2346.671,
  281. 458.782,
  282. ],
  283. "subject": "alice",
  284. "hemisphere": "left",
  285. "correction": None,
  286. }
  287. ),
  288. )
  289. ],
  290. )
  291. def test_hippocampal_subfields_volume_file_read_volumes_dataframe(
  292. volume_file_path: str, expected_dataframe: pandas.DataFrame
  293. ):
  294. volume_file = HippocampalSubfieldsVolumeFile(path=volume_file_path)
  295. assert_volume_frames_equal(
  296. left=expected_dataframe, right=volume_file.read_volumes_dataframe()
  297. )
  298. def test_hippocampal_subfields_volume_file_read_volumes_dataframe_not_found():
  299. volume_file = HippocampalSubfieldsVolumeFile(
  300. path=os.path.join(
  301. SUBJECTS_DIR, "nobert", "final", "bert_left_corr_nogray_volumes.txt"
  302. )
  303. )
  304. with pytest.raises(FileNotFoundError):
  305. volume_file.read_volumes_dataframe()
  306. @pytest.mark.parametrize(
  307. ("root_dir_path", "expected_file_paths"),
  308. [
  309. (
  310. os.path.join(SUBJECTS_DIR, "alice"),
  311. {
  312. os.path.join(
  313. SUBJECTS_DIR, "alice", "final", "alice_left_heur_volumes.txt"
  314. ),
  315. os.path.join(
  316. SUBJECTS_DIR, "alice", "final", "alice_left_corr_nogray_volumes.txt"
  317. ),
  318. },
  319. ),
  320. (
  321. os.path.join(SUBJECTS_DIR, "bert"),
  322. {
  323. os.path.join(
  324. SUBJECTS_DIR, "bert", "final", "bert_left_corr_nogray_volumes.txt"
  325. ),
  326. os.path.join(
  327. SUBJECTS_DIR, "bert", "final", "bert_left_corr_usegray_volumes.txt"
  328. ),
  329. os.path.join(
  330. SUBJECTS_DIR, "bert", "final", "bert_left_heur_volumes.txt"
  331. ),
  332. os.path.join(
  333. SUBJECTS_DIR, "bert", "final", "bert_right_corr_nogray_volumes.txt"
  334. ),
  335. },
  336. ),
  337. (
  338. SUBJECTS_DIR,
  339. {
  340. os.path.join(
  341. SUBJECTS_DIR, "alice", "final", "alice_left_heur_volumes.txt"
  342. ),
  343. os.path.join(
  344. SUBJECTS_DIR, "alice", "final", "alice_left_corr_nogray_volumes.txt"
  345. ),
  346. os.path.join(
  347. SUBJECTS_DIR, "bert", "final", "bert_left_corr_nogray_volumes.txt"
  348. ),
  349. os.path.join(
  350. SUBJECTS_DIR, "bert", "final", "bert_left_corr_usegray_volumes.txt"
  351. ),
  352. os.path.join(
  353. SUBJECTS_DIR, "bert", "final", "bert_left_heur_volumes.txt"
  354. ),
  355. os.path.join(
  356. SUBJECTS_DIR, "bert", "final", "bert_right_corr_nogray_volumes.txt"
  357. ),
  358. },
  359. ),
  360. ],
  361. )
  362. def test_hippocampal_subfields_volume_file_find(root_dir_path, expected_file_paths):
  363. volume_files_iterator = HippocampalSubfieldsVolumeFile.find(
  364. root_dir_path=root_dir_path
  365. )
  366. assert expected_file_paths == set(f.absolute_path for f in volume_files_iterator)
  367. @pytest.mark.parametrize(
  368. ("root_dir_path", "filename_pattern", "expected_file_paths"),
  369. [
  370. (
  371. SUBJECTS_DIR,
  372. r"^bert_right_",
  373. {
  374. os.path.join(
  375. SUBJECTS_DIR, "bert", "final", "bert_right_corr_nogray_volumes.txt"
  376. )
  377. },
  378. ),
  379. (
  380. SUBJECTS_DIR,
  381. r"_nogray_volumes.txt$",
  382. {
  383. os.path.join(
  384. SUBJECTS_DIR, "alice", "final", "alice_left_corr_nogray_volumes.txt"
  385. ),
  386. os.path.join(
  387. SUBJECTS_DIR, "bert", "final", "bert_left_corr_nogray_volumes.txt"
  388. ),
  389. os.path.join(
  390. SUBJECTS_DIR, "bert", "final", "bert_right_corr_nogray_volumes.txt"
  391. ),
  392. },
  393. ),
  394. ],
  395. )
  396. def test_hippocampal_subfields_volume_file_find_pattern(
  397. root_dir_path, filename_pattern, expected_file_paths
  398. ):
  399. volume_files_iterator = HippocampalSubfieldsVolumeFile.find(
  400. root_dir_path=root_dir_path, filename_regex=re.compile(filename_pattern)
  401. )
  402. assert expected_file_paths == set(f.absolute_path for f in volume_files_iterator)