junifer 0.0.7.dev332__py3-none-any.whl → 0.0.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. junifer/_version.py +9 -19
  2. junifer/api/__init__.pyi +17 -2
  3. junifer/api/functions.py +222 -39
  4. junifer/api/queue_context/__init__.pyi +11 -3
  5. junifer/api/queue_context/gnu_parallel_local_adapter.py +81 -120
  6. junifer/api/queue_context/htcondor_adapter.py +118 -181
  7. junifer/api/queue_context/queue_context_adapter.py +51 -7
  8. junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +10 -35
  9. junifer/api/queue_context/tests/test_htcondor_adapter.py +13 -50
  10. junifer/api/res/fsl/run_fsl_docker.sh +4 -0
  11. junifer/api/tests/test_functions.py +863 -36
  12. junifer/cli/__init__.py +1 -7
  13. junifer/cli/cli.py +41 -22
  14. junifer/cli/parser.py +23 -147
  15. junifer/cli/tests/data/gmd_mean.yaml +6 -6
  16. junifer/cli/tests/data/gmd_mean_htcondor.yaml +6 -5
  17. junifer/cli/tests/data/partly_cloudy_agg_mean_tian.yml +1 -0
  18. junifer/cli/tests/test_cli.py +120 -4
  19. junifer/cli/tests/test_cli_utils.py +23 -6
  20. junifer/cli/utils.py +14 -9
  21. junifer/configs/__init__.py +5 -0
  22. junifer/configs/__init__.pyi +0 -0
  23. junifer/configs/juseless/datagrabbers/__init__.pyi +4 -2
  24. junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +18 -24
  25. junifer/configs/juseless/datagrabbers/camcan_vbm.py +20 -27
  26. junifer/configs/juseless/datagrabbers/ixi_vbm.py +44 -52
  27. junifer/configs/juseless/datagrabbers/tests/test_ixi_vbm.py +0 -7
  28. junifer/configs/juseless/datagrabbers/tests/test_ucla.py +2 -19
  29. junifer/configs/juseless/datagrabbers/ucla.py +111 -104
  30. junifer/configs/juseless/datagrabbers/ukb_vbm.py +19 -25
  31. junifer/configs/py.typed +0 -0
  32. junifer/conftest.py +63 -24
  33. junifer/data/_dispatch.py +9 -19
  34. junifer/data/coordinates/_ants_coordinates_warper.py +4 -1
  35. junifer/data/coordinates/_coordinates.py +51 -6
  36. junifer/data/coordinates/_fsl_coordinates_warper.py +4 -1
  37. junifer/data/coordinates/tests/test_coordinates.py +15 -3
  38. junifer/data/coordinates/tests/test_coordinates_names.py +37 -0
  39. junifer/data/maps/_ants_maps_warper.py +18 -12
  40. junifer/data/maps/_fsl_maps_warper.py +7 -3
  41. junifer/data/maps/_maps.py +12 -8
  42. junifer/data/maps/tests/test_maps.py +13 -21
  43. junifer/data/masks/_ants_mask_warper.py +18 -12
  44. junifer/data/masks/_fsl_mask_warper.py +7 -3
  45. junifer/data/masks/_masks.py +15 -12
  46. junifer/data/masks/tests/test_masks.py +20 -17
  47. junifer/data/parcellations/_ants_parcellation_warper.py +18 -12
  48. junifer/data/parcellations/_fsl_parcellation_warper.py +7 -5
  49. junifer/data/parcellations/_parcellations.py +125 -91
  50. junifer/data/parcellations/tests/test_parcellations.py +122 -1
  51. junifer/data/template_spaces.py +117 -50
  52. junifer/data/tests/test_template_spaces.py +10 -7
  53. junifer/data/utils.py +10 -8
  54. junifer/datagrabber/__init__.pyi +38 -5
  55. junifer/datagrabber/aomic/__init__.pyi +8 -1
  56. junifer/datagrabber/aomic/_types.py +22 -0
  57. junifer/datagrabber/aomic/id1000.py +193 -183
  58. junifer/datagrabber/aomic/piop1.py +215 -259
  59. junifer/datagrabber/aomic/piop2.py +211 -244
  60. junifer/datagrabber/aomic/tests/test_id1000.py +70 -53
  61. junifer/datagrabber/aomic/tests/test_piop1.py +98 -102
  62. junifer/datagrabber/aomic/tests/test_piop2.py +88 -85
  63. junifer/datagrabber/base.py +253 -79
  64. junifer/datagrabber/datalad_base.py +127 -76
  65. junifer/datagrabber/dmcc13_benchmark.py +204 -289
  66. junifer/datagrabber/hcp1200/__init__.pyi +7 -2
  67. junifer/datagrabber/hcp1200/datalad_hcp1200.py +61 -40
  68. junifer/datagrabber/hcp1200/hcp1200.py +151 -164
  69. junifer/datagrabber/hcp1200/tests/test_hcp1200.py +116 -128
  70. junifer/datagrabber/multiple.py +183 -63
  71. junifer/datagrabber/pattern.py +358 -227
  72. junifer/datagrabber/pattern_datalad.py +84 -124
  73. junifer/datagrabber/pattern_validation_mixin.py +22 -50
  74. junifer/datagrabber/tests/test_base.py +17 -4
  75. junifer/datagrabber/tests/test_datalad_base.py +20 -27
  76. junifer/datagrabber/tests/test_dmcc13_benchmark.py +110 -122
  77. junifer/datagrabber/tests/test_multiple.py +293 -31
  78. junifer/datagrabber/tests/test_pattern.py +577 -18
  79. junifer/datagrabber/tests/test_pattern_datalad.py +177 -107
  80. junifer/datagrabber/tests/test_pattern_validation_mixin.py +9 -51
  81. junifer/datareader/default.py +8 -5
  82. junifer/datareader/tests/test_default_reader.py +1 -1
  83. junifer/external/BrainPrint/.codecov.yml +2 -0
  84. junifer/external/BrainPrint/.codespellignore +2 -0
  85. junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/bug-report.md +45 -0
  86. junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/documentation.md +12 -0
  87. junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/feature-request.md +24 -0
  88. junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/questions-help-support.md +28 -0
  89. junifer/external/BrainPrint/.github/dependabot.yml +6 -0
  90. junifer/external/BrainPrint/.github/workflows/build.yml +53 -0
  91. junifer/external/BrainPrint/.github/workflows/code-style.yml +44 -0
  92. junifer/external/BrainPrint/.github/workflows/doc.yml +65 -0
  93. junifer/external/BrainPrint/.github/workflows/publish.yml +31 -0
  94. junifer/external/BrainPrint/.github/workflows/pytest.yml +54 -0
  95. junifer/external/BrainPrint/.gitignore +123 -0
  96. junifer/external/BrainPrint/LICENSE +21 -0
  97. junifer/external/BrainPrint/README.md +108 -0
  98. junifer/external/BrainPrint/brainprint/cli/__init__.py +11 -0
  99. junifer/external/BrainPrint/brainprint/cli/help_text.py +169 -0
  100. junifer/external/BrainPrint/brainprint/cli/parser.py +150 -0
  101. junifer/external/BrainPrint/brainprint/cli/utils.py +14 -0
  102. junifer/external/BrainPrint/brainprint/commands/__init__.py +0 -0
  103. junifer/external/BrainPrint/brainprint/commands/sys_info.py +18 -0
  104. junifer/external/BrainPrint/brainprint/utils/tests/__init__.py +0 -0
  105. junifer/external/BrainPrint/brainprint/utils/tests/test_config.py +33 -0
  106. junifer/external/BrainPrint/doc/Makefile +20 -0
  107. junifer/external/BrainPrint/doc/_static/.gitkeep +0 -0
  108. junifer/external/BrainPrint/doc/_templates/autosummary/class.rst +10 -0
  109. junifer/external/BrainPrint/doc/_templates/autosummary/function.rst +8 -0
  110. junifer/external/BrainPrint/doc/_templates/autosummary/module.rst +6 -0
  111. junifer/external/BrainPrint/doc/api/index.rst +11 -0
  112. junifer/external/BrainPrint/doc/conf.py +272 -0
  113. junifer/external/BrainPrint/doc/index.rst +140 -0
  114. junifer/external/BrainPrint/doc/links.inc +36 -0
  115. junifer/external/BrainPrint/doc/make.bat +35 -0
  116. junifer/external/BrainPrint/doc/references.bib +23 -0
  117. junifer/external/BrainPrint/pyproject.toml +170 -0
  118. junifer/external/BrainPrint/setup.py +3 -0
  119. junifer/external/__init__.py +5 -0
  120. junifer/external/__init__.pyi +0 -0
  121. junifer/external/nilearn/junifer_connectivity_measure.py +95 -39
  122. junifer/external/nilearn/junifer_nifti_spheres_masker.py +226 -67
  123. junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +39 -27
  124. junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py +231 -21
  125. junifer/external/py.typed +0 -0
  126. junifer/markers/__init__.pyi +6 -3
  127. junifer/markers/base.py +126 -76
  128. junifer/markers/brainprint.py +30 -39
  129. junifer/markers/complexity/__init__.py +20 -3
  130. junifer/markers/complexity/complexity_base.py +40 -41
  131. junifer/markers/complexity/hurst_exponent.py +22 -35
  132. junifer/markers/complexity/multiscale_entropy_auc.py +53 -41
  133. junifer/markers/complexity/perm_entropy.py +22 -36
  134. junifer/markers/complexity/range_entropy.py +22 -35
  135. junifer/markers/complexity/range_entropy_auc.py +27 -36
  136. junifer/markers/complexity/sample_entropy.py +22 -36
  137. junifer/markers/complexity/tests/test_complexity_registry.py +48 -0
  138. junifer/markers/complexity/tests/test_hurst_exponent.py +47 -36
  139. junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +50 -36
  140. junifer/markers/complexity/tests/test_perm_entropy.py +48 -36
  141. junifer/markers/complexity/tests/test_range_entropy.py +47 -36
  142. junifer/markers/complexity/tests/test_range_entropy_auc.py +47 -36
  143. junifer/markers/complexity/tests/test_sample_entropy.py +48 -36
  144. junifer/markers/complexity/tests/test_weighted_perm_entropy.py +50 -36
  145. junifer/markers/complexity/weighted_perm_entropy.py +22 -36
  146. junifer/markers/ets_rss.py +35 -31
  147. junifer/markers/falff/__init__.pyi +7 -1
  148. junifer/markers/falff/_afni_falff.py +22 -9
  149. junifer/markers/falff/_junifer_falff.py +47 -31
  150. junifer/markers/falff/falff_base.py +80 -60
  151. junifer/markers/falff/falff_maps.py +17 -41
  152. junifer/markers/falff/falff_parcels.py +26 -51
  153. junifer/markers/falff/falff_spheres.py +34 -61
  154. junifer/markers/falff/tests/test_falff_maps.py +20 -23
  155. junifer/markers/falff/tests/test_falff_mask.py +99 -0
  156. junifer/markers/falff/tests/test_falff_parcels.py +14 -10
  157. junifer/markers/falff/tests/test_falff_spheres.py +14 -10
  158. junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +32 -34
  159. junifer/markers/functional_connectivity/edge_functional_connectivity_maps.py +12 -25
  160. junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +19 -34
  161. junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +24 -44
  162. junifer/markers/functional_connectivity/functional_connectivity_base.py +50 -40
  163. junifer/markers/functional_connectivity/functional_connectivity_maps.py +12 -25
  164. junifer/markers/functional_connectivity/functional_connectivity_parcels.py +19 -34
  165. junifer/markers/functional_connectivity/functional_connectivity_spheres.py +24 -45
  166. junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +21 -22
  167. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_maps.py +8 -7
  168. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +8 -4
  169. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +8 -4
  170. junifer/markers/functional_connectivity/tests/test_functional_connectivity_maps.py +8 -7
  171. junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +9 -5
  172. junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +8 -12
  173. junifer/markers/maps_aggregation.py +77 -55
  174. junifer/markers/parcel_aggregation.py +91 -70
  175. junifer/markers/reho/__init__.pyi +7 -1
  176. junifer/markers/reho/_afni_reho.py +23 -14
  177. junifer/markers/reho/_junifer_reho.py +112 -123
  178. junifer/markers/reho/reho_base.py +115 -37
  179. junifer/markers/reho/reho_maps.py +18 -32
  180. junifer/markers/reho/reho_parcels.py +26 -41
  181. junifer/markers/reho/reho_spheres.py +33 -54
  182. junifer/markers/reho/tests/test_junifer_reho.py +178 -0
  183. junifer/markers/reho/tests/test_reho_maps.py +27 -25
  184. junifer/markers/reho/tests/test_reho_parcels.py +28 -22
  185. junifer/markers/reho/tests/test_reho_spheres.py +16 -12
  186. junifer/markers/sphere_aggregation.py +88 -72
  187. junifer/markers/temporal_snr/temporal_snr_base.py +32 -30
  188. junifer/markers/temporal_snr/temporal_snr_maps.py +9 -18
  189. junifer/markers/temporal_snr/temporal_snr_parcels.py +19 -27
  190. junifer/markers/temporal_snr/temporal_snr_spheres.py +27 -41
  191. junifer/markers/temporal_snr/tests/test_temporal_snr_base.py +2 -2
  192. junifer/markers/temporal_snr/tests/test_temporal_snr_maps.py +17 -22
  193. junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +11 -3
  194. junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +9 -9
  195. junifer/markers/tests/test_brainprint.py +10 -9
  196. junifer/markers/tests/test_ets_rss.py +7 -3
  197. junifer/markers/tests/test_lost_regions.py +279 -0
  198. junifer/markers/tests/test_maps_aggregation.py +67 -114
  199. junifer/markers/tests/test_marker_utils.py +40 -1
  200. junifer/markers/tests/test_markers_base.py +275 -6
  201. junifer/markers/tests/test_parcel_aggregation.py +91 -53
  202. junifer/markers/tests/test_sphere_aggregation.py +53 -47
  203. junifer/markers/utils.py +267 -5
  204. junifer/onthefly/__init__.py +2 -3
  205. junifer/onthefly/__init__.pyi +4 -0
  206. junifer/onthefly/_brainprint.py +3 -5
  207. junifer/onthefly/py.typed +0 -0
  208. junifer/onthefly/read_transform.py +11 -9
  209. junifer/onthefly/tests/test_read_transform.py +7 -7
  210. junifer/pipeline/__init__.pyi +4 -2
  211. junifer/pipeline/marker_collection.py +14 -10
  212. junifer/pipeline/pipeline_component_registry.py +25 -6
  213. junifer/pipeline/pipeline_step_mixin.py +5 -12
  214. junifer/pipeline/tests/test_data_object_dumper.py +10 -10
  215. junifer/pipeline/tests/test_marker_collection.py +145 -168
  216. junifer/pipeline/tests/test_pipeline_component_registry.py +52 -8
  217. junifer/pipeline/tests/test_pipeline_step_mixin.py +12 -26
  218. junifer/pipeline/tests/test_update_meta_mixin.py +4 -5
  219. junifer/pipeline/tests/test_workdir_manager.py +39 -0
  220. junifer/pipeline/update_meta_mixin.py +13 -10
  221. junifer/pipeline/utils.py +22 -17
  222. junifer/pipeline/workdir_manager.py +41 -32
  223. junifer/preprocess/__init__.pyi +9 -4
  224. junifer/preprocess/_temporal_filter.py +34 -33
  225. junifer/preprocess/_temporal_slicer.py +17 -30
  226. junifer/preprocess/base.py +99 -55
  227. junifer/preprocess/confounds/__init__.pyi +10 -2
  228. junifer/preprocess/confounds/fmriprep_confound_remover.py +87 -109
  229. junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +64 -45
  230. junifer/preprocess/smoothing/__init__.pyi +2 -2
  231. junifer/preprocess/smoothing/_afni_smoothing.py +8 -7
  232. junifer/preprocess/smoothing/_fsl_smoothing.py +6 -4
  233. junifer/preprocess/smoothing/_nilearn_smoothing.py +7 -5
  234. junifer/preprocess/smoothing/smoothing.py +59 -40
  235. junifer/preprocess/smoothing/tests/test_smoothing.py +28 -8
  236. junifer/preprocess/tests/test_preprocess_base.py +17 -9
  237. junifer/preprocess/tests/test_temporal_filter.py +37 -16
  238. junifer/preprocess/tests/test_temporal_slicer.py +12 -12
  239. junifer/preprocess/warping/__init__.pyi +2 -2
  240. junifer/preprocess/warping/_ants_warper.py +56 -40
  241. junifer/preprocess/warping/_fsl_warper.py +49 -36
  242. junifer/preprocess/warping/_utils.py +106 -0
  243. junifer/preprocess/warping/space_warper.py +99 -98
  244. junifer/preprocess/warping/tests/test_space_warper.py +46 -41
  245. junifer/preprocess/warping/tests/test_warping_utils.py +163 -0
  246. junifer/stats.py +46 -34
  247. junifer/storage/__init__.pyi +8 -4
  248. junifer/storage/base.py +129 -64
  249. junifer/storage/hdf5.py +307 -199
  250. junifer/storage/pandas_base.py +46 -24
  251. junifer/storage/sqlite.py +99 -62
  252. junifer/storage/tests/data/collected_h5io_fork.hdf5 +0 -0
  253. junifer/storage/tests/test_hdf5.py +147 -12
  254. junifer/storage/tests/test_repeated_storage.py +293 -0
  255. junifer/storage/tests/test_sqlite.py +9 -20
  256. junifer/storage/tests/test_storage_base.py +18 -21
  257. junifer/storage/tests/test_utils.py +83 -22
  258. junifer/storage/utils.py +58 -38
  259. junifer/testing/__init__.pyi +2 -2
  260. junifer/testing/datagrabbers.py +480 -44
  261. junifer/testing/registry.py +12 -0
  262. junifer/testing/tests/test_adhdtesting_datagrabber.py +24 -0
  263. junifer/testing/tests/test_oasisvmbtesting_datagrabber.py +5 -0
  264. junifer/testing/tests/test_partlycloudytesting_datagrabber.py +52 -0
  265. junifer/testing/tests/test_spmauditory_datagrabber.py +16 -0
  266. junifer/testing/tests/test_testing_registry.py +31 -0
  267. junifer/testing/tests/test_testing_utils.py +35 -0
  268. junifer/testing/tests/test_uclacnpvbmtesting_datagrabber.py +81 -0
  269. junifer/testing/utils.py +33 -1
  270. junifer/tests/test_stats.py +1 -5
  271. junifer/typing/__init__.pyi +2 -0
  272. junifer/typing/_typing.py +34 -19
  273. junifer/typing/py.typed +0 -0
  274. junifer/utils/__init__.pyi +10 -1
  275. junifer/utils/_config.py +1 -2
  276. junifer/utils/helpers.py +68 -2
  277. junifer/utils/logging.py +31 -7
  278. junifer/utils/tests/test_helpers.py +36 -1
  279. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/METADATA +43 -35
  280. junifer-0.0.8.dist-info/RECORD +402 -0
  281. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/WHEEL +1 -1
  282. junifer/cli/tests/test_parser.py +0 -280
  283. junifer/external/h5io/h5io/__init__.py +0 -15
  284. junifer/external/h5io/h5io/_h5io.py +0 -767
  285. junifer/external/h5io/h5io/_version.py +0 -1
  286. junifer/external/h5io/h5io/chunked_array.py +0 -94
  287. junifer/external/h5io/h5io/chunked_list.py +0 -65
  288. junifer/markers/complexity/__init__.pyi +0 -17
  289. junifer-0.0.7.dev332.dist-info/RECORD +0 -353
  290. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/entry_points.txt +0 -0
  291. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/licenses/AUTHORS.rst +0 -0
  292. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/licenses/LICENSE.md +0 -0
  293. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,140 @@
1
+ .. include:: ./links.inc
2
+
3
+ .. .. literalinclude:: ../README.md
4
+ .. :language: markdown
5
+
6
+ .. image:: https://badge.fury.io/py/brainprint.svg
7
+ :target: https://pypi.org/project/brainprint/
8
+
9
+ BrainPrint
10
+ ==========
11
+
12
+ This is the `brainprint` python package, a derivative of the original `BrainPrint-legacy <https://github.com/Deep-MI/BrainPrint-legacy>`_ scripts,
13
+ with the primary goal to provide a Python-only version, to integrate the `LaPy <https://github.com/Deep-MI/LaPy>`_ package,
14
+ and to remove dependencies on third-party software (shapeDNA-* binaries, gmsh, meshfix).
15
+ As a result, some functionality of the original BrainPrint-legacy scripts is no longer maintained (currently no support of tetrahedral meshes and no support of cortical parcellations or label files).
16
+
17
+ Installation
18
+ ------------
19
+
20
+ Use the following code to install the latest release of LaPy into your local Python package directory:
21
+
22
+ .. code-block:: bash
23
+
24
+ python3 -m pip install brainprint
25
+
26
+ This will also install the necessary dependencies, e.g. the `LaPy <https://github.com/Deep-MI/LaPy>`_ package.
27
+ You may need to add your local Python package directory to your $PATH in order to run the scripts.
28
+
29
+ Usage
30
+ -----
31
+
32
+ Command Line Interface (CLI)
33
+ ----------------------------
34
+
35
+ Once installed, the package provides a `brainprint` executable which can be run from the command line.
36
+
37
+ The `brainprint` CLI enables per-subject computation of the individual brainprint descriptors. Its usage and options are summarized below; detailed info is available by calling the script without any arguments from the command line.
38
+
39
+ brainprint Command-Line Interface
40
+ '''''''''''''''''''''''''''''''''
41
+
42
+ .. code-block:: sh
43
+
44
+ brainprint
45
+ --sdir <directory>
46
+ --sid <SubjectID>
47
+ [--num <num>] [--evec] [--skipcortex]
48
+ [--norm <surface|volume|geometry|none> ]
49
+ [--reweight] [--asymmetry] [--outdir <directory>]
50
+ [--help] [--more-help]
51
+
52
+ Options
53
+ '''''''
54
+
55
+ ``--help`` Show this help message and exit.
56
+
57
+ ``--more-help`` Show extensive help message and exit.
58
+
59
+ Required options
60
+ ''''''''''''''''
61
+
62
+ ``--sid <SubjectID>`` Subject ID (FreeSurfer-processed directory inside the subjects directory).
63
+
64
+ ``--sdir <directory>`` FreeSurfer subjects directory.
65
+
66
+ Processing directives
67
+ '''''''''''''''''''''
68
+
69
+ ``--num <num>`` Number of eigenvalues/vectors to compute (default: 50).
70
+
71
+ ``--evec`` Switch on eigenvector computation (default: off).
72
+
73
+ ``--skipcortex`` Skip cortical surfaces (default: off).
74
+
75
+ ``--norm <surface|volume|geometry|none>`` Switch on eigenvalue normalization; will be either surface, volume, or determined by the geometry of the object. Use "none" or leave out entirely to skip normalization.
76
+
77
+ ``--reweight`` Switch on eigenvalue reweighting (default: off).
78
+
79
+ ``--asymmetry`` Perform left-right asymmetry calculation (default: off).
80
+
81
+ ``--cholmod`` Switch on use of (faster) Cholesky decomposition instead of (slower) LU decomposition (default: off). May require manual install of scikit-sparse package.
82
+
83
+ Output parameters
84
+ '''''''''''''''''
85
+
86
+ ``--outdir=OUTDIR`` Output directory (default: <sdir>/<sid>/brainprint).
87
+
88
+ ``--keep-temp`` Whether to keep the temporary files directory or not (default: False).
89
+
90
+
91
+ Python Package
92
+ --------------
93
+
94
+ `brainprint` can also be run within a pure Python environment, i.e. installed and imported as a Python package. E.g.:
95
+
96
+ .. code-block:: python
97
+
98
+ from brainprint import Brainprint
99
+
100
+ subjects_dir = "/path/to/freesurfer/subjects_dir/"
101
+ subject_id = "42"
102
+
103
+ bp = Brainprint(subjects_dir=subjects_dir, asymmetry=True, keep_eigenvectors=True)
104
+ results = bp.run(subject_id=subject_id)
105
+ results
106
+ {"eigenvalues": PosixPath("/path/to/freesurfer/subjects_dir/subject_id/brainprint/subject_id.brainprint.csv"),
107
+ "eigenvectors": PosixPath("/path/to/freesurfer/subjects_dir/subject_id/brainprint/eigenvectors"),
108
+ "distances": PosixPath("/path/to/freesurfer/subjects_dir/subject_id/brainprint/subject_id.brainprint.asymmetry.csv")}
109
+
110
+
111
+ Output
112
+ ------
113
+ The script will create an output directory that contains a CSV table with
114
+ values (in that order) for the area, volume, and first n eigenvalues per each
115
+ FreeSurfer structure. An additional output file will be created if the
116
+ asymmetry calculation is performed and/or for the eigenvectors (CLI `--evecs` flag or `keep_eigenvectors` on class initialization).
117
+
118
+ Changes
119
+ -------
120
+
121
+ There are some changes in functionality in comparison to the original `BrainPrint <https://github.com/Deep-MI/BrainPrint-legacy>`_ scripts:
122
+
123
+ - Currently, there is no support for tetrahedral meshes.
124
+ - Currently, there is no support for analyses of cortical parcellation or label files.
125
+ - No more Python 2.x compatibility.
126
+
127
+ References
128
+ ----------
129
+
130
+ If you use this software for a publication, please cite:
131
+
132
+ [1] BrainPrint: a discriminative characterization of brain morphology. Wachinger C, Golland P, Kremen W, Fischl B, Reuter M. Neuroimage. 2015;109:232-48. `http://dx.doi.org/10.1016/j.neuroimage.2015.01.032 <http://dx.doi.org/10.1016/j.neuroimage.2015.01.032>`_ `PubMed <http://www.ncbi.nlm.nih.gov/pubmed/25613439>`_
133
+
134
+ [2] Laplace-Beltrami spectra as 'Shape-DNA' of surfaces and solids. Reuter M, Wolter F-E, Peinecke N. Computer-Aided Design. 2006;38:342-366. `http://dx.doi.org/10.1016/j.cad.2005.10.011 <http://dx.doi.org/10.1016/j.cad.2005.10.011>`_
135
+
136
+
137
+ .. toctree::
138
+ :hidden:
139
+
140
+ api/index
@@ -0,0 +1,36 @@
1
+ .. This (-*- rst -*-) format file contains commonly used link targets and name
2
+ substitutions. It may be included in many files, therefore it should only
3
+ contain link targets and name substitutions. Try grepping for "^\.\. _" to
4
+ find plausible candidates for this list.
5
+
6
+ .. NOTE: reST targets are
7
+ __not_case_sensitive__, so only one target definition is needed for:
8
+ nipy, NIPY, Nipy, etc...
9
+
10
+
11
+ .. project
12
+
13
+ .. _project pypi: https://pypi.org/project/lapy/
14
+ .. _project conda: https://anaconda.org/conda-forge/lapy
15
+ .. _project github: https://github.com/Deep-MI/BrainPrint
16
+ .. _project license: https://github.com/Deep-MI/BrainPrint/blob/main/LICENSE
17
+ .. _project brainprint: https://pypi.org/project/brainprint/
18
+
19
+ .. license
20
+
21
+ .. _MIT license: https://opensource.org/licenses/MIT
22
+
23
+
24
+ .. numpy
25
+
26
+ .. _numpy: https://numpy.org/
27
+
28
+
29
+ .. sklearn
30
+
31
+ .. _scikit-learn: https://scikit-learn.org/stable/
32
+
33
+
34
+ .. scipy
35
+
36
+ .. _scipy: https://scipy.org/
@@ -0,0 +1,35 @@
1
+ @ECHO OFF
2
+
3
+ pushd %~dp0
4
+
5
+ REM Command file for Sphinx documentation
6
+
7
+ if "%SPHINXBUILD%" == "" (
8
+ set SPHINXBUILD=sphinx-build
9
+ )
10
+ set SOURCEDIR=.
11
+ set BUILDDIR=_build
12
+
13
+ %SPHINXBUILD% >NUL 2>NUL
14
+ if errorlevel 9009 (
15
+ echo.
16
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17
+ echo.installed, then set the SPHINXBUILD environment variable to point
18
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
19
+ echo.may add the Sphinx directory to PATH.
20
+ echo.
21
+ echo.If you don't have Sphinx installed, grab it from
22
+ echo.https://www.sphinx-doc.org/
23
+ exit /b 1
24
+ )
25
+
26
+ if "%1" == "" goto help
27
+
28
+ %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29
+ goto end
30
+
31
+ :help
32
+ %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33
+
34
+ :end
35
+ popd
@@ -0,0 +1,23 @@
1
+ @article{numpy_2020,
2
+ author = {Harris, Charles R. and Millman, K. Jarrod and van der Walt, Stéfan J. and Gommers, Ralf and Virtanen, Pauli and Cournapeau, David and Wieser, Eric and Taylor, Julian and Berg, Sebastian and Smith, Nathaniel J. and Kern, Robert and Picus, Matti and Hoyer, Stephan and van Kerkwijk, Marten H. and Brett, Matthew and Haldane, Allan and del Río, Jaime Fernández and Wiebe, Mark and Peterson, Pearu and Gérard-Marchant, Pierre and Sheppard, Kevin and Reddy, Tyler and Weckesser, Warren and Abbasi, Hameer and Gohlke, Christoph and Oliphant, Travis E.},
3
+ doi = {10.1038/s41586-020-2649-2},
4
+ journal = {Nature},
5
+ month = {September},
6
+ number = {7825},
7
+ pages = {357--362},
8
+ title = {Array programming with {NumPy}},
9
+ volume = {585},
10
+ year = {2020}
11
+ }
12
+
13
+ @article{scipy_2020,
14
+ author = {Virtanen, Pauli and Gommers, Ralf and Oliphant, Travis E. and Haberland, Matt and Reddy, Tyler and Cournapeau, David and Burovski, Evgeni and Peterson, Pearu and Weckesser, Warren and Bright, Jonathan and van der Walt, Stéfan J. and Brett, Matthew and Wilson, Joshua and Millman, K. Jarrod and Mayorov, Nikolay and Nelson, Andrew R. J. and Jones, Eric and Kern, Robert and Larson, Eric and Carey, C J and Polat, İlhan and Feng, Yu and Moore, Eric W. and VanderPlas, Jake and Laxalde, Denis and Perktold, Josef and Cimrman, Robert and Henriksen, Ian and Quintero, E. A. and Harris, Charles R. and Archibald, Anne M. and Ribeiro, Antônio H. and Pedregosa, Fabian and van Mulbregt, Paul and {SciPy 1.0 Contributors} and Vijaykumar, Aditya and Bardelli, Alessandro Pietro and Rothberg, Alex and Hilboll, Andreas and Kloeckner, Andreas and Scopatz, Anthony and Lee, Antony and Rokem, Ariel and Woods, C. Nathan and Fulton, Chad and Masson, Charles and Häggström, Christian and Fitzgerald, Clark and Nicholson, David A. and Hagen, David R. and Pasechnik, Dmitrii V. and Olivetti, Emanuele and Martin, Eric and Wieser, Eric and Silva, Fabrice and Lenders, Felix and Wilhelm, Florian and Young, G. and Price, Gavin A. and Ingold, Gert-Ludwig and Allen, Gregory E. and Lee, Gregory R. and Audren, Hervé and Probst, Irvin and Dietrich, Jörg P. and Silterra, Jacob and Webber, James T and Slavič, Janko and Nothman, Joel and Buchner, Johannes and Kulick, Johannes and Schönberger, Johannes L. and de Miranda Cardoso, José Vinícius and Reimer, Joscha and Harrington, Joseph and Rodríguez, Juan Luis Cano and Nunez-Iglesias, Juan and Kuczynski, Justin and Tritz, Kevin and Thoma, Martin and Newville, Matthew and Kümmerer, Matthias and Bolingbroke, Maximilian and Tartre, Michael and Pak, Mikhail and Smith, Nathaniel J. and Nowaczyk, Nikolai and Shebanov, Nikolay and Pavlyk, Oleksandr and Brodtkorb, Per A. and Lee, Perry and McGibbon, Robert T. and Feldbauer, Roman and Lewis, Sam and Tygier, Sam and Sievert, Scott and Vigna, Sebastiano and Peterson, Stefan and More, Surhud and Pudlik, Tadeusz and Oshima, Takuya and Pingel, Thomas J. and Robitaille, Thomas P. and Spura, Thomas and Jones, Thouis R. and Cera, Tim and Leslie, Tim and Zito, Tiziano and Krauss, Tom and Upadhyay, Utkarsh and Halchenko, Yaroslav O. and Vázquez-Baeza, Yoshiki},
15
+ doi = {10.1038/s41592-019-0686-2},
16
+ journal = {Nature Methods},
17
+ month = {March},
18
+ number = {3},
19
+ pages = {261--272},
20
+ title = {{SciPy} 1.0: fundamental algorithms for scientific computing in {Python}},
21
+ volume = {17},
22
+ year = {2020}
23
+ }
@@ -0,0 +1,170 @@
1
+ [build-system]
2
+ requires = ['setuptools >= 61.0.0']
3
+ build-backend = 'setuptools.build_meta'
4
+
5
+ [project]
6
+ name = 'brainprint'
7
+ version = '0.4.0'
8
+ description = 'A package to compute BrainPrint (shape descriptors) from FastSurfer/FreeSurfer MRI segmentations'
9
+ readme = 'README.md'
10
+ license = {file = 'LICENSE'}
11
+ requires-python = '>=3.8'
12
+ authors = [
13
+ {name = 'Martin Reuter', email = 'martin.reuter@dzne.de'},
14
+ {name = 'Kersten Diers', email = 'kersten.diers@dzne.de'},
15
+ ]
16
+ maintainers = [
17
+ {name = 'Martin Reuter', email = 'martin.reuter@dzne.de'},
18
+ ]
19
+ keywords = [
20
+ 'neuroscience',
21
+ 'sMRI',
22
+ 'FreeSurfer'
23
+ ]
24
+ classifiers = [
25
+ 'Operating System :: Microsoft :: Windows',
26
+ 'Operating System :: Unix',
27
+ 'Operating System :: MacOS',
28
+ 'Programming Language :: Python :: 3 :: Only',
29
+ 'Programming Language :: Python :: 3.8',
30
+ 'Programming Language :: Python :: 3.9',
31
+ 'Programming Language :: Python :: 3.10',
32
+ 'Programming Language :: Python :: 3.11',
33
+ 'Natural Language :: English',
34
+ 'License :: OSI Approved :: MIT License',
35
+ 'Intended Audience :: Science/Research',
36
+ ]
37
+ dependencies = [
38
+ 'numpy',
39
+ 'scipy',
40
+ 'pandas',
41
+ 'lapy >= 1.0.0, <2',
42
+ 'psutil'
43
+ ]
44
+
45
+ [project.optional-dependencies]
46
+ build = [
47
+ 'build',
48
+ 'twine',
49
+ ]
50
+ doc = [
51
+ 'furo!=2023.8.17',
52
+ 'matplotlib',
53
+ 'memory-profiler',
54
+ 'numpydoc',
55
+ 'sphinx!=7.2.*',
56
+ 'sphinxcontrib-bibtex',
57
+ 'sphinx-copybutton',
58
+ 'sphinx-design',
59
+ 'sphinx-gallery',
60
+ 'sphinx-issues',
61
+ 'pypandoc',
62
+ 'nbsphinx',
63
+ 'IPython', # For syntax highlighting in notebooks
64
+ 'ipykernel',
65
+ ]
66
+ style = [
67
+ 'bibclean',
68
+ 'black',
69
+ 'codespell',
70
+ 'isort',
71
+ 'pydocstyle[toml]',
72
+ 'ruff',
73
+ ]
74
+ test = [
75
+ 'pytest',
76
+ 'pytest-cov',
77
+ 'pytest-timeout',
78
+ ]
79
+ all = [
80
+ 'brainprint[build]',
81
+ 'brainprint[doc]',
82
+ 'brainprint[style]',
83
+ 'brainprint[test]',
84
+ ]
85
+ full = [
86
+ 'brainprint[all]',
87
+ ]
88
+
89
+ [project.urls]
90
+ homepage = 'https://github.com/Deep-MI/BrainPrint'
91
+ documentation = 'https://github.com/Deep-MI/BrainPrint'
92
+ source = 'https://github.com/Deep-MI/BrainPrint'
93
+ tracker = 'https://github.com/Deep-MI/BrainPrint/issues'
94
+
95
+ [project.scripts]
96
+ brainprint = 'brainprint.cli:main'
97
+ brainprint-sys_info = 'brainprint.commands.sys_info:run'
98
+
99
+ [tool.setuptools]
100
+ include-package-data = false
101
+
102
+ [tool.setuptools.packages.find]
103
+ include = ['brainprint*']
104
+ exclude = ['brainprint*tests']
105
+
106
+ [tool.black]
107
+ line-length = 88
108
+ target-version = ['py38']
109
+ include = '\.pyi?$'
110
+ extend-exclude = '''
111
+ (
112
+ __pycache__
113
+ | .github
114
+ | setup.py
115
+ | data/
116
+ | doc/
117
+ | examples/
118
+ )
119
+ '''
120
+
121
+ [tool.isort]
122
+ profile = 'black'
123
+ multi_line_output = 3
124
+ line_length = 88
125
+ py_version = 38
126
+ extend_skip_glob = [
127
+ 'setup.py',
128
+ 'data/*',
129
+ 'doc/*',
130
+ 'examples/*',
131
+ ]
132
+
133
+ [tool.pydocstyle]
134
+ convention = 'numpy'
135
+ ignore-decorators = '(copy_doc|property|.*setter|.*getter|pyqtSlot|Slot)'
136
+ match = '^(?!setup|__init__|test_).*\.py'
137
+ match-dir = '^brainprint.*'
138
+ add_ignore = 'D100,D104,D107'
139
+
140
+ [tool.ruff]
141
+ line-length = 88
142
+ extend-exclude = [
143
+ "doc",
144
+ "setup.py",
145
+ ]
146
+
147
+ [tool.ruff.per-file-ignores]
148
+ "__init__.py" = ["F401"]
149
+
150
+ [tool.pytest.ini_options]
151
+ minversion = '6.0'
152
+ addopts = '--durations 20 --junit-xml=junit-results.xml --verbose'
153
+ filterwarnings = []
154
+
155
+ [tool.coverage.run]
156
+ branch = true
157
+ cover_pylib = false
158
+ omit = [
159
+ '**/__init__.py',
160
+ '**/brainprint/_version.py',
161
+ '**/brainprint/commands/*',
162
+ '**/tests/**',
163
+ ]
164
+
165
+ [tool.coverage.report]
166
+ exclude_lines = [
167
+ 'pragma: no cover',
168
+ 'if __name__ == .__main__.:',
169
+ ]
170
+ precision = 2
@@ -0,0 +1,3 @@
1
+ from setuptools import setup
2
+
3
+ setup()
@@ -2,3 +2,8 @@
2
2
 
3
3
  # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
4
  # License: AGPL
5
+
6
+ import lazy_loader as lazy
7
+
8
+
9
+ __getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__)
File without changes
@@ -3,9 +3,8 @@
3
3
  # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
4
  # License: AGPL
5
5
 
6
- import sys
6
+ from collections.abc import Callable
7
7
  from itertools import product
8
- from typing import Callable, Optional
9
8
 
10
9
  import numpy as np
11
10
  from nilearn import signal
@@ -19,7 +18,7 @@ from scipy import linalg, stats
19
18
  from sklearn.base import clone
20
19
  from sklearn.covariance import EmpiricalCovariance
21
20
 
22
- from ...utils import logger, raise_error, warn_with_log
21
+ from ...utils import check_standardize, logger, raise_error, warn_with_log
23
22
 
24
23
 
25
24
  __all__ = ["JuniferConnectivityMeasure"]
@@ -189,9 +188,9 @@ def _map_eigenvalues(
189
188
 
190
189
  def _geometric_mean(
191
190
  matrices: list[np.ndarray],
192
- init: Optional[np.ndarray] = None,
191
+ init: np.ndarray | None = None,
193
192
  max_iter: int = 10,
194
- tol: Optional[float] = 1e-7,
193
+ tol: float | None = 1e-7,
195
194
  ) -> np.ndarray:
196
195
  """Compute the geometric mean of symmetric positive definite matrices.
197
196
 
@@ -314,9 +313,19 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
314
313
  following ways:
315
314
 
316
315
  * default ``cov_estimator`` is
317
- :class:`sklearn.covariance.EmpiricalCovariance`
318
- * default ``kind`` is ``"correlation"``
316
+ :class:`sklearn.covariance.EmpiricalCovariance` instead of
317
+ :class:`sklearn.covariance.LedoitWolf`, and ``cov_estimator=None`` is
318
+ not supported
319
+ * default ``kind`` is ``"correlation"`` instead of ``"covariance"``
319
320
  * supports Spearman's correlation via ``kind="spearman correlation"``
321
+ * supports Chatterjee's xi correlation via ``kind="xi correlation"``
322
+ * ``kind`` is validated when computing the matrices instead of when
323
+ fitting
324
+ * no ``verbose`` parameter, so nothing is logged while fitting
325
+ * ``inverse_transform()`` only knows the diagonal of
326
+ ``"correlation"`` and ``"partial correlation"`` matrices, so with
327
+ ``discard_diagonal=True`` the other kinds (including
328
+ ``"spearman correlation"``) need the ``diagonal`` to be passed
320
329
 
321
330
  Parameters
322
331
  ----------
@@ -330,7 +339,10 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
330
339
  If ``"spearman correlation"`` is used, the data will be ranked before
331
340
  estimating the covariance. For ``"xi correlation"``, the coefficient
332
341
  is not symmetric and should be interpreted as a measure of dependence
333
- [2]_ . For the use of ``"tangent"`` see [1]_ (default "correlation").
342
+ [2]_ ; ``cov_estimator`` and ``standardize`` are not used, ``mean_``
343
+ is symmetrized and, if ``vectorize=True``, only the lower triangular
344
+ part is kept. For the use of ``"tangent"`` see [1]_
345
+ (default "correlation").
334
346
  vectorize : bool, optional
335
347
  If True, connectivity matrices are reshaped into 1D arrays and only
336
348
  their flattened lower triangular parts are returned (default False).
@@ -338,17 +350,13 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
338
350
  If True, vectorized connectivity coefficients do not include the
339
351
  matrices diagonal elements. Used only when vectorize is set to True
340
352
  (default False).
341
- standardize : bool, optional
342
- If standardize is True, the data are centered and normed: their mean
343
- is put to 0 and their variance is put to 1 in the time dimension
344
- (default True).
345
-
346
- .. note::
347
-
348
- Added to control passing value to ``standardize`` of
349
- ``signal.clean`` to call new behavior since passing ``"zscore"`` or
350
- True (default) is deprecated. This parameter will be deprecated in
351
- version 0.13 and removed in version 0.15.
353
+ standardize : {"zscore_sample", "psc"} or None, optional
354
+ The strategy to standardize the signals before estimating the
355
+ covariance. ``"zscore_sample"`` sets them to zero mean and unit
356
+ variance (using the sample standard deviation), ``"psc"`` converts
357
+ them to percent signal change and None does not standardize them.
358
+ Only used for ``"correlation"`` and ``"spearman correlation"``
359
+ (default "zscore_sample").
352
360
 
353
361
  Attributes
354
362
  ----------
@@ -390,7 +398,7 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
390
398
  kind="correlation",
391
399
  vectorize=False,
392
400
  discard_diagonal=False,
393
- standardize=True,
401
+ standardize="zscore_sample",
394
402
  ):
395
403
  super().__init__(
396
404
  cov_estimator=cov_estimator,
@@ -400,6 +408,59 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
400
408
  standardize=standardize,
401
409
  )
402
410
 
411
+ def _validate_input(
412
+ self,
413
+ X, # noqa: N803
414
+ do_transform=False,
415
+ confounds=None,
416
+ ):
417
+ """Validate the input of ``_fit_transform``.
418
+
419
+ Parameters
420
+ ----------
421
+ X : iterable of numpy.ndarray
422
+ The time series of each subject.
423
+ do_transform : bool, optional
424
+ Whether the input will be transformed (default False).
425
+ confounds : numpy.ndarray, optional
426
+ The confounds (default None).
427
+
428
+ Returns
429
+ -------
430
+ list of numpy.ndarray
431
+ The time series of each subject.
432
+
433
+ Raises
434
+ ------
435
+ TypeError
436
+ If ``X`` is not iterable.
437
+ ValueError
438
+ If ``standardize`` is a boolean or
439
+ if ``X`` is a single subject and ``kind="tangent"``.
440
+
441
+ """
442
+ check_standardize(self.standardize)
443
+ if not hasattr(X, "__iter__"):
444
+ raise_error(
445
+ "Input must be an iterable of numpy arrays. "
446
+ f"Got {X.__class__.__name__}",
447
+ klass=TypeError,
448
+ )
449
+ # A single subject can be passed as a 2D array
450
+ if isinstance(X, np.ndarray) and X.ndim == 2:
451
+ X = [X]
452
+ self._check_input(X, confounds=confounds)
453
+ if do_transform and self.kind == "tangent" and len(X) <= 1:
454
+ # Check that people are applying transform to a group of subjects
455
+ # We can only impose this in transform,
456
+ # as it is legit to fit only on a single given reference point
457
+ raise_error(
458
+ "Tangent space parametrization can only be applied to a "
459
+ "group of subjects, as it returns deviations to the mean. "
460
+ f"You provided {X!r}"
461
+ )
462
+ return X
463
+
403
464
  def _fit_transform(
404
465
  self,
405
466
  X, # noqa: N803
@@ -408,9 +469,19 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
408
469
  confounds=None,
409
470
  ):
410
471
  """Avoid duplication of computation."""
411
- self._check_input(X, confounds=confounds)
472
+ X = self._validate_input(
473
+ X, do_transform=do_transform, confounds=confounds
474
+ )
412
475
  if do_fit:
476
+ if not hasattr(self.cov_estimator, "fit"):
477
+ raise_error(
478
+ "'cov_estimator' must be an estimator with '.fit()' and "
479
+ "'.covariance_' (e.g., from `sklearn.covariance` or a "
480
+ "custom estimator constructed similarly). Got: "
481
+ f"`{type(self.cov_estimator).__name__}`."
482
+ )
413
483
  self.cov_estimator_ = clone(self.cov_estimator)
484
+ self.n_features_in_ = next(iter(s.shape[1] for s in X))
414
485
 
415
486
  # Compute all the matrices, stored in "connectivities"
416
487
  if self.kind in ["correlation", "spearman correlation"]:
@@ -431,14 +502,6 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
431
502
 
432
503
  connectivities = [cov_to_corr(cov) for cov in covariances_std]
433
504
  elif self.kind == "xi correlation":
434
- if sys.version_info < (3, 10): # pragma: no cover
435
- raise_error(
436
- klass=RuntimeError,
437
- msg=(
438
- "scipy.stats.chatterjeexi is available from "
439
- "scipy 1.15.0 and that requires Python 3.10 and above."
440
- ),
441
- )
442
505
  connectivities = []
443
506
  for x in X:
444
507
  n_rois = x.shape[1]
@@ -461,10 +524,12 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
461
524
  ]
462
525
  else:
463
526
  allowed_kinds = (
527
+ "covariance",
464
528
  "correlation",
529
+ "spearman correlation",
465
530
  "partial correlation",
531
+ "xi correlation",
466
532
  "tangent",
467
- "covariance",
468
533
  "precision",
469
534
  )
470
535
  raise_error(
@@ -499,15 +564,6 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
499
564
 
500
565
  connectivities = np.array(connectivities)
501
566
 
502
- if confounds is not None and not self.vectorize:
503
- error_message = (
504
- "'confounds' are provided but vectorize=False. "
505
- "Confounds are only cleaned on vectorized matrices "
506
- "as second level connectome regression "
507
- "but not on symmetric matrices."
508
- )
509
- raise_error(error_message)
510
-
511
567
  if self.vectorize:
512
568
  connectivities = sym_matrix_to_vec(
513
569
  connectivities, discard_diagonal=self.discard_diagonal