junifer 0.0.4.dev829__py3-none-any.whl → 0.0.5__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 (206) hide show
  1. junifer/__init__.py +17 -0
  2. junifer/_version.py +2 -2
  3. junifer/api/__init__.py +4 -1
  4. junifer/api/cli.py +91 -1
  5. junifer/api/decorators.py +9 -0
  6. junifer/api/functions.py +56 -10
  7. junifer/api/parser.py +3 -0
  8. junifer/api/queue_context/__init__.py +4 -1
  9. junifer/api/queue_context/gnu_parallel_local_adapter.py +16 -6
  10. junifer/api/queue_context/htcondor_adapter.py +16 -5
  11. junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +41 -12
  12. junifer/api/queue_context/tests/test_htcondor_adapter.py +48 -15
  13. junifer/api/res/afni/run_afni_docker.sh +1 -1
  14. junifer/api/res/ants/run_ants_docker.sh +1 -1
  15. junifer/api/res/freesurfer/mri_binarize +3 -0
  16. junifer/api/res/freesurfer/mri_mc +3 -0
  17. junifer/api/res/freesurfer/mri_pretess +3 -0
  18. junifer/api/res/freesurfer/mris_convert +3 -0
  19. junifer/api/res/freesurfer/run_freesurfer_docker.sh +61 -0
  20. junifer/api/res/fsl/run_fsl_docker.sh +1 -1
  21. junifer/api/res/{run_conda.sh → run_conda.bash} +1 -1
  22. junifer/api/res/run_conda.zsh +23 -0
  23. junifer/api/res/run_venv.bash +22 -0
  24. junifer/api/res/{run_venv.sh → run_venv.zsh} +1 -1
  25. junifer/api/tests/test_api_utils.py +4 -2
  26. junifer/api/tests/test_cli.py +83 -0
  27. junifer/api/tests/test_functions.py +27 -2
  28. junifer/configs/__init__.py +1 -1
  29. junifer/configs/juseless/__init__.py +4 -1
  30. junifer/configs/juseless/datagrabbers/__init__.py +10 -1
  31. junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +4 -3
  32. junifer/configs/juseless/datagrabbers/camcan_vbm.py +3 -0
  33. junifer/configs/juseless/datagrabbers/ixi_vbm.py +4 -3
  34. junifer/configs/juseless/datagrabbers/tests/test_ucla.py +1 -3
  35. junifer/configs/juseless/datagrabbers/ucla.py +12 -9
  36. junifer/configs/juseless/datagrabbers/ukb_vbm.py +3 -0
  37. junifer/data/__init__.py +21 -1
  38. junifer/data/coordinates.py +10 -19
  39. junifer/data/masks/ukb/UKB_15K_GM_template.nii.gz +0 -0
  40. junifer/data/masks.py +58 -87
  41. junifer/data/parcellations.py +14 -3
  42. junifer/data/template_spaces.py +4 -1
  43. junifer/data/tests/test_masks.py +26 -37
  44. junifer/data/utils.py +3 -0
  45. junifer/datagrabber/__init__.py +18 -1
  46. junifer/datagrabber/aomic/__init__.py +3 -0
  47. junifer/datagrabber/aomic/id1000.py +70 -37
  48. junifer/datagrabber/aomic/piop1.py +69 -36
  49. junifer/datagrabber/aomic/piop2.py +71 -38
  50. junifer/datagrabber/aomic/tests/test_id1000.py +44 -100
  51. junifer/datagrabber/aomic/tests/test_piop1.py +65 -108
  52. junifer/datagrabber/aomic/tests/test_piop2.py +45 -102
  53. junifer/datagrabber/base.py +13 -6
  54. junifer/datagrabber/datalad_base.py +13 -1
  55. junifer/datagrabber/dmcc13_benchmark.py +36 -53
  56. junifer/datagrabber/hcp1200/__init__.py +3 -0
  57. junifer/datagrabber/hcp1200/datalad_hcp1200.py +3 -0
  58. junifer/datagrabber/hcp1200/hcp1200.py +4 -1
  59. junifer/datagrabber/multiple.py +45 -6
  60. junifer/datagrabber/pattern.py +170 -62
  61. junifer/datagrabber/pattern_datalad.py +25 -12
  62. junifer/datagrabber/pattern_validation_mixin.py +388 -0
  63. junifer/datagrabber/tests/test_datalad_base.py +4 -4
  64. junifer/datagrabber/tests/test_dmcc13_benchmark.py +46 -19
  65. junifer/datagrabber/tests/test_multiple.py +161 -84
  66. junifer/datagrabber/tests/test_pattern.py +45 -0
  67. junifer/datagrabber/tests/test_pattern_datalad.py +4 -4
  68. junifer/datagrabber/tests/test_pattern_validation_mixin.py +249 -0
  69. junifer/datareader/__init__.py +4 -1
  70. junifer/datareader/default.py +95 -43
  71. junifer/external/BrainPrint/brainprint/__init__.py +4 -0
  72. junifer/external/BrainPrint/brainprint/_version.py +3 -0
  73. junifer/external/BrainPrint/brainprint/asymmetry.py +91 -0
  74. junifer/external/BrainPrint/brainprint/brainprint.py +441 -0
  75. junifer/external/BrainPrint/brainprint/surfaces.py +258 -0
  76. junifer/external/BrainPrint/brainprint/utils/__init__.py +1 -0
  77. junifer/external/BrainPrint/brainprint/utils/_config.py +112 -0
  78. junifer/external/BrainPrint/brainprint/utils/utils.py +188 -0
  79. junifer/external/__init__.py +1 -1
  80. junifer/external/nilearn/__init__.py +5 -1
  81. junifer/external/nilearn/junifer_connectivity_measure.py +483 -0
  82. junifer/external/nilearn/junifer_nifti_spheres_masker.py +23 -9
  83. junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +1089 -0
  84. junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py +76 -1
  85. junifer/markers/__init__.py +23 -1
  86. junifer/markers/base.py +68 -28
  87. junifer/markers/brainprint.py +459 -0
  88. junifer/markers/collection.py +10 -2
  89. junifer/markers/complexity/__init__.py +10 -0
  90. junifer/markers/complexity/complexity_base.py +26 -43
  91. junifer/markers/complexity/hurst_exponent.py +3 -0
  92. junifer/markers/complexity/multiscale_entropy_auc.py +3 -0
  93. junifer/markers/complexity/perm_entropy.py +3 -0
  94. junifer/markers/complexity/range_entropy.py +3 -0
  95. junifer/markers/complexity/range_entropy_auc.py +3 -0
  96. junifer/markers/complexity/sample_entropy.py +3 -0
  97. junifer/markers/complexity/tests/test_hurst_exponent.py +11 -3
  98. junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +11 -3
  99. junifer/markers/complexity/tests/test_perm_entropy.py +11 -3
  100. junifer/markers/complexity/tests/test_range_entropy.py +11 -3
  101. junifer/markers/complexity/tests/test_range_entropy_auc.py +11 -3
  102. junifer/markers/complexity/tests/test_sample_entropy.py +11 -3
  103. junifer/markers/complexity/tests/test_weighted_perm_entropy.py +11 -3
  104. junifer/markers/complexity/weighted_perm_entropy.py +3 -0
  105. junifer/markers/ets_rss.py +27 -42
  106. junifer/markers/falff/__init__.py +3 -0
  107. junifer/markers/falff/_afni_falff.py +5 -2
  108. junifer/markers/falff/_junifer_falff.py +3 -0
  109. junifer/markers/falff/falff_base.py +20 -46
  110. junifer/markers/falff/falff_parcels.py +56 -27
  111. junifer/markers/falff/falff_spheres.py +60 -29
  112. junifer/markers/falff/tests/test_falff_parcels.py +39 -23
  113. junifer/markers/falff/tests/test_falff_spheres.py +39 -23
  114. junifer/markers/functional_connectivity/__init__.py +9 -0
  115. junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +63 -60
  116. junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +45 -32
  117. junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +49 -36
  118. junifer/markers/functional_connectivity/functional_connectivity_base.py +71 -70
  119. junifer/markers/functional_connectivity/functional_connectivity_parcels.py +34 -25
  120. junifer/markers/functional_connectivity/functional_connectivity_spheres.py +40 -30
  121. junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +11 -7
  122. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +27 -7
  123. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +28 -12
  124. junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +35 -11
  125. junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +36 -62
  126. junifer/markers/parcel_aggregation.py +47 -61
  127. junifer/markers/reho/__init__.py +3 -0
  128. junifer/markers/reho/_afni_reho.py +5 -2
  129. junifer/markers/reho/_junifer_reho.py +4 -1
  130. junifer/markers/reho/reho_base.py +8 -27
  131. junifer/markers/reho/reho_parcels.py +28 -17
  132. junifer/markers/reho/reho_spheres.py +27 -18
  133. junifer/markers/reho/tests/test_reho_parcels.py +8 -3
  134. junifer/markers/reho/tests/test_reho_spheres.py +8 -3
  135. junifer/markers/sphere_aggregation.py +43 -59
  136. junifer/markers/temporal_snr/__init__.py +3 -0
  137. junifer/markers/temporal_snr/temporal_snr_base.py +23 -32
  138. junifer/markers/temporal_snr/temporal_snr_parcels.py +9 -6
  139. junifer/markers/temporal_snr/temporal_snr_spheres.py +9 -6
  140. junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +6 -3
  141. junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +6 -3
  142. junifer/markers/tests/test_brainprint.py +58 -0
  143. junifer/markers/tests/test_collection.py +9 -8
  144. junifer/markers/tests/test_ets_rss.py +15 -9
  145. junifer/markers/tests/test_markers_base.py +17 -18
  146. junifer/markers/tests/test_parcel_aggregation.py +93 -32
  147. junifer/markers/tests/test_sphere_aggregation.py +72 -19
  148. junifer/onthefly/__init__.py +4 -1
  149. junifer/onthefly/read_transform.py +3 -0
  150. junifer/pipeline/__init__.py +9 -1
  151. junifer/pipeline/pipeline_step_mixin.py +21 -4
  152. junifer/pipeline/registry.py +3 -0
  153. junifer/pipeline/singleton.py +3 -0
  154. junifer/pipeline/tests/test_registry.py +1 -1
  155. junifer/pipeline/update_meta_mixin.py +3 -0
  156. junifer/pipeline/utils.py +67 -1
  157. junifer/pipeline/workdir_manager.py +3 -0
  158. junifer/preprocess/__init__.py +10 -2
  159. junifer/preprocess/base.py +6 -3
  160. junifer/preprocess/confounds/__init__.py +3 -0
  161. junifer/preprocess/confounds/fmriprep_confound_remover.py +47 -60
  162. junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +72 -113
  163. junifer/preprocess/smoothing/__init__.py +9 -0
  164. junifer/preprocess/smoothing/_afni_smoothing.py +119 -0
  165. junifer/preprocess/smoothing/_fsl_smoothing.py +116 -0
  166. junifer/preprocess/smoothing/_nilearn_smoothing.py +69 -0
  167. junifer/preprocess/smoothing/smoothing.py +174 -0
  168. junifer/preprocess/smoothing/tests/test_smoothing.py +94 -0
  169. junifer/preprocess/warping/__init__.py +3 -0
  170. junifer/preprocess/warping/_ants_warper.py +3 -0
  171. junifer/preprocess/warping/_fsl_warper.py +3 -0
  172. junifer/stats.py +4 -1
  173. junifer/storage/__init__.py +9 -1
  174. junifer/storage/base.py +40 -1
  175. junifer/storage/hdf5.py +71 -9
  176. junifer/storage/pandas_base.py +3 -0
  177. junifer/storage/sqlite.py +3 -0
  178. junifer/storage/tests/test_hdf5.py +82 -10
  179. junifer/storage/utils.py +9 -0
  180. junifer/testing/__init__.py +4 -1
  181. junifer/testing/datagrabbers.py +13 -6
  182. junifer/testing/tests/test_partlycloudytesting_datagrabber.py +7 -7
  183. junifer/testing/utils.py +3 -0
  184. junifer/utils/__init__.py +13 -2
  185. junifer/utils/fs.py +3 -0
  186. junifer/utils/helpers.py +32 -1
  187. junifer/utils/logging.py +33 -4
  188. junifer/utils/tests/test_logging.py +8 -0
  189. {junifer-0.0.4.dev829.dist-info → junifer-0.0.5.dist-info}/METADATA +17 -16
  190. junifer-0.0.5.dist-info/RECORD +275 -0
  191. {junifer-0.0.4.dev829.dist-info → junifer-0.0.5.dist-info}/WHEEL +1 -1
  192. junifer/datagrabber/tests/test_datagrabber_utils.py +0 -218
  193. junifer/datagrabber/utils.py +0 -230
  194. junifer/preprocess/ants/__init__.py +0 -4
  195. junifer/preprocess/ants/ants_apply_transforms_warper.py +0 -185
  196. junifer/preprocess/ants/tests/test_ants_apply_transforms_warper.py +0 -56
  197. junifer/preprocess/bold_warper.py +0 -265
  198. junifer/preprocess/fsl/__init__.py +0 -4
  199. junifer/preprocess/fsl/apply_warper.py +0 -179
  200. junifer/preprocess/fsl/tests/test_apply_warper.py +0 -45
  201. junifer/preprocess/tests/test_bold_warper.py +0 -159
  202. junifer-0.0.4.dev829.dist-info/RECORD +0 -257
  203. {junifer-0.0.4.dev829.dist-info → junifer-0.0.5.dist-info}/AUTHORS.rst +0 -0
  204. {junifer-0.0.4.dev829.dist-info → junifer-0.0.5.dist-info}/LICENSE.md +0 -0
  205. {junifer-0.0.4.dev829.dist-info → junifer-0.0.5.dist-info}/entry_points.txt +0 -0
  206. {junifer-0.0.4.dev829.dist-info → junifer-0.0.5.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,9 @@ from ..utils import raise_error
13
13
  from .functional_connectivity_base import FunctionalConnectivityBase
14
14
 
15
15
 
16
+ __all__ = ["FunctionalConnectivitySpheres"]
17
+
18
+
16
19
  @register_marker
17
20
  class FunctionalConnectivitySpheres(FunctionalConnectivityBase):
18
21
  """Class for functional connectivity using coordinates (spheres).
@@ -20,35 +23,42 @@ class FunctionalConnectivitySpheres(FunctionalConnectivityBase):
20
23
  Parameters
21
24
  ----------
22
25
  coords : str
23
- The name of the coordinates list to use. See
24
- :func:`.list_coordinates` for options.
25
- radius : float, optional
26
- The radius of the sphere in mm. If None, the signal will be extracted
27
- from a single voxel. See :class:`nilearn.maskers.NiftiSpheresMasker`
28
- for more information (default None).
26
+ The name of the coordinates list to use.
27
+ See :func:`.list_coordinates` for options.
28
+ radius : positive float, optional
29
+ The radius of the sphere around each coordinates in millimetres.
30
+ If None, the signal will be extracted from a single voxel.
31
+ See :class:`.JuniferNiftiSpheresMasker` for more information
32
+ (default None).
29
33
  allow_overlap : bool, optional
30
34
  Whether to allow overlapping spheres. If False, an error is raised if
31
- the spheres overlap (default is False).
35
+ the spheres overlap (default False).
32
36
  agg_method : str, optional
33
- The aggregation method to use.
34
- See :func:`.get_aggfunc_by_name` for more information
35
- (default None).
37
+ The method to perform aggregation using.
38
+ See :func:`.get_aggfunc_by_name` for options
39
+ (default "mean").
36
40
  agg_method_params : dict, optional
37
- The parameters to pass to the aggregation method (default None).
38
- cor_method : str, optional
39
- The method to perform correlation using. Check valid options in
40
- :class:`nilearn.connectome.ConnectivityMeasure` (default "covariance").
41
- cor_method_params : dict, optional
42
- Parameters to pass to the correlation function. Check valid options in
43
- :class:`nilearn.connectome.ConnectivityMeasure` (default None).
41
+ Parameters to pass to the aggregation function.
42
+ See :func:`.get_aggfunc_by_name` for options
43
+ (default None).
44
+ conn_method : str, optional
45
+ The method to perform connectivity measure using.
46
+ See :class:`.JuniferConnectivityMeasure` for options
47
+ (default "correlation").
48
+ conn_method_params : dict, optional
49
+ Parameters to pass to :class:`.JuniferConnectivityMeasure`.
50
+ If None, ``{"empirical": True}`` will be used, which would mean
51
+ :class:`sklearn.covariance.EmpiricalCovariance` is used to compute
52
+ covariance. If usage of :class:`sklearn.covariance.LedoitWolf` is
53
+ desired, ``{"empirical": False}`` should be passed
54
+ (default None).
44
55
  masks : str, dict or list of dict or str, optional
45
56
  The specification of the masks to apply to regions before extracting
46
57
  signals. Check :ref:`Using Masks <using_masks>` for more details.
47
58
  If None, will not apply any mask (default None).
48
59
  name : str, optional
49
- The name of the marker. By default, it will use
50
- KIND_FunctionalConnectivitySpheres where KIND is the kind of data it
51
- was applied to (default None).
60
+ The name of the marker. If None, will use
61
+ ``BOLD_FunctionalConnectivitySpheres`` (default None).
52
62
 
53
63
  """
54
64
 
@@ -59,8 +69,8 @@ class FunctionalConnectivitySpheres(FunctionalConnectivityBase):
59
69
  allow_overlap: bool = False,
60
70
  agg_method: str = "mean",
61
71
  agg_method_params: Optional[Dict] = None,
62
- cor_method: str = "covariance",
63
- cor_method_params: Optional[Dict] = None,
72
+ conn_method: str = "correlation",
73
+ conn_method_params: Optional[Dict] = None,
64
74
  masks: Union[str, Dict, List[Union[Dict, str]], None] = None,
65
75
  name: Optional[str] = None,
66
76
  ) -> None:
@@ -72,8 +82,8 @@ class FunctionalConnectivitySpheres(FunctionalConnectivityBase):
72
82
  super().__init__(
73
83
  agg_method=agg_method,
74
84
  agg_method_params=agg_method_params,
75
- cor_method=cor_method,
76
- cor_method_params=cor_method_params,
85
+ conn_method=conn_method,
86
+ conn_method_params=conn_method_params,
77
87
  masks=masks,
78
88
  name=name,
79
89
  )
@@ -101,11 +111,13 @@ class FunctionalConnectivitySpheres(FunctionalConnectivityBase):
101
111
  to the user or stored in the storage by calling the store method
102
112
  with this as a parameter. The dictionary has the following keys:
103
113
 
104
- * ``data`` : the actual computed values as a numpy.ndarray
105
- * ``col_names`` : the column labels for the computed values as list
114
+ * ``aggregation`` : dictionary with the following keys:
115
+
116
+ - ``data`` : ROI values as ``numpy.ndarray``
117
+ - ``col_names`` : ROI labels as list of str
106
118
 
107
119
  """
108
- sphere_aggregation = SphereAggregation(
120
+ return SphereAggregation(
109
121
  coords=self.coords,
110
122
  radius=self.radius,
111
123
  allow_overlap=self.allow_overlap,
@@ -113,6 +125,4 @@ class FunctionalConnectivitySpheres(FunctionalConnectivityBase):
113
125
  method_params=self.agg_method_params,
114
126
  masks=self.masks,
115
127
  on="BOLD",
116
- )
117
- # Return the 2D timeseries after sphere aggregation
118
- return sphere_aggregation.compute(input, extra_input=extra_input)
128
+ ).compute(input=input, extra_input=extra_input)
@@ -27,16 +27,17 @@ def test_init() -> None:
27
27
  CrossParcellationFC(
28
28
  parcellation_one="a",
29
29
  parcellation_two="a",
30
- correlation_method="pearson",
30
+ corr_method="pearson",
31
31
  )
32
32
 
33
33
 
34
34
  def test_get_output_type() -> None:
35
35
  """Test CrossParcellationFC get_output_type()."""
36
- crossparcellation = CrossParcellationFC(
36
+ assert "matrix" == CrossParcellationFC(
37
37
  parcellation_one=parcellation_one, parcellation_two=parcellation_two
38
+ ).get_output_type(
39
+ input_type="BOLD", output_feature="functional_connectivity"
38
40
  )
39
- assert "matrix" == crossparcellation.get_output_type("BOLD")
40
41
 
41
42
 
42
43
  @pytest.mark.skipif(
@@ -57,9 +58,11 @@ def test_compute(tmp_path: Path) -> None:
57
58
  crossparcellation = CrossParcellationFC(
58
59
  parcellation_one=parcellation_one,
59
60
  parcellation_two=parcellation_two,
60
- correlation_method="spearman",
61
+ corr_method="spearman",
61
62
  )
62
- out = crossparcellation.compute(element_data["BOLD"])
63
+ out = crossparcellation.compute(element_data["BOLD"])[
64
+ "functional_connectivity"
65
+ ]
63
66
  assert out["data"].shape == (200, 100)
64
67
  assert len(out["col_names"]) == 100
65
68
  assert len(out["row_names"]) == 200
@@ -83,7 +86,7 @@ def test_store(tmp_path: Path) -> None:
83
86
  crossparcellation = CrossParcellationFC(
84
87
  parcellation_one=parcellation_one,
85
88
  parcellation_two=parcellation_two,
86
- correlation_method="spearman",
89
+ corr_method="spearman",
87
90
  )
88
91
  storage = SQLiteFeatureStorage(
89
92
  uri=tmp_path / "test_crossparcellation.sqlite", upsert="ignore"
@@ -92,5 +95,6 @@ def test_store(tmp_path: Path) -> None:
92
95
  crossparcellation.fit_transform(input=element_data, storage=storage)
93
96
  features = storage.list_features()
94
97
  assert any(
95
- x["name"] == "BOLD_CrossParcellationFC" for x in features.values()
98
+ x["name"] == "BOLD_CrossParcellationFC_functional_connectivity"
99
+ for x in features.values()
96
100
  )
@@ -5,6 +5,9 @@
5
5
  # License: AGPL
6
6
 
7
7
  from pathlib import Path
8
+ from typing import Dict
9
+
10
+ import pytest
8
11
 
9
12
  from junifer.datareader import DefaultDataReader
10
13
  from junifer.markers.functional_connectivity import EdgeCentricFCParcels
@@ -12,35 +15,51 @@ from junifer.storage import SQLiteFeatureStorage
12
15
  from junifer.testing.datagrabbers import PartlyCloudyTestingDataGrabber
13
16
 
14
17
 
15
- def test_EdgeCentricFCParcels(tmp_path: Path) -> None:
18
+ @pytest.mark.parametrize(
19
+ "conn_method_params",
20
+ [
21
+ {"empirical": False},
22
+ {"empirical": True},
23
+ ],
24
+ )
25
+ def test_EdgeCentricFCParcels(
26
+ tmp_path: Path,
27
+ conn_method_params: Dict[str, bool],
28
+ ) -> None:
16
29
  """Test EdgeCentricFCParcels.
17
30
 
18
31
  Parameters
19
32
  ----------
20
33
  tmp_path : pathlib.Path
21
34
  The path to the test directory.
35
+ conn_method_params : dict
36
+ The parametrized parameters to connectivity measure method.
22
37
 
23
38
  """
24
39
  with PartlyCloudyTestingDataGrabber() as dg:
40
+ # Get element data
25
41
  element_data = DefaultDataReader().fit_transform(dg["sub-01"])
42
+ # Setup marker
26
43
  marker = EdgeCentricFCParcels(
27
44
  parcellation="TianxS1x3TxMNInonlinear2009cAsym",
28
- cor_method_params={"empirical": True},
45
+ conn_method="correlation",
46
+ conn_method_params=conn_method_params,
29
47
  )
30
48
  # Check correct output
31
- assert marker.get_output_type("BOLD") == "matrix"
49
+ assert "matrix" == marker.get_output_type(
50
+ input_type="BOLD", output_feature="functional_connectivity"
51
+ )
32
52
 
33
53
  # Fit-transform the data
34
54
  edge_fc = marker.fit_transform(element_data)
35
- edge_fc_bold = edge_fc["BOLD"]
55
+ edge_fc_bold = edge_fc["BOLD"]["functional_connectivity"]
36
56
 
37
57
  # For 16 ROIs we should get (16 * (16 -1) / 2) edges in the ETS
38
58
  n_edges = int(16 * (16 - 1) / 2)
39
59
  assert "data" in edge_fc_bold
40
60
  assert "row_names" in edge_fc_bold
41
61
  assert "col_names" in edge_fc_bold
42
- assert edge_fc_bold["data"].shape[0] == n_edges
43
- assert edge_fc_bold["data"].shape[1] == n_edges
62
+ assert edge_fc_bold["data"].shape == (n_edges, n_edges)
44
63
  assert len(set(edge_fc_bold["row_names"])) == n_edges
45
64
  assert len(set(edge_fc_bold["col_names"])) == n_edges
46
65
 
@@ -51,5 +70,6 @@ def test_EdgeCentricFCParcels(tmp_path: Path) -> None:
51
70
  marker.fit_transform(input=element_data, storage=storage)
52
71
  features = storage.list_features()
53
72
  assert any(
54
- x["name"] == "BOLD_EdgeCentricFCParcels" for x in features.values()
73
+ x["name"] == "BOLD_EdgeCentricFCParcels_functional_connectivity"
74
+ for x in features.values()
55
75
  )
@@ -5,6 +5,9 @@
5
5
  # License: AGPL
6
6
 
7
7
  from pathlib import Path
8
+ from typing import Dict
9
+
10
+ import pytest
8
11
 
9
12
  from junifer.datareader import DefaultDataReader
10
13
  from junifer.markers.functional_connectivity import EdgeCentricFCSpheres
@@ -12,26 +15,45 @@ from junifer.storage import SQLiteFeatureStorage
12
15
  from junifer.testing.datagrabbers import SPMAuditoryTestingDataGrabber
13
16
 
14
17
 
15
- def test_EdgeCentricFCSpheres(tmp_path: Path) -> None:
18
+ @pytest.mark.parametrize(
19
+ "conn_method_params",
20
+ [
21
+ {"empirical": False},
22
+ {"empirical": True},
23
+ ],
24
+ )
25
+ def test_EdgeCentricFCSpheres(
26
+ tmp_path: Path,
27
+ conn_method_params: Dict[str, bool],
28
+ ) -> None:
16
29
  """Test EdgeCentricFCSpheres.
17
30
 
18
31
  Parameters
19
32
  ----------
20
33
  tmp_path : pathlib.Path
21
34
  The path to the test directory.
35
+ conn_method_params : dict
36
+ The parametrized parameters to connectivity measure method.
22
37
 
23
38
  """
24
39
  with SPMAuditoryTestingDataGrabber() as dg:
40
+ # Get element data
25
41
  element_data = DefaultDataReader().fit_transform(dg["sub001"])
42
+ # Setup marker
26
43
  marker = EdgeCentricFCSpheres(
27
- coords="DMNBuckner", radius=5.0, cor_method="correlation"
44
+ coords="DMNBuckner",
45
+ radius=5.0,
46
+ conn_method="correlation",
47
+ conn_method_params=conn_method_params,
28
48
  )
29
49
  # Check correct output
30
- assert marker.get_output_type("BOLD") == "matrix"
50
+ assert "matrix" == marker.get_output_type(
51
+ input_type="BOLD", output_feature="functional_connectivity"
52
+ )
31
53
 
32
54
  # Fit-transform the data
33
55
  edge_fc = marker.fit_transform(element_data)
34
- edge_fc_bold = edge_fc["BOLD"]
56
+ edge_fc_bold = edge_fc["BOLD"]["functional_connectivity"]
35
57
 
36
58
  # There are six DMNBuckner coordinates, so
37
59
  # for 6 ROIs we should get (6 * (6 -1) / 2) edges in the ETS
@@ -43,13 +65,6 @@ def test_EdgeCentricFCSpheres(tmp_path: Path) -> None:
43
65
  assert len(set(edge_fc_bold["row_names"])) == n_edges
44
66
  assert len(set(edge_fc_bold["col_names"])) == n_edges
45
67
 
46
- # Check empirical correlation method parameters
47
- marker = EdgeCentricFCSpheres(
48
- coords="DMNBuckner",
49
- radius=5.0,
50
- cor_method="correlation",
51
- cor_method_params={"empirical": True},
52
- )
53
68
  # Store
54
69
  storage = SQLiteFeatureStorage(
55
70
  uri=tmp_path / "test_edge_fc_spheres.sqlite", upsert="ignore"
@@ -57,5 +72,6 @@ def test_EdgeCentricFCSpheres(tmp_path: Path) -> None:
57
72
  marker.fit_transform(input=element_data, storage=storage)
58
73
  features = storage.list_features()
59
74
  assert any(
60
- x["name"] == "BOLD_EdgeCentricFCSpheres" for x in features.values()
75
+ x["name"] == "BOLD_EdgeCentricFCSpheres_functional_connectivity"
76
+ for x in features.values()
61
77
  )
@@ -6,10 +6,13 @@
6
6
  # License: AGPL
7
7
 
8
8
  from pathlib import Path
9
+ from typing import TYPE_CHECKING, Dict, Type
9
10
 
11
+ import pytest
10
12
  from nilearn.connectome import ConnectivityMeasure
11
13
  from nilearn.maskers import NiftiLabelsMasker
12
14
  from numpy.testing import assert_array_almost_equal
15
+ from sklearn.covariance import EmpiricalCovariance, LedoitWolf
13
16
 
14
17
  from junifer.data import get_parcellation
15
18
  from junifer.datareader import DefaultDataReader
@@ -20,26 +23,51 @@ from junifer.storage import SQLiteFeatureStorage
20
23
  from junifer.testing.datagrabbers import PartlyCloudyTestingDataGrabber
21
24
 
22
25
 
23
- def test_FunctionalConnectivityParcels(tmp_path: Path) -> None:
26
+ if TYPE_CHECKING:
27
+ from sklearn.base import BaseEstimator
28
+
29
+
30
+ @pytest.mark.parametrize(
31
+ "conn_method_params, cov_estimator",
32
+ [
33
+ ({"empirical": False}, LedoitWolf(store_precision=False)),
34
+ ({"empirical": True}, EmpiricalCovariance(store_precision=False)),
35
+ ],
36
+ )
37
+ def test_FunctionalConnectivityParcels(
38
+ tmp_path: Path,
39
+ conn_method_params: Dict[str, bool],
40
+ cov_estimator: Type["BaseEstimator"],
41
+ ) -> None:
24
42
  """Test FunctionalConnectivityParcels.
25
43
 
26
44
  Parameters
27
45
  ----------
28
46
  tmp_path : pathlib.Path
29
47
  The path to the test directory.
48
+ conn_method_params : dict
49
+ The parametrized parameters to connectivity measure method.
50
+ cov_estimator : estimator object
51
+ The parametrized covariance estimator.
30
52
 
31
53
  """
32
54
  with PartlyCloudyTestingDataGrabber() as dg:
55
+ # Get element data
33
56
  element_data = DefaultDataReader().fit_transform(dg["sub-01"])
57
+ # Setup marker
34
58
  marker = FunctionalConnectivityParcels(
35
- parcellation="TianxS1x3TxMNInonlinear2009cAsym"
59
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
60
+ conn_method="correlation",
61
+ conn_method_params=conn_method_params,
36
62
  )
37
63
  # Check correct output
38
- assert marker.get_output_type("BOLD") == "matrix"
64
+ assert "matrix" == marker.get_output_type(
65
+ input_type="BOLD", output_feature="functional_connectivity"
66
+ )
39
67
 
40
68
  # Fit-transform the data
41
69
  fc = marker.fit_transform(element_data)
42
- fc_bold = fc["BOLD"]
70
+ fc_bold = fc["BOLD"]["functional_connectivity"]
43
71
 
44
72
  assert "data" in fc_bold
45
73
  assert "row_names" in fc_bold
@@ -63,7 +91,7 @@ def test_FunctionalConnectivityParcels(tmp_path: Path) -> None:
63
91
  )
64
92
  # Compute the connectivity measure
65
93
  connectivity_measure = ConnectivityMeasure(
66
- kind="covariance"
94
+ cov_estimator=cov_estimator, kind="correlation" # type: ignore
67
95
  ).fit_transform([extracted_timeseries])[0]
68
96
 
69
97
  # Check that FC are almost equal
@@ -71,11 +99,6 @@ def test_FunctionalConnectivityParcels(tmp_path: Path) -> None:
71
99
  connectivity_measure, fc_bold["data"], decimal=3
72
100
  )
73
101
 
74
- # Check empirical correlation method parameters
75
- marker = FunctionalConnectivityParcels(
76
- parcellation="TianxS1x3TxMNInonlinear2009cAsym",
77
- cor_method_params={"empirical": True},
78
- )
79
102
  # Store
80
103
  storage = SQLiteFeatureStorage(
81
104
  uri=tmp_path / "test_fc_parcels.sqlite", upsert="ignore"
@@ -83,6 +106,7 @@ def test_FunctionalConnectivityParcels(tmp_path: Path) -> None:
83
106
  marker.fit_transform(input=element_data, storage=storage)
84
107
  features = storage.list_features()
85
108
  assert any(
86
- x["name"] == "BOLD_FunctionalConnectivityParcels"
109
+ x["name"]
110
+ == "BOLD_FunctionalConnectivityParcels_functional_connectivity"
87
111
  for x in features.values()
88
112
  )
@@ -7,12 +7,13 @@
7
7
  # License: AGPL
8
8
 
9
9
  from pathlib import Path
10
+ from typing import TYPE_CHECKING, Dict, Type
10
11
 
11
12
  import pytest
12
13
  from nilearn.connectome import ConnectivityMeasure
13
14
  from nilearn.maskers import NiftiSpheresMasker
14
15
  from numpy.testing import assert_array_almost_equal
15
- from sklearn.covariance import EmpiricalCovariance
16
+ from sklearn.covariance import EmpiricalCovariance, LedoitWolf
16
17
 
17
18
  from junifer.data import get_coordinates
18
19
  from junifer.datareader import DefaultDataReader
@@ -23,26 +24,52 @@ from junifer.storage import SQLiteFeatureStorage
23
24
  from junifer.testing.datagrabbers import SPMAuditoryTestingDataGrabber
24
25
 
25
26
 
26
- def test_FunctionalConnectivitySpheres(tmp_path: Path) -> None:
27
+ if TYPE_CHECKING:
28
+ from sklearn.base import BaseEstimator
29
+
30
+
31
+ @pytest.mark.parametrize(
32
+ "conn_method_params, cov_estimator",
33
+ [
34
+ ({"empirical": False}, LedoitWolf(store_precision=False)),
35
+ ({"empirical": True}, EmpiricalCovariance(store_precision=False)),
36
+ ],
37
+ )
38
+ def test_FunctionalConnectivitySpheres(
39
+ tmp_path: Path,
40
+ conn_method_params: Dict[str, bool],
41
+ cov_estimator: Type["BaseEstimator"],
42
+ ) -> None:
27
43
  """Test FunctionalConnectivitySpheres.
28
44
 
29
45
  Parameters
30
46
  ----------
31
47
  tmp_path : pathlib.Path
32
48
  The path to the test directory.
49
+ conn_method_params : dict
50
+ The parametrized parameters to connectivity measure method.
51
+ cov_estimator : estimator object
52
+ The parametrized covariance estimator.
33
53
 
34
54
  """
35
55
  with SPMAuditoryTestingDataGrabber() as dg:
56
+ # Get element data
36
57
  element_data = DefaultDataReader().fit_transform(dg["sub001"])
58
+ # Setup marker
37
59
  marker = FunctionalConnectivitySpheres(
38
- coords="DMNBuckner", radius=5.0, cor_method="correlation"
60
+ coords="DMNBuckner",
61
+ radius=5.0,
62
+ conn_method="correlation",
63
+ conn_method_params=conn_method_params,
39
64
  )
40
65
  # Check correct output
41
- assert marker.get_output_type("BOLD") == "matrix"
66
+ assert "matrix" == marker.get_output_type(
67
+ input_type="BOLD", output_feature="functional_connectivity"
68
+ )
42
69
 
43
70
  # Fit-transform the data
44
71
  fc = marker.fit_transform(element_data)
45
- fc_bold = fc["BOLD"]
72
+ fc_bold = fc["BOLD"]["functional_connectivity"]
46
73
 
47
74
  assert "data" in fc_bold
48
75
  assert "row_names" in fc_bold
@@ -65,7 +92,7 @@ def test_FunctionalConnectivitySpheres(tmp_path: Path) -> None:
65
92
  )
66
93
  # Compute the connectivity measure
67
94
  connectivity_measure = ConnectivityMeasure(
68
- kind="correlation"
95
+ cov_estimator=cov_estimator, kind="correlation" # type: ignore
69
96
  ).fit_transform([extracted_timeseries])[0]
70
97
 
71
98
  # Check that FC are almost equal
@@ -80,68 +107,15 @@ def test_FunctionalConnectivitySpheres(tmp_path: Path) -> None:
80
107
  marker.fit_transform(input=element_data, storage=storage)
81
108
  features = storage.list_features()
82
109
  assert any(
83
- x["name"] == "BOLD_FunctionalConnectivitySpheres"
110
+ x["name"]
111
+ == "BOLD_FunctionalConnectivitySpheres_functional_connectivity"
84
112
  for x in features.values()
85
113
  )
86
114
 
87
115
 
88
- def test_FunctionalConnectivitySpheres_empirical(tmp_path: Path) -> None:
89
- """Test FunctionalConnectivitySpheres with empirical covariance.
90
-
91
- Parameters
92
- ----------
93
- tmp_path : pathlib.Path
94
- The path to the test directory.
95
-
96
- """
97
- with SPMAuditoryTestingDataGrabber() as dg:
98
- element_data = DefaultDataReader().fit_transform(dg["sub001"])
99
- marker = FunctionalConnectivitySpheres(
100
- coords="DMNBuckner",
101
- radius=5.0,
102
- cor_method="correlation",
103
- cor_method_params={"empirical": True},
104
- )
105
- # Check correct output
106
- assert marker.get_output_type("BOLD") == "matrix"
107
-
108
- # Fit-transform the data
109
- fc = marker.fit_transform(element_data)
110
- fc_bold = fc["BOLD"]
111
-
112
- assert "data" in fc_bold
113
- assert "row_names" in fc_bold
114
- assert "col_names" in fc_bold
115
- assert fc_bold["data"].shape == (6, 6)
116
- assert len(set(fc_bold["row_names"])) == 6
117
- assert len(set(fc_bold["col_names"])) == 6
118
-
119
- # Compare with nilearn
120
- # Load testing coordinates for the target data
121
- testing_coords, _ = get_coordinates(
122
- coords="DMNBuckner", target_data=element_data["BOLD"]
123
- )
124
- # Extract timeseries
125
- nifti_spheres_masker = NiftiSpheresMasker(
126
- seeds=testing_coords, radius=5.0
127
- )
128
- extracted_timeseries = nifti_spheres_masker.fit_transform(
129
- element_data["BOLD"]["data"]
130
- )
131
- # Compute the connectivity measure
132
- connectivity_measure = ConnectivityMeasure(
133
- cov_estimator=EmpiricalCovariance(), kind="correlation" # type: ignore
134
- ).fit_transform([extracted_timeseries])[0]
135
-
136
- # Check that FC are almost equal
137
- assert_array_almost_equal(
138
- connectivity_measure, fc_bold["data"], decimal=3
139
- )
140
-
141
-
142
116
  def test_FunctionalConnectivitySpheres_error() -> None:
143
117
  """Test FunctionalConnectivitySpheres errors."""
144
118
  with pytest.raises(ValueError, match="radius should be > 0"):
145
119
  FunctionalConnectivitySpheres(
146
- coords="DMNBuckner", radius=-0.1, cor_method="correlation"
120
+ coords="DMNBuckner", radius=-0.1, conn_method="correlation"
147
121
  )