ashs_test.py 14 KB

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