junifer 0.0.6.dev422__py3-none-any.whl → 0.0.6.dev459__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.
@@ -5,26 +5,25 @@
5
5
  # Synchon Mandal <s.mandal@fz-juelich.de>
6
6
  # License: AGPL
7
7
 
8
- import io
9
- import shutil
10
- import tarfile
11
- import tempfile
12
- import zipfile
13
8
  from itertools import product
14
9
  from pathlib import Path
15
10
  from typing import TYPE_CHECKING, Any, Optional, Union
16
11
 
17
- import httpx
18
12
  import nibabel as nib
19
13
  import nilearn.image as nimg
20
14
  import numpy as np
21
15
  import pandas as pd
22
- from nilearn import datasets
16
+ from junifer_data import get
23
17
 
24
18
  from ...utils import logger, raise_error, warn_with_log
25
19
  from ...utils.singleton import Singleton
26
20
  from ..pipeline_data_registry_base import BasePipelineDataRegistry
27
- from ..utils import closest_resolution, get_native_warper
21
+ from ..utils import (
22
+ JUNIFER_DATA_VERSION,
23
+ closest_resolution,
24
+ get_dataset_path,
25
+ get_native_warper,
26
+ )
28
27
  from ._ants_parcellation_warper import ANTsParcellationWarper
29
28
  from ._fsl_parcellation_warper import FSLParcellationWarper
30
29
 
@@ -49,6 +48,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
49
48
 
50
49
  def __init__(self) -> None:
51
50
  """Initialize the class."""
51
+ super().__init__()
52
52
  # Each entry in registry is a dictionary that must contain at least
53
53
  # the following keys:
54
54
  # * 'family': the parcellation's family name (e.g., 'Schaefer', 'SUIT')
@@ -56,6 +56,8 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
56
56
  # and can also have optional key(s):
57
57
  # * 'valid_resolutions': a list of valid resolutions for the
58
58
  # parcellation (e.g., [1, 2])
59
+ # The built-in coordinates are files that are shipped with the
60
+ # junifer-data dataset.
59
61
  # Make built-in and external dictionaries for validation later
60
62
  self._builtin = {}
61
63
  self._external = {}
@@ -63,8 +65,14 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
63
65
  # Add SUIT
64
66
  self._builtin.update(
65
67
  {
66
- "SUITxSUIT": {"family": "SUIT", "space": "SUIT"},
67
- "SUITxMNI": {"family": "SUIT", "space": "MNI152NLin6Asym"},
68
+ "SUITxSUIT": {
69
+ "family": "SUIT",
70
+ "space": "SUIT",
71
+ },
72
+ "SUITxMNI": {
73
+ "family": "SUIT",
74
+ "space": "MNI152NLin6Asym",
75
+ },
68
76
  }
69
77
  )
70
78
  # Add Schaefer
@@ -72,7 +80,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
72
80
  self._builtin.update(
73
81
  {
74
82
  f"Schaefer{n_rois}x{t_net}": {
75
- "family": "Schaefer",
83
+ "family": "Schaefer2018",
76
84
  "n_rois": n_rois,
77
85
  "yeo_networks": t_net,
78
86
  "space": "MNI152NLin6Asym",
@@ -84,19 +92,19 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
84
92
  self._builtin.update(
85
93
  {
86
94
  f"TianxS{scale}x7TxMNI6thgeneration": {
87
- "family": "Tian",
95
+ "family": "Melbourne",
88
96
  "scale": scale,
89
97
  "magneticfield": "7T",
90
98
  "space": "MNI152NLin6Asym",
91
99
  },
92
100
  f"TianxS{scale}x3TxMNI6thgeneration": {
93
- "family": "Tian",
101
+ "family": "Melbourne",
94
102
  "scale": scale,
95
103
  "magneticfield": "3T",
96
104
  "space": "MNI152NLin6Asym",
97
105
  },
98
106
  f"TianxS{scale}x3TxMNInonlinear2009cAsym": {
99
- "family": "Tian",
107
+ "family": "Melbourne",
100
108
  "scale": scale,
101
109
  "magneticfield": "3T",
102
110
  "space": "MNI152NLin2009cAsym",
@@ -155,7 +163,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
155
163
  self._builtin.update(
156
164
  {
157
165
  f"Yan{n_rois}xYeo{yeo_network}": {
158
- "family": "Yan",
166
+ "family": "Yan2023",
159
167
  "n_rois": n_rois,
160
168
  "yeo_networks": yeo_network,
161
169
  "space": "MNI152NLin6Asym",
@@ -165,7 +173,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
165
173
  self._builtin.update(
166
174
  {
167
175
  f"Yan{n_rois}xKong17": {
168
- "family": "Yan",
176
+ "family": "Yan2023",
169
177
  "n_rois": n_rois,
170
178
  "kong_networks": 17,
171
179
  "space": "MNI152NLin6Asym",
@@ -184,8 +192,8 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
184
192
  }
185
193
  )
186
194
 
187
- # Set built-in to registry
188
- self._registry = self._builtin
195
+ # Update registry with built-in ones
196
+ self._registry.update(self._builtin)
189
197
 
190
198
  def register(
191
199
  self,
@@ -214,20 +222,21 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
214
222
  Raises
215
223
  ------
216
224
  ValueError
217
- If the parcellation ``name`` is already registered and
218
- ``overwrite=False`` or
219
- if the parcellation ``name`` is a built-in parcellation.
225
+ If the parcellation ``name`` is a built-in parcellation or
226
+ if the parcellation ``name`` is already registered and
227
+ ``overwrite=False``.
220
228
 
221
229
  """
222
230
  # Check for attempt of overwriting built-in parcellations
223
231
  if name in self._builtin:
232
+ raise_error(
233
+ f"Parcellation: {name} already registered as "
234
+ "built-in parcellation."
235
+ )
236
+ # Check for attempt of overwriting external parcellations
237
+ if name in self._external:
224
238
  if overwrite:
225
239
  logger.info(f"Overwriting parcellation: {name}")
226
- if self._registry[name]["family"] != "CustomUserParcellation":
227
- raise_error(
228
- f"Parcellation: {name} already registered as "
229
- "built-in parcellation."
230
- )
231
240
  else:
232
241
  raise_error(
233
242
  f"Parcellation: {name} already registered. Set "
@@ -236,6 +245,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
236
245
  # Convert str to Path
237
246
  if not isinstance(parcellation_path, Path):
238
247
  parcellation_path = Path(parcellation_path)
248
+ # Registration
239
249
  logger.info(f"Registering parcellation: {name}")
240
250
  # Add user parcellation info
241
251
  self._external[name] = {
@@ -271,24 +281,17 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
271
281
  self,
272
282
  name: str,
273
283
  target_space: str,
274
- parcellations_dir: Union[str, Path, None] = None,
275
284
  resolution: Optional[float] = None,
276
285
  path_only: bool = False,
277
286
  ) -> tuple[Optional["Nifti1Image"], list[str], Path, str]:
278
287
  """Load parcellation and labels.
279
288
 
280
- If it is a built-in parcellation and the file is not present in the
281
- ``parcellations_dir`` directory, it will be downloaded.
282
-
283
289
  Parameters
284
290
  ----------
285
291
  name : str
286
292
  The name of the parcellation.
287
293
  target_space : str
288
294
  The desired space of the parcellation.
289
- parcellations_dir : str or pathlib.Path, optional
290
- Path where the parcellations files are stored. The default location
291
- is "$HOME/junifer/data/parcellations" (default None).
292
295
  resolution : float, optional
293
296
  The desired resolution of the parcellation to load. If it is not
294
297
  available, the closest resolution will be loaded. Preferably, use a
@@ -312,6 +315,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
312
315
  ------
313
316
  ValueError
314
317
  If ``name`` is invalid or
318
+ if the parcellation family is invalid or
315
319
  if the parcellation values and labels
316
320
  don't have equal dimension or if the value range is invalid.
317
321
 
@@ -327,7 +331,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
327
331
  parcellation_definition = self._registry[name].copy()
328
332
  t_family = parcellation_definition.pop("family")
329
333
  # Remove space conditionally
330
- if t_family not in ["SUIT", "Tian"]:
334
+ if t_family not in ["SUIT", "Melbourne"]:
331
335
  space = parcellation_definition.pop("space")
332
336
  else:
333
337
  space = parcellation_definition["space"]
@@ -342,15 +346,57 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
342
346
 
343
347
  # Check if the parcellation family is custom or built-in
344
348
  if t_family == "CustomUserParcellation":
345
- parcellation_fname = Path(parcellation_definition["path"])
349
+ parcellation_fname = parcellation_definition["path"]
346
350
  parcellation_labels = parcellation_definition["labels"]
351
+ elif t_family in [
352
+ "Schaefer2018",
353
+ "SUIT",
354
+ "Melbourne",
355
+ "AICHA",
356
+ "Shen",
357
+ "Yan2023",
358
+ "Brainnetome",
359
+ ]:
360
+ # Load parcellation and labels
361
+ if t_family == "Schaefer2018":
362
+ parcellation_fname, parcellation_labels = _retrieve_schaefer(
363
+ resolution=resolution,
364
+ **parcellation_definition,
365
+ )
366
+ elif t_family == "SUIT":
367
+ parcellation_fname, parcellation_labels = _retrieve_suit(
368
+ resolution=resolution,
369
+ **parcellation_definition,
370
+ )
371
+ elif t_family == "Melbourne":
372
+ parcellation_fname, parcellation_labels = _retrieve_tian(
373
+ resolution=resolution,
374
+ **parcellation_definition,
375
+ )
376
+ elif t_family == "AICHA":
377
+ parcellation_fname, parcellation_labels = _retrieve_aicha(
378
+ resolution=resolution,
379
+ **parcellation_definition,
380
+ )
381
+ elif t_family == "Shen":
382
+ parcellation_fname, parcellation_labels = _retrieve_shen(
383
+ resolution=resolution,
384
+ **parcellation_definition,
385
+ )
386
+ elif t_family == "Yan2023":
387
+ parcellation_fname, parcellation_labels = _retrieve_yan(
388
+ resolution=resolution,
389
+ **parcellation_definition,
390
+ )
391
+ elif t_family == "Brainnetome":
392
+ parcellation_fname, parcellation_labels = (
393
+ _retrieve_brainnetome(
394
+ resolution=resolution,
395
+ **parcellation_definition,
396
+ )
397
+ )
347
398
  else:
348
- parcellation_fname, parcellation_labels = _retrieve_parcellation(
349
- family=t_family,
350
- parcellations_dir=parcellations_dir,
351
- resolution=resolution,
352
- **parcellation_definition,
353
- )
399
+ raise_error(f"Unknown parcellation family: {t_family}")
354
400
 
355
401
  # Load parcellation image and values
356
402
  logger.info(f"Loading parcellation: {parcellation_fname.absolute()!s}")
@@ -529,152 +575,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
529
575
  return resampled_parcellation_img, labels
530
576
 
531
577
 
532
- def _retrieve_parcellation(
533
- family: str,
534
- parcellations_dir: Union[str, Path, None] = None,
535
- resolution: Optional[float] = None,
536
- **kwargs,
537
- ) -> tuple[Path, list[str]]:
538
- """Retrieve a brain parcellation object from nilearn or online source.
539
-
540
- Only returns one parcellation per call. Call function multiple times for
541
- different parameter specifications. Only retrieves parcellation if it is
542
- not yet in parcellations_dir.
543
-
544
- Parameters
545
- ----------
546
- family : {"Schaefer", "SUIT", "Tian", "AICHA", "Shen", "Yan"}
547
- The name of the parcellation family.
548
- parcellations_dir : str or pathlib.Path, optional
549
- Path where the retrieved parcellations file are stored. The default
550
- location is "$HOME/junifer/data/parcellations" (default None).
551
- resolution : float, optional
552
- The desired resolution of the parcellation to load. If it is not
553
- available, the closest resolution will be loaded. Preferably, use a
554
- resolution higher than the desired one. By default, will load the
555
- highest one (default None).
556
- **kwargs
557
- Use to specify parcellation-specific keyword arguments found in the
558
- following section.
559
-
560
- Other Parameters
561
- ----------------
562
- * Schaefer :
563
- ``n_rois`` : {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}
564
- Granularity of parcellation to be used.
565
- ``yeo_network`` : {7, 17}, optional
566
- Number of Yeo networks to use (default 7).
567
- * Tian :
568
- ``scale`` : {1, 2, 3, 4}
569
- Scale of parcellation (defines granularity).
570
- ``space`` : {"MNI152NLin6Asym", "MNI152NLin2009cAsym"}, optional
571
- Space of parcellation (default "MNI152NLin6Asym"). (For more
572
- information see https://github.com/yetianmed/subcortex)
573
- ``magneticfield`` : {"3T", "7T"}, optional
574
- Magnetic field (default "3T").
575
- * SUIT :
576
- ``space`` : {"MNI152NLin6Asym", "SUIT"}, optional
577
- Space of parcellation (default "MNI"). (For more information
578
- see http://www.diedrichsenlab.org/imaging/suit.htm).
579
- * AICHA :
580
- ``version`` : {1, 2}, optional
581
- Version of parcellation (default 2).
582
- * Shen :
583
- ``year`` : {2013, 2015, 2019}, optional
584
- Year of the parcellation to use (default 2015).
585
- ``n_rois`` : int, optional
586
- Number of ROIs to use. Can be ``50, 100, or 150`` for
587
- ``year = 2013`` but is fixed at ``268`` for ``year = 2015`` and at
588
- ``368`` for ``year = 2019``.
589
- * Yan :
590
- ``n_rois`` : {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}
591
- Granularity of the parcellation to be used.
592
- ``yeo_networks`` : {7, 17}, optional
593
- Number of Yeo networks to use (default None).
594
- ``kong_networks`` : {17}, optional
595
- Number of Kong networks to use (default None).
596
- * Brainnetome :
597
- ``threshold`` : {0, 25, 50}
598
- Threshold for the probabilistic maps of subregion.
599
-
600
- Returns
601
- -------
602
- pathlib.Path
603
- File path to the parcellation image.
604
- list of str
605
- Parcellation labels.
606
-
607
- Raises
608
- ------
609
- ValueError
610
- If the parcellation's name is invalid.
611
-
612
- """
613
- if parcellations_dir is None:
614
- parcellations_dir = (
615
- Path().home() / "junifer" / "data" / "parcellations"
616
- )
617
- # Create default junifer data directory if not present
618
- parcellations_dir.mkdir(exist_ok=True, parents=True)
619
- # Convert str to Path
620
- elif not isinstance(parcellations_dir, Path):
621
- parcellations_dir = Path(parcellations_dir)
622
-
623
- logger.info(f"Fetching one of {family} parcellations.")
624
-
625
- # Retrieval details per family
626
- if family == "Schaefer":
627
- parcellation_fname, parcellation_labels = _retrieve_schaefer(
628
- parcellations_dir=parcellations_dir,
629
- resolution=resolution,
630
- **kwargs,
631
- )
632
- elif family == "SUIT":
633
- parcellation_fname, parcellation_labels = _retrieve_suit(
634
- parcellations_dir=parcellations_dir,
635
- resolution=resolution,
636
- **kwargs,
637
- )
638
- elif family == "Tian":
639
- parcellation_fname, parcellation_labels = _retrieve_tian(
640
- parcellations_dir=parcellations_dir,
641
- resolution=resolution,
642
- **kwargs,
643
- )
644
- elif family == "AICHA":
645
- parcellation_fname, parcellation_labels = _retrieve_aicha(
646
- parcellations_dir=parcellations_dir,
647
- resolution=resolution,
648
- **kwargs,
649
- )
650
- elif family == "Shen":
651
- parcellation_fname, parcellation_labels = _retrieve_shen(
652
- parcellations_dir=parcellations_dir,
653
- resolution=resolution,
654
- **kwargs,
655
- )
656
- elif family == "Yan":
657
- parcellation_fname, parcellation_labels = _retrieve_yan(
658
- parcellations_dir=parcellations_dir,
659
- resolution=resolution,
660
- **kwargs,
661
- )
662
- elif family == "Brainnetome":
663
- parcellation_fname, parcellation_labels = _retrieve_brainnetome(
664
- parcellations_dir=parcellations_dir,
665
- resolution=resolution,
666
- **kwargs,
667
- )
668
- else:
669
- raise_error(
670
- f"The provided parcellation name {family} cannot be retrieved."
671
- )
672
-
673
- return parcellation_fname, parcellation_labels
674
-
675
-
676
578
  def _retrieve_schaefer(
677
- parcellations_dir: Path,
678
579
  resolution: Optional[float] = None,
679
580
  n_rois: Optional[int] = None,
680
581
  yeo_networks: int = 7,
@@ -683,8 +584,6 @@ def _retrieve_schaefer(
683
584
 
684
585
  Parameters
685
586
  ----------
686
- parcellations_dir : pathlib.Path
687
- The path to the parcellation data directory.
688
587
  resolution : float, optional
689
588
  The desired resolution of the parcellation to load. If it is not
690
589
  available, the closest resolution will be loaded. Preferably, use a
@@ -706,8 +605,7 @@ def _retrieve_schaefer(
706
605
  Raises
707
606
  ------
708
607
  ValueError
709
- If invalid value is provided for ``n_rois`` or ``yeo_networks`` or if
710
- there is a problem fetching the parcellation.
608
+ If invalid value is provided for ``n_rois`` or ``yeo_networks``.
711
609
 
712
610
  """
713
611
  logger.info("Parcellation parameters:")
@@ -735,47 +633,33 @@ def _retrieve_schaefer(
735
633
  _valid_resolutions = [1, 2]
736
634
  resolution = closest_resolution(resolution, _valid_resolutions)
737
635
 
738
- # Define parcellation and label file names
739
- parcellation_fname = (
740
- parcellations_dir
741
- / "schaefer_2018"
742
- / (
743
- f"Schaefer2018_{n_rois}Parcels_{yeo_networks}Networks_order_"
744
- f"FSLMNI152_{resolution}mm.nii.gz"
745
- )
636
+ # Fetch file paths
637
+ path_prefix = Path("parcellations/Schaefer2018/Yeo2011")
638
+ parcellation_img_path = get(
639
+ file_path=path_prefix / f"Schaefer2018_{n_rois}Parcels_{yeo_networks}"
640
+ f"Networks_order_FSLMNI152_{resolution}mm.nii.gz",
641
+ dataset_path=get_dataset_path(),
642
+ tag=JUNIFER_DATA_VERSION,
746
643
  )
747
- parcellation_lname = (
748
- parcellations_dir
749
- / "schaefer_2018"
750
- / (f"Schaefer2018_{n_rois}Parcels_{yeo_networks}Networks_order.txt")
644
+ parcellation_label_path = get(
645
+ file_path=path_prefix
646
+ / f"Schaefer2018_{n_rois}Parcels_{yeo_networks}Networks_order.txt",
647
+ dataset_path=get_dataset_path(),
648
+ tag=JUNIFER_DATA_VERSION,
751
649
  )
752
650
 
753
- # Check existence of parcellation
754
- if not (parcellation_fname.exists() and parcellation_lname.exists()):
755
- logger.info(
756
- "At least one of the parcellation files are missing. "
757
- "Fetching using nilearn."
758
- )
759
- datasets.fetch_atlas_schaefer_2018(
760
- n_rois=n_rois,
761
- yeo_networks=yeo_networks,
762
- resolution_mm=resolution, # type: ignore we know it's 1 or 2
763
- data_dir=parcellations_dir.resolve(),
764
- )
765
-
766
651
  # Load labels
767
652
  labels = [
768
653
  "_".join(x.split("_")[1:])
769
- for x in pd.read_csv(parcellation_lname, sep="\t", header=None)
654
+ for x in pd.read_csv(parcellation_label_path, sep="\t", header=None)
770
655
  .iloc[:, 1]
771
656
  .to_list()
772
657
  ]
773
658
 
774
- return parcellation_fname, labels
659
+ return parcellation_img_path, labels
775
660
 
776
661
 
777
662
  def _retrieve_tian(
778
- parcellations_dir: Path,
779
663
  resolution: Optional[float] = None,
780
664
  scale: Optional[int] = None,
781
665
  space: str = "MNI152NLin6Asym",
@@ -785,8 +669,6 @@ def _retrieve_tian(
785
669
 
786
670
  Parameters
787
671
  ----------
788
- parcellations_dir : pathlib.Path
789
- The path to the parcellation data directory.
790
672
  resolution : float, optional
791
673
  The desired resolution of the parcellation to load. If it is not
792
674
  available, the closest resolution will be loaded. Preferably, use a
@@ -810,8 +692,6 @@ def _retrieve_tian(
810
692
 
811
693
  Raises
812
694
  ------
813
- RuntimeError
814
- If there is a problem fetching files.
815
695
  ValueError
816
696
  If invalid value is provided for ``scale`` or ``magneticfield`` or
817
697
  ``space``.
@@ -832,13 +712,10 @@ def _retrieve_tian(
832
712
  )
833
713
 
834
714
  # Check resolution
835
- _valid_resolutions = [] # avoid pylance error
836
715
  if magneticfield == "3T":
837
716
  _valid_spaces = ["MNI152NLin6Asym", "MNI152NLin2009cAsym"]
838
- if space == "MNI152NLin6Asym":
717
+ if space in _valid_spaces:
839
718
  _valid_resolutions = [1, 2]
840
- elif space == "MNI152NLin2009cAsym":
841
- _valid_resolutions = [2]
842
719
  else:
843
720
  raise_error(
844
721
  f"The parameter `space` ({space}) for 3T needs to be one of "
@@ -858,100 +735,71 @@ def _retrieve_tian(
858
735
  )
859
736
  resolution = closest_resolution(resolution, _valid_resolutions)
860
737
 
861
- # Define parcellation and label file names
738
+ # Fetch file paths
862
739
  if magneticfield == "3T":
863
- parcellation_fname_base_3T = (
864
- parcellations_dir / "Tian2020MSA_v1.1" / "3T" / "Subcortex-Only"
865
- )
866
- parcellation_lname = parcellation_fname_base_3T / (
867
- f"Tian_Subcortex_S{scale}_3T_label.txt"
740
+ parcellation_fname_base_3T = Path(
741
+ "parcellations/Melbourne/v1.4/3T/Subcortex-Only"
868
742
  )
869
743
  if space == "MNI152NLin6Asym":
870
- parcellation_fname = parcellation_fname_base_3T / (
871
- f"Tian_Subcortex_S{scale}_{magneticfield}.nii.gz"
872
- )
873
744
  if resolution == 1:
874
745
  parcellation_fname = (
875
746
  parcellation_fname_base_3T
876
747
  / f"Tian_Subcortex_S{scale}_{magneticfield}_1mm.nii.gz"
877
748
  )
749
+ else:
750
+ parcellation_fname = parcellation_fname_base_3T / (
751
+ f"Tian_Subcortex_S{scale}_{magneticfield}.nii.gz"
752
+ )
878
753
  elif space == "MNI152NLin2009cAsym":
879
754
  space = "2009cAsym"
880
- parcellation_fname = parcellation_fname_base_3T / (
881
- f"Tian_Subcortex_S{scale}_{magneticfield}_{space}.nii.gz"
882
- )
883
- elif magneticfield == "7T":
884
- parcellation_fname_base_7T = (
885
- parcellations_dir / "Tian2020MSA_v1.1" / "7T"
755
+ if resolution == 1:
756
+ parcellation_fname = parcellation_fname_base_3T / (
757
+ f"Tian_Subcortex_S{scale}_{magneticfield}_{space}_1mm.nii.gz"
758
+ )
759
+ else:
760
+ parcellation_fname = parcellation_fname_base_3T / (
761
+ f"Tian_Subcortex_S{scale}_{magneticfield}_{space}.nii.gz"
762
+ )
763
+
764
+ parcellation_img_path = get(
765
+ file_path=parcellation_fname,
766
+ dataset_path=get_dataset_path(),
767
+ tag=JUNIFER_DATA_VERSION,
886
768
  )
887
- parcellation_fname_base_7T.mkdir(exist_ok=True, parents=True)
888
- parcellation_fname = (
889
- parcellations_dir
890
- / "Tian2020MSA_v1.1"
891
- / f"{magneticfield}"
892
- / (f"Tian_Subcortex_S{scale}_{magneticfield}.nii.gz")
769
+ parcellation_label_path = get(
770
+ file_path=parcellation_fname_base_3T
771
+ / f"Tian_Subcortex_S{scale}_3T_label.txt",
772
+ dataset_path=get_dataset_path(),
773
+ tag=JUNIFER_DATA_VERSION,
774
+ )
775
+ # Load labels
776
+ labels = pd.read_csv(parcellation_label_path, sep=" ", header=None)[
777
+ 0
778
+ ].to_list()
779
+ elif magneticfield == "7T":
780
+ parcellation_img_path = get(
781
+ file_path=Path(
782
+ "parcellations/Melbourne/v1.4/7T/"
783
+ f"Tian_Subcortex_S{scale}_{magneticfield}.nii.gz"
784
+ ),
785
+ dataset_path=get_dataset_path(),
786
+ tag=JUNIFER_DATA_VERSION,
893
787
  )
894
788
  # define 7T labels (b/c currently no labels file available for 7T)
895
789
  scale7Trois = {1: 16, 2: 34, 3: 54, 4: 62}
896
790
  labels = [
897
791
  ("parcel_" + str(x)) for x in np.arange(1, scale7Trois[scale] + 1)
898
792
  ]
899
- parcellation_lname = parcellation_fname_base_7T / (
900
- f"Tian_Subcortex_S{scale}_7T_labelnumbering.txt"
901
- )
902
- with open(parcellation_lname, "w") as filehandle:
903
- for listitem in labels:
904
- filehandle.write(f"{listitem}\n")
905
793
  logger.info(
906
794
  "Currently there are no labels provided for the 7T Tian "
907
795
  "parcellation. A simple numbering scheme for distinction was "
908
796
  "therefore used."
909
797
  )
910
798
 
911
- # Check existence of parcellation
912
- if not (parcellation_fname.exists() and parcellation_lname.exists()):
913
- logger.info(
914
- "At least one of the parcellation files are missing, fetching."
915
- )
916
- # Set URL
917
- url = (
918
- "https://www.nitrc.org/frs/download.php/12012/Tian2020MSA_v1.1.zip"
919
- )
920
-
921
- logger.info(f"Downloading TIAN from {url}")
922
- # Store initial download in a tempdir
923
- with tempfile.TemporaryDirectory() as tmpdir:
924
- # Make HTTP request
925
- try:
926
- resp = httpx.get(url)
927
- resp.raise_for_status()
928
- except httpx.HTTPError as exc:
929
- raise_error(
930
- f"Error response {exc.response.status_code} while "
931
- f"requesting {exc.request.url!r}",
932
- klass=RuntimeError,
933
- )
934
- else:
935
- # Set tempfile for storing initial content and unzipping
936
- zip_fname = Path(tmpdir) / "Tian2020MSA_v1.1.zip"
937
- # Open tempfile and write content
938
- with open(zip_fname, "wb") as f:
939
- f.write(resp.content)
940
- # Unzip tempfile
941
- with zipfile.ZipFile(zip_fname, "r") as zip_ref:
942
- zip_ref.extractall(parcellations_dir.as_posix())
943
- # Clean after unzipping
944
- if (parcellations_dir / "__MACOSX").exists():
945
- shutil.rmtree((parcellations_dir / "__MACOSX").as_posix())
946
-
947
- # Load labels
948
- labels = pd.read_csv(parcellation_lname, sep=" ", header=None)[0].to_list()
949
-
950
- return parcellation_fname, labels
799
+ return parcellation_img_path, labels
951
800
 
952
801
 
953
802
  def _retrieve_suit(
954
- parcellations_dir: Path,
955
803
  resolution: Optional[float],
956
804
  space: str = "MNI152NLin6Asym",
957
805
  ) -> tuple[Path, list[str]]:
@@ -959,8 +807,6 @@ def _retrieve_suit(
959
807
 
960
808
  Parameters
961
809
  ----------
962
- parcellations_dir : pathlib.Path
963
- The path to the parcellation data directory.
964
810
  resolution : float, optional
965
811
  The desired resolution of the parcellation to load. If it is not
966
812
  available, the closest resolution will be loaded. Preferably, use a
@@ -980,8 +826,6 @@ def _retrieve_suit(
980
826
 
981
827
  Raises
982
828
  ------
983
- RuntimeError
984
- If there is a problem fetching files.
985
829
  ValueError
986
830
  If invalid value is provided for ``space``.
987
831
 
@@ -1006,78 +850,28 @@ def _retrieve_suit(
1006
850
  if space == "MNI152NLin6Asym":
1007
851
  space = "MNI"
1008
852
 
1009
- # Define parcellation and label file names
1010
- parcellation_fname = (
1011
- parcellations_dir / "SUIT" / (f"SUIT_{space}Space_{resolution}mm.nii")
853
+ # Fetch file paths
854
+ path_prefix = Path("parcellations/SUIT")
855
+ parcellation_img_path = get(
856
+ file_path=path_prefix / f"SUIT_{space}Space_{resolution}mm.nii",
857
+ dataset_path=get_dataset_path(),
858
+ tag=JUNIFER_DATA_VERSION,
1012
859
  )
1013
- parcellation_lname = (
1014
- parcellations_dir / "SUIT" / (f"SUIT_{space}Space_{resolution}mm.tsv")
860
+ parcellation_label_path = get(
861
+ file_path=path_prefix / f"SUIT_{space}Space_{resolution}mm.tsv",
862
+ dataset_path=get_dataset_path(),
863
+ tag=JUNIFER_DATA_VERSION,
1015
864
  )
1016
865
 
1017
- # Check existence of parcellation
1018
- if not (parcellation_fname.exists() and parcellation_lname.exists()):
1019
- logger.info(
1020
- "At least one of the parcellation files is missing, fetching."
1021
- )
1022
- # Create local directory if not present
1023
- parcellation_fname.parent.mkdir(exist_ok=True, parents=True)
1024
- # Set URL
1025
- url_basis = (
1026
- "https://github.com/DiedrichsenLab/cerebellar_atlases/raw"
1027
- "/master/Diedrichsen_2009"
1028
- )
1029
- if space == "MNI":
1030
- url = f"{url_basis}/atl-Anatom_space-MNI_dseg.nii"
1031
- else: # if not MNI, then SUIT
1032
- url = f"{url_basis}/atl-Anatom_space-SUIT_dseg.nii"
1033
- url_labels = f"{url_basis}/atl-Anatom.tsv"
1034
-
1035
- # Make HTTP requests
1036
- with httpx.Client(follow_redirects=True) as client:
1037
- # Download parcellation file
1038
- logger.info(f"Downloading SUIT parcellation from {url}")
1039
- try:
1040
- img_resp = client.get(url)
1041
- img_resp.raise_for_status()
1042
- except httpx.HTTPError as exc:
1043
- raise_error(
1044
- f"Error response {exc.response.status_code} while "
1045
- f"requesting {exc.request.url!r}",
1046
- klass=RuntimeError,
1047
- )
1048
- else:
1049
- with open(parcellation_fname, "wb") as f:
1050
- f.write(img_resp.content)
1051
- # Download label file
1052
- logger.info(f"Downloading SUIT labels from {url_labels}")
1053
- try:
1054
- label_resp = client.get(url_labels)
1055
- label_resp.raise_for_status()
1056
- except httpx.HTTPError as exc:
1057
- raise_error(
1058
- f"Error response {exc.response.status_code} while "
1059
- f"requesting {exc.request.url!r}",
1060
- klass=RuntimeError,
1061
- )
1062
- else:
1063
- # Load labels
1064
- labels = pd.read_csv(
1065
- io.StringIO(label_resp.content.decode("utf-8")),
1066
- sep="\t",
1067
- usecols=["name"],
1068
- )
1069
- labels.to_csv(parcellation_lname, sep="\t", index=False)
1070
-
1071
866
  # Load labels
1072
- labels = pd.read_csv(parcellation_lname, sep="\t", usecols=["name"])[
867
+ labels = pd.read_csv(parcellation_label_path, sep="\t", usecols=["name"])[
1073
868
  "name"
1074
869
  ].to_list()
1075
870
 
1076
- return parcellation_fname, labels
871
+ return parcellation_img_path, labels
1077
872
 
1078
873
 
1079
874
  def _retrieve_aicha(
1080
- parcellations_dir: Path,
1081
875
  resolution: Optional[float] = None,
1082
876
  version: int = 2,
1083
877
  ) -> tuple[Path, list[str]]:
@@ -1085,8 +879,6 @@ def _retrieve_aicha(
1085
879
 
1086
880
  Parameters
1087
881
  ----------
1088
- parcellations_dir : pathlib.Path
1089
- The path to the parcellation data directory.
1090
882
  resolution : float, optional
1091
883
  The desired resolution of the parcellation to load. If it is not
1092
884
  available, the closest resolution will be loaded. Preferably, use a
@@ -1105,8 +897,6 @@ def _retrieve_aicha(
1105
897
 
1106
898
  Raises
1107
899
  ------
1108
- RuntimeError
1109
- If there is a problem fetching files.
1110
900
  ValueError
1111
901
  If invalid value is provided for ``version``.
1112
902
 
@@ -1143,99 +933,39 @@ def _retrieve_aicha(
1143
933
  _valid_resolutions = [1]
1144
934
  resolution = closest_resolution(resolution, _valid_resolutions)
1145
935
 
1146
- # Define parcellation and label file names
1147
- parcellation_fname = (
1148
- parcellations_dir / f"AICHA_v{version}" / "AICHA" / "AICHA.nii"
936
+ # Fetch file paths
937
+ path_prefix = Path(f"parcellations/AICHA/v{version}")
938
+ parcellation_img_path = get(
939
+ file_path=path_prefix / "AICHA.nii",
940
+ dataset_path=get_dataset_path(),
941
+ tag=JUNIFER_DATA_VERSION,
1149
942
  )
1150
- parcellation_lname = Path()
943
+ # Conditional label file fetch
1151
944
  if version == 1:
1152
- parcellation_lname = (
1153
- parcellations_dir
1154
- / f"AICHA_v{version}"
1155
- / "AICHA"
1156
- / "AICHA_vol1.txt"
945
+ parcellation_label_path = get(
946
+ file_path=path_prefix / "AICHA_vol1.txt",
947
+ dataset_path=get_dataset_path(),
948
+ tag=JUNIFER_DATA_VERSION,
1157
949
  )
1158
950
  elif version == 2:
1159
- parcellation_lname = (
1160
- parcellations_dir
1161
- / f"AICHA_v{version}"
1162
- / "AICHA"
1163
- / "AICHA_vol3.txt"
951
+ parcellation_label_path = get(
952
+ file_path=path_prefix / "AICHA_vol3.txt",
953
+ dataset_path=get_dataset_path(),
954
+ tag=JUNIFER_DATA_VERSION,
1164
955
  )
1165
956
 
1166
- # Check existence of parcellation
1167
- if not (parcellation_fname.exists() and parcellation_lname.exists()):
1168
- logger.info(
1169
- "At least one of the parcellation files are missing, fetching."
1170
- )
1171
- # Set file name on server according to version
1172
- server_filename = ""
1173
- if version == 1:
1174
- server_filename = "aicha_v1.zip"
1175
- elif version == 2:
1176
- server_filename = "AICHA_v2.tar.zip"
1177
- # Set URL
1178
- url = f"http://www.gin.cnrs.fr/wp-content/uploads/{server_filename}"
1179
-
1180
- logger.info(f"Downloading AICHA v{version} from {url}")
1181
- # Store initial download in a tempdir
1182
- with tempfile.TemporaryDirectory() as tmpdir:
1183
- # Make HTTP request
1184
- try:
1185
- resp = httpx.get(url, follow_redirects=True)
1186
- resp.raise_for_status()
1187
- except httpx.HTTPError as exc:
1188
- raise_error(
1189
- f"Error response {exc.response.status_code} while "
1190
- f"requesting {exc.request.url!r}",
1191
- klass=RuntimeError,
1192
- )
1193
- else:
1194
- # Set tempfile for storing initial content and unzipping
1195
- parcellation_zip_path = Path(tmpdir) / server_filename
1196
- # Open tempfile and write content
1197
- with open(parcellation_zip_path, "wb") as f:
1198
- f.write(resp.content)
1199
- # Unzip tempfile
1200
- with zipfile.ZipFile(parcellation_zip_path, "r") as zip_ref:
1201
- if version == 1:
1202
- zip_ref.extractall(
1203
- (parcellations_dir / "AICHA_v1").as_posix()
1204
- )
1205
- elif version == 2:
1206
- zip_ref.extractall(Path(tmpdir).as_posix())
1207
- # Extract tarfile for v2
1208
- with tarfile.TarFile(
1209
- Path(tmpdir) / "aicha_v2.tar", "r"
1210
- ) as tar_ref:
1211
- tar_ref.extractall(
1212
- (parcellations_dir / "AICHA_v2").as_posix()
1213
- )
1214
- # Cleanup after unzipping
1215
- if (
1216
- parcellations_dir / f"AICHA_v{version}" / "__MACOSX"
1217
- ).exists():
1218
- shutil.rmtree(
1219
- (
1220
- parcellations_dir
1221
- / f"AICHA_v{version}"
1222
- / "__MACOSX"
1223
- ).as_posix()
1224
- )
1225
-
1226
957
  # Load labels
1227
958
  labels = pd.read_csv(
1228
- parcellation_lname,
959
+ parcellation_label_path,
1229
960
  sep="\t",
1230
961
  header=None,
1231
- skiprows=[0], # type: ignore
962
+ skiprows=[0],
1232
963
  )[0].to_list()
1233
964
 
1234
- return parcellation_fname, labels
965
+ return parcellation_img_path, labels
1235
966
 
1236
967
 
1237
- def _retrieve_shen( # noqa: C901
1238
- parcellations_dir: Path,
968
+ def _retrieve_shen(
1239
969
  resolution: Optional[float] = None,
1240
970
  year: int = 2015,
1241
971
  n_rois: int = 268,
@@ -1244,8 +974,6 @@ def _retrieve_shen( # noqa: C901
1244
974
 
1245
975
  Parameters
1246
976
  ----------
1247
- parcellations_dir : pathlib.Path
1248
- The path to the parcellation data directory.
1249
977
  resolution : float, optional
1250
978
  The desired resolution of the parcellation to load. If it is not
1251
979
  available, the closest resolution will be loaded. Preferably, use a
@@ -1269,8 +997,6 @@ def _retrieve_shen( # noqa: C901
1269
997
 
1270
998
  Raises
1271
999
  ------
1272
- RuntimeError
1273
- If there is a problem fetching files.
1274
1000
  ValueError
1275
1001
  If invalid value or combination is provided for ``year`` and
1276
1002
  ``n_rois``.
@@ -1323,123 +1049,49 @@ def _retrieve_shen( # noqa: C901
1323
1049
  f"`year = {year}` is invalid"
1324
1050
  )
1325
1051
 
1326
- # Define parcellation and label file names
1052
+ # Fetch file paths based on year
1053
+ path_prefix = Path(f"parcellations/Shen/{year}")
1327
1054
  if year == 2013:
1328
- parcellation_fname = (
1329
- parcellations_dir
1330
- / "Shen_2013"
1331
- / "shenetal_neuroimage2013"
1332
- / f"fconn_atlas_{n_rois}_{resolution}mm.nii"
1055
+ parcellation_img_path = get(
1056
+ file_path=path_prefix / f"fconn_atlas_{n_rois}_{resolution}mm.nii",
1057
+ dataset_path=get_dataset_path(),
1058
+ tag=JUNIFER_DATA_VERSION,
1333
1059
  )
1334
- parcellation_lname = (
1335
- parcellations_dir
1336
- / "Shen_2013"
1337
- / "shenetal_neuroimage2013"
1338
- / f"Group_seg{n_rois}_BAindexing_setA.txt"
1339
- )
1340
- elif year == 2015:
1341
- parcellation_fname = (
1342
- parcellations_dir
1343
- / "Shen_2015"
1344
- / f"shen_{resolution}mm_268_parcellation.nii.gz"
1060
+ parcellation_label_path = get(
1061
+ file_path=path_prefix / f"Group_seg{n_rois}_BAindexing_setA.txt",
1062
+ dataset_path=get_dataset_path(),
1063
+ tag=JUNIFER_DATA_VERSION,
1345
1064
  )
1346
- elif year == 2019:
1347
- parcellation_fname = (
1348
- parcellations_dir
1349
- / "Shen_2019"
1350
- / "Shen_1mm_368_parcellation.nii.gz"
1351
- )
1352
-
1353
- # Check existence of parcellation
1354
- if not parcellation_fname.exists():
1355
- logger.info(
1356
- "At least one of the parcellation files are missing, fetching."
1357
- )
1358
-
1359
- # Set URL based on year
1360
- url = ""
1361
- if year == 2013:
1362
- url = "https://www.nitrc.org/frs/download.php/5785/shenetal_neuroimage2013_funcatlas.zip"
1363
- elif year == 2015:
1364
- # Set URL based on resolution
1365
- if resolution == 1:
1366
- url = "https://www.nitrc.org/frs/download.php/7976/shen_1mm_268_parcellation.nii.gz"
1367
- elif resolution == 2:
1368
- url = "https://www.nitrc.org/frs/download.php/7977/shen_2mm_268_parcellation.nii.gz"
1369
- elif year == 2019:
1370
- url = "https://www.nitrc.org/frs/download.php/11629/shen_368.zip"
1371
-
1372
- logger.info(f"Downloading Shen {year} from {url}")
1373
- # Store initial download in a tempdir
1374
- with tempfile.TemporaryDirectory() as tmpdir:
1375
- # Make HTTP request
1376
- try:
1377
- resp = httpx.get(url)
1378
- resp.raise_for_status()
1379
- except httpx.HTTPError as exc:
1380
- raise_error(
1381
- f"Error response {exc.response.status_code} while "
1382
- f"requesting {exc.request.url!r}",
1383
- klass=RuntimeError,
1384
- )
1385
- else:
1386
- if year in (2013, 2019):
1387
- parcellation_zip_path = Path(tmpdir) / f"Shen{year}.zip"
1388
- # Open tempfile and write content
1389
- with open(parcellation_zip_path, "wb") as f:
1390
- f.write(resp.content)
1391
- # Unzip tempfile
1392
- with zipfile.ZipFile(
1393
- parcellation_zip_path, "r"
1394
- ) as zip_ref:
1395
- zip_ref.extractall(
1396
- (parcellations_dir / f"Shen_{year}").as_posix()
1397
- )
1398
- # Cleanup after unzipping
1399
- if (
1400
- parcellations_dir / f"Shen_{year}" / "__MACOSX"
1401
- ).exists():
1402
- shutil.rmtree(
1403
- (
1404
- parcellations_dir / f"Shen_{year}" / "__MACOSX"
1405
- ).as_posix()
1406
- )
1407
- elif year == 2015:
1408
- img_dir_path = parcellations_dir / "Shen_2015"
1409
- # Create local directory if not present
1410
- img_dir_path.mkdir(parents=True, exist_ok=True)
1411
- img_path = (
1412
- img_dir_path
1413
- / f"shen_{resolution}mm_268_parcellation.nii.gz"
1414
- )
1415
- # Create local file if not present
1416
- img_path.touch(exist_ok=True)
1417
- # Open tempfile and write content
1418
- with open(img_path, "wb") as f:
1419
- f.write(resp.content)
1420
-
1421
- # Load labels based on year
1422
- if year == 2013:
1423
1065
  labels = (
1424
1066
  pd.read_csv(
1425
- parcellation_lname, # type: ignore
1426
- sep=",", # type: ignore
1427
- header=None, # type: ignore
1428
- skiprows=[0], # type: ignore
1067
+ parcellation_label_path,
1068
+ sep=",",
1069
+ header=None,
1070
+ skiprows=[0],
1429
1071
  )[1]
1430
1072
  .map(lambda x: x.strip()) # fix formatting
1431
1073
  .to_list()
1432
1074
  )
1433
1075
  elif year == 2015:
1076
+ parcellation_img_path = get(
1077
+ file_path=path_prefix
1078
+ / f"shen_{resolution}mm_268_parcellation.nii.gz",
1079
+ dataset_path=get_dataset_path(),
1080
+ tag=JUNIFER_DATA_VERSION,
1081
+ )
1434
1082
  labels = list(range(1, 269))
1435
1083
  elif year == 2019:
1084
+ parcellation_img_path = get(
1085
+ file_path=path_prefix / "Shen_1mm_368_parcellation.nii.gz",
1086
+ dataset_path=get_dataset_path(),
1087
+ tag=JUNIFER_DATA_VERSION,
1088
+ )
1436
1089
  labels = list(range(1, 369))
1437
1090
 
1438
- return parcellation_fname, labels
1091
+ return parcellation_img_path, labels
1439
1092
 
1440
1093
 
1441
1094
  def _retrieve_yan(
1442
- parcellations_dir: Path,
1443
1095
  resolution: Optional[float] = None,
1444
1096
  n_rois: Optional[int] = None,
1445
1097
  yeo_networks: Optional[int] = None,
@@ -1449,8 +1101,6 @@ def _retrieve_yan(
1449
1101
 
1450
1102
  Parameters
1451
1103
  ----------
1452
- parcellations_dir : pathlib.Path
1453
- The path to the parcellation data directory.
1454
1104
  resolution : float, optional
1455
1105
  The desired resolution of the parcellation to load. If it is not
1456
1106
  available, the closest resolution will be loaded. Preferably, use a
@@ -1473,8 +1123,6 @@ def _retrieve_yan(
1473
1123
 
1474
1124
  Raises
1475
1125
  ------
1476
- RuntimeError
1477
- If there is a problem fetching files.
1478
1126
  ValueError
1479
1127
  If invalid value is provided for ``n_rois``, ``yeo_networks`` or
1480
1128
  ``kong_networks``.
@@ -1507,8 +1155,8 @@ def _retrieve_yan(
1507
1155
  f"following: {_valid_n_rois}"
1508
1156
  )
1509
1157
 
1510
- parcellation_fname = Path()
1511
- parcellation_lname = Path()
1158
+ # Fetch file paths based on networks
1159
+ pre_path_prefix = Path("parcellations/Yan2023")
1512
1160
  if yeo_networks:
1513
1161
  # Check yeo_networks value
1514
1162
  _valid_yeo_networks = [7, 17]
@@ -1517,19 +1165,22 @@ def _retrieve_yan(
1517
1165
  f"The parameter `yeo_networks` ({yeo_networks}) needs to be "
1518
1166
  f"one of the following: {_valid_yeo_networks}"
1519
1167
  )
1520
- # Define image and label file according to network
1521
- parcellation_fname = (
1522
- parcellations_dir
1523
- / "Yan_2023"
1168
+
1169
+ path_prefix = pre_path_prefix / "Yeo2011"
1170
+ parcellation_img_path = get(
1171
+ file_path=path_prefix
1524
1172
  / (
1525
1173
  f"{n_rois}Parcels_Yeo2011_{yeo_networks}Networks_FSLMNI152_"
1526
1174
  f"{resolution}mm.nii.gz"
1527
- )
1175
+ ),
1176
+ dataset_path=get_dataset_path(),
1177
+ tag=JUNIFER_DATA_VERSION,
1528
1178
  )
1529
- parcellation_lname = (
1530
- parcellations_dir
1531
- / "Yan_2023"
1532
- / f"{n_rois}Parcels_Yeo2011_{yeo_networks}Networks_LUT.txt"
1179
+ parcellation_label_path = get(
1180
+ file_path=path_prefix
1181
+ / f"{n_rois}Parcels_Yeo2011_{yeo_networks}Networks_LUT.txt",
1182
+ dataset_path=get_dataset_path(),
1183
+ tag=JUNIFER_DATA_VERSION,
1533
1184
  )
1534
1185
  elif kong_networks:
1535
1186
  # Check kong_networks value
@@ -1539,106 +1190,33 @@ def _retrieve_yan(
1539
1190
  f"The parameter `kong_networks` ({kong_networks}) needs to be "
1540
1191
  f"one of the following: {_valid_kong_networks}"
1541
1192
  )
1542
- # Define image and label file according to network
1543
- parcellation_fname = (
1544
- parcellations_dir
1545
- / "Yan_2023"
1193
+
1194
+ path_prefix = pre_path_prefix / "Kong2022"
1195
+ parcellation_img_path = get(
1196
+ file_path=path_prefix
1546
1197
  / (
1547
1198
  f"{n_rois}Parcels_Kong2022_{kong_networks}Networks_FSLMNI152_"
1548
1199
  f"{resolution}mm.nii.gz"
1549
- )
1550
- )
1551
- parcellation_lname = (
1552
- parcellations_dir
1553
- / "Yan_2023"
1554
- / f"{n_rois}Parcels_Kong2022_{kong_networks}Networks_LUT.txt"
1200
+ ),
1201
+ dataset_path=get_dataset_path(),
1202
+ tag=JUNIFER_DATA_VERSION,
1555
1203
  )
1556
-
1557
- # Check for existence of parcellation:
1558
- if not parcellation_fname.exists() and not parcellation_lname.exists():
1559
- logger.info(
1560
- "At least one of the parcellation files are missing, fetching."
1204
+ parcellation_label_path = get(
1205
+ file_path=path_prefix
1206
+ / f"{n_rois}Parcels_Kong2022_{kong_networks}Networks_LUT.txt",
1207
+ dataset_path=get_dataset_path(),
1208
+ tag=JUNIFER_DATA_VERSION,
1561
1209
  )
1562
1210
 
1563
- # Set URL based on network
1564
- img_url = ""
1565
- label_url = ""
1566
- if yeo_networks:
1567
- img_url = (
1568
- "https://raw.githubusercontent.com/ThomasYeoLab/CBIG/"
1569
- "master/stable_projects/brain_parcellation/Yan2023_homotopic/"
1570
- f"parcellations/MNI/yeo{yeo_networks}/{n_rois}Parcels_Yeo2011"
1571
- f"_{yeo_networks}Networks_FSLMNI152_{resolution}mm.nii.gz"
1572
- )
1573
- label_url = (
1574
- "https://raw.githubusercontent.com/ThomasYeoLab/CBIG/"
1575
- "master/stable_projects/brain_parcellation/Yan2023_homotopic/"
1576
- f"parcellations/MNI/yeo{yeo_networks}/freeview_lut/{n_rois}"
1577
- f"Parcels_Yeo2011_{yeo_networks}Networks_LUT.txt"
1578
- )
1579
- elif kong_networks:
1580
- img_url = (
1581
- "https://raw.githubusercontent.com/ThomasYeoLab/CBIG/"
1582
- "master/stable_projects/brain_parcellation/Yan2023_homotopic/"
1583
- f"parcellations/MNI/kong17/{n_rois}Parcels_Kong2022"
1584
- f"_17Networks_FSLMNI152_{resolution}mm.nii.gz"
1585
- )
1586
- label_url = (
1587
- "https://raw.githubusercontent.com/ThomasYeoLab/CBIG/"
1588
- "master/stable_projects/brain_parcellation/Yan2023_homotopic/"
1589
- f"parcellations/MNI/kong17/freeview_lut/{n_rois}Parcels_"
1590
- "Kong2022_17Networks_LUT.txt"
1591
- )
1592
-
1593
- # Make HTTP requests
1594
- with httpx.Client() as client:
1595
- # Download parcellation file
1596
- logger.info(f"Downloading Yan 2023 parcellation from {img_url}")
1597
- try:
1598
- img_resp = client.get(img_url)
1599
- img_resp.raise_for_status()
1600
- except httpx.HTTPError as exc:
1601
- raise_error(
1602
- f"Error response {exc.response.status_code} while "
1603
- f"requesting {exc.request.url!r}",
1604
- klass=RuntimeError,
1605
- )
1606
- else:
1607
- parcellation_img_path = Path(parcellation_fname)
1608
- # Create local directory if not present
1609
- parcellation_img_path.parent.mkdir(parents=True, exist_ok=True)
1610
- # Create local file if not present
1611
- parcellation_img_path.touch(exist_ok=True)
1612
- # Open file and write content
1613
- with open(parcellation_img_path, "wb") as f:
1614
- f.write(img_resp.content)
1615
- # Download label file
1616
- logger.info(f"Downloading Yan 2023 labels from {label_url}")
1617
- try:
1618
- label_resp = client.get(label_url)
1619
- label_resp.raise_for_status()
1620
- except httpx.HTTPError as exc:
1621
- raise_error(
1622
- f"Error response {exc.response.status_code} while "
1623
- f"requesting {exc.request.url!r}",
1624
- klass=RuntimeError,
1625
- )
1626
- else:
1627
- parcellation_labels_path = Path(parcellation_lname)
1628
- # Create local file if not present
1629
- parcellation_labels_path.touch(exist_ok=True)
1630
- # Open file and write content
1631
- with open(parcellation_labels_path, "wb") as f:
1632
- f.write(label_resp.content)
1633
-
1634
1211
  # Load label file
1635
- labels = pd.read_csv(parcellation_lname, sep=" ", header=None)[1].to_list()
1212
+ labels = pd.read_csv(parcellation_label_path, sep=" ", header=None)[
1213
+ 1
1214
+ ].to_list()
1636
1215
 
1637
- return parcellation_fname, labels
1216
+ return parcellation_img_path, labels
1638
1217
 
1639
1218
 
1640
1219
  def _retrieve_brainnetome(
1641
- parcellations_dir: Path,
1642
1220
  resolution: Optional[float] = None,
1643
1221
  threshold: Optional[int] = None,
1644
1222
  ) -> tuple[Path, list[str]]:
@@ -1646,8 +1224,6 @@ def _retrieve_brainnetome(
1646
1224
 
1647
1225
  Parameters
1648
1226
  ----------
1649
- parcellations_dir : pathlib.Path
1650
- The path to the parcellation data directory.
1651
1227
  resolution : {1.0, 1.25, 2.0}, optional
1652
1228
  The desired resolution of the parcellation to load. If it is not
1653
1229
  available, the closest resolution will be loaded. Preferably, use a
@@ -1666,8 +1242,6 @@ def _retrieve_brainnetome(
1666
1242
 
1667
1243
  Raises
1668
1244
  ------
1669
- RuntimeError
1670
- If there is a problem fetching files.
1671
1245
  ValueError
1672
1246
  If invalid value is provided for ``threshold``.
1673
1247
 
@@ -1691,36 +1265,16 @@ def _retrieve_brainnetome(
1691
1265
  if resolution in [1.0, 2.0]:
1692
1266
  resolution = int(resolution)
1693
1267
 
1694
- parcellation_fname = (
1695
- parcellations_dir
1696
- / "BNA246"
1697
- / f"BNA-maxprob-thr{threshold}-{resolution}mm.nii.gz"
1268
+ # Fetch file path
1269
+ parcellation_img_path = get(
1270
+ file_path=Path(
1271
+ "parcellations/Brainnetome/"
1272
+ f"BNA-maxprob-thr{threshold}-{resolution}mm.nii.gz"
1273
+ ),
1274
+ dataset_path=get_dataset_path(),
1275
+ tag=JUNIFER_DATA_VERSION,
1698
1276
  )
1699
1277
 
1700
- # Check for existence of parcellation
1701
- if not parcellation_fname.exists():
1702
- # Set URL
1703
- url = f"http://neurovault.org/media/images/1625/BNA-maxprob-thr{threshold}-{resolution}mm.nii.gz"
1704
-
1705
- logger.info(f"Downloading Brainnetome from {url}")
1706
- # Make HTTP request
1707
- try:
1708
- resp = httpx.get(url, follow_redirects=True)
1709
- resp.raise_for_status()
1710
- except httpx.HTTPError as exc:
1711
- raise_error(
1712
- f"Error response {exc.response.status_code} while "
1713
- f"requesting {exc.request.url!r}",
1714
- klass=RuntimeError,
1715
- )
1716
- else:
1717
- # Create local directory if not present
1718
- parcellation_fname.parent.mkdir(parents=True, exist_ok=True)
1719
- # Create file if not present
1720
- parcellation_fname.touch(exist_ok=True)
1721
- # Open file and write bytes
1722
- parcellation_fname.write_bytes(resp.content)
1723
-
1724
1278
  # Load labels
1725
1279
  labels = (
1726
1280
  sorted([f"SFG_L(R)_7_{i}" for i in range(1, 8)] * 2)
@@ -1750,7 +1304,7 @@ def _retrieve_brainnetome(
1750
1304
  + sorted([f"Tha_L(R)_8_{i}" for i in range(1, 9)] * 2)
1751
1305
  )
1752
1306
 
1753
- return parcellation_fname, labels
1307
+ return parcellation_img_path, labels
1754
1308
 
1755
1309
 
1756
1310
  def merge_parcellations(