clabtoolkit 0.4.2__tar.gz → 0.4.3__tar.gz
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.
- clabtoolkit-0.4.3/HISTORY.rst +63 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/PKG-INFO +10 -1
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/README.rst +5 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/__init__.py +1 -1
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/bidstools.py +105 -18
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/colorstools.py +21 -7
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/config/config.json +1 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/connectivitytools.py +489 -194
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/dicomtools.py +1 -1
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/dwitools.py +297 -16
- clabtoolkit-0.4.3/clabtoolkit/dwitools_utils.py +107 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/freesurfertools.py +1037 -440
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/imagetools.py +325 -79
- clabtoolkit-0.4.3/clabtoolkit/imagetools_utils.py +81 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/misctools.py +71 -2
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/morphometrytools.py +317 -35
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/networktools.py +78 -214
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/parcellationtools.py +981 -17
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/plottools.py +83 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/surfacetools.py +5 -7
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/tracttools.py +21 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/visualization_utils.py +11 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/visualizationtools.py +535 -1
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit.egg-info/PKG-INFO +10 -1
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit.egg-info/SOURCES.txt +11 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit.egg-info/requires.txt +4 -0
- clabtoolkit-0.4.3/docs/source/_static/clabtoolkit_ecosystem.png +0 -0
- clabtoolkit-0.4.3/docs/source/_static/clabtoolkit_favicon.png +0 -0
- clabtoolkit-0.4.3/docs/source/_static/clabtoolkit_logo.png +0 -0
- clabtoolkit-0.4.3/docs/source/_static/clabtoolkit_logo_notext.png +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/conf.py +3 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/dicomtools.rst +12 -38
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/pyproject.toml +5 -1
- clabtoolkit-0.4.3/usage_examples/VisClasses4Paper.ipynb +1011 -0
- clabtoolkit-0.4.3/usage_examples/clabtoolkit-OHBM2026-final.ipynb +2069 -0
- clabtoolkit-0.4.3/usage_examples/clabtoolkit_examples.ipynb +1358 -0
- clabtoolkit-0.4.3/usage_examples/examples-bidstools-methods.ipynb +1366 -0
- clabtoolkit-0.4.3/usage_examples/examples-freesurfertools-methods.ipynb +2595 -0
- clabtoolkit-0.4.3/usage_examples/examples-parcellationtools-methods.ipynb +2351 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/usage_examples/examples-surfacetools-methods.ipynb +44 -6
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/usage_examples/examples-visualizationtools-methods.ipynb +3 -5
- clabtoolkit-0.4.2/HISTORY.rst +0 -35
- clabtoolkit-0.4.2/usage_examples/examples-parcellationtools-methods.ipynb +0 -1808
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/AUTHORS.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/CONTRIBUTING.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/LICENSE +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/MANIFEST.in +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/build_visualization_layout.py +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/config/bids.json +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/config/lobes.json +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/config/stats_mapping.json +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/config/viz_views.json +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/config/viz_views_test.json +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/connectome.py +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/misctools_utils.py +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/old_dwitool.py +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/pipelinetools.py +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/pointstools.py +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/qcqatools.py +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit/segmentationtools.py +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit.egg-info/dependency_links.txt +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/clabtoolkit.egg-info/top_level.txt +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/Makefile +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/clabtoolkit.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/make.bat +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/modules.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/index.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/bidstools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/connectivitytools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/dwitools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/freesurfertools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/imagetools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/misctools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/morphometrytools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/networktools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/parcellationtools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/pipelinetools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/plottools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/qcqatools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/segmentationtools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/surfacetools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/docs/source/modules/visualizationtools.rst +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/setup.cfg +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/usage_examples/examples-colorstools-methods.ipynb +0 -0
- {clabtoolkit-0.4.2 → clabtoolkit-0.4.3}/usage_examples/examples-misctools-methods.ipynb +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
=======
|
|
2
|
+
History
|
|
3
|
+
=======
|
|
4
|
+
|
|
5
|
+
0.4.3 (2026-06-10)
|
|
6
|
+
------------------
|
|
7
|
+
|
|
8
|
+
* Added compute_fc_matrix method to Parcellation class
|
|
9
|
+
* Added get_info method to Connectome and Parcellation classes
|
|
10
|
+
* Added create_carpet_plot function in visualizationtools
|
|
11
|
+
* Added compute_scalar_maps_from_tensor in diffusiontools
|
|
12
|
+
* Added RegionTimeSeries object and integration across the package
|
|
13
|
+
* Added method to generate connectomes
|
|
14
|
+
* Added connected components computation from edge arrays
|
|
15
|
+
* Added region lookup methods in AnnotParcellation
|
|
16
|
+
* Added comprehensive get_info() for AnnotParcellation
|
|
17
|
+
* Added method to binarize and dilate 3D arrays by millimeter distance
|
|
18
|
+
* Added support for pathlib.Path objects as inputs
|
|
19
|
+
* Added option to make TSV file compatible with templateflow
|
|
20
|
+
* Added new colors to the bcolors class
|
|
21
|
+
* Added bundle id map and updated names
|
|
22
|
+
* Added notebook with examples for OHBM 2026
|
|
23
|
+
* Added new ecosystem figure and logo
|
|
24
|
+
* Refactored stats_from_vector for edge cases with nonzeros_only=True
|
|
25
|
+
* Refactored AnnotParcellation gii2annot/annot2gii to use nibabel instead of FreeSurfer mris_convert
|
|
26
|
+
* Extended merge_to_4d method to deal with DWI data
|
|
27
|
+
* Fixed strict entity and suffix validation in is_bids_filename
|
|
28
|
+
* Fixed pyvista notebook crash from threaded display
|
|
29
|
+
* Fixed color table names bug
|
|
30
|
+
* Fixed dimensions field bugs ("dims" vs "dim")
|
|
31
|
+
* Multiple bug fixes, dependency updates, and documentation improvements
|
|
32
|
+
|
|
33
|
+
0.4.1 (2026-02-19)
|
|
34
|
+
------------------
|
|
35
|
+
|
|
36
|
+
* Major refactoring of Parcellation class with improved attribute handling
|
|
37
|
+
* Enhanced color table loading and export with multiple format support
|
|
38
|
+
* Added region adjacency computation to Parcellation
|
|
39
|
+
* Improved BIDS file entity extraction with parallel processing
|
|
40
|
+
* Added DiffusionScheme class for gradient visualization
|
|
41
|
+
* Enhanced Connectome class initialization and metrics computation
|
|
42
|
+
* Added derivatives inventory functionality
|
|
43
|
+
* Improved surface tools with PyVista fallback support
|
|
44
|
+
* Added usage examples notebooks
|
|
45
|
+
* Multiple bug fixes in mask handling, color processing, and data type conversion
|
|
46
|
+
* Improved documentation and code organization
|
|
47
|
+
|
|
48
|
+
0.3.4 (2025-01-09)
|
|
49
|
+
------------------
|
|
50
|
+
|
|
51
|
+
* Enhanced documentation and ReadTheDocs configuration
|
|
52
|
+
* Moved region growing method to imagetools module
|
|
53
|
+
* Improved Sphinx autodoc configuration for better API documentation
|
|
54
|
+
* Multiple improvements to surface visualization and plotting functionality
|
|
55
|
+
* Added new morphometry and connectivity analysis tools
|
|
56
|
+
* Enhanced BIDS dataset handling and entity management
|
|
57
|
+
* Improved surface mesh operations and color mapping
|
|
58
|
+
* Added network analysis tools and visualization capabilities
|
|
59
|
+
|
|
60
|
+
0.3.1 (2025-05-22)
|
|
61
|
+
------------------
|
|
62
|
+
|
|
63
|
+
* Fourth release on PyPI.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clabtoolkit
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: A comprehensive toolkit for neuroimaging data processing and analysis
|
|
5
5
|
Author-email: Yasser Alemán-Gómez <yasseraleman@protonmail.com>
|
|
6
6
|
Maintainer-email: Yasser Alemán-Gómez <yasseraleman@protonmail.com>
|
|
@@ -39,6 +39,10 @@ Requires-Dist: matplotlib>=3.10.3
|
|
|
39
39
|
Requires-Dist: pyvista>=0.45.3
|
|
40
40
|
Requires-Dist: nilearn>=0.12.0
|
|
41
41
|
Requires-Dist: joblib>=1.5.1
|
|
42
|
+
Requires-Dist: colorama>=0.4.6
|
|
43
|
+
Requires-Dist: dipy>=1.11.0
|
|
44
|
+
Requires-Dist: screeninfo>=0.8.1
|
|
45
|
+
Requires-Dist: ipython>=8.0.0
|
|
42
46
|
Provides-Extra: dev
|
|
43
47
|
Requires-Dist: pytest>=8.4.1; extra == "dev"
|
|
44
48
|
Requires-Dist: pytest-cov>=6.2.1; extra == "dev"
|
|
@@ -63,6 +67,11 @@ Dynamic: license-file
|
|
|
63
67
|
Connectomics Lab Toolkit
|
|
64
68
|
========================
|
|
65
69
|
|
|
70
|
+
.. image:: docs/source/_static/clabtoolkit_logo.png
|
|
71
|
+
:alt: clabtoolkit logo
|
|
72
|
+
:align: center
|
|
73
|
+
:width: 400
|
|
74
|
+
|
|
66
75
|
|
|
67
76
|
.. image:: https://img.shields.io/pypi/v/clabtoolkit.svg
|
|
68
77
|
:target: https://pypi.python.org/pypi/clabtoolkit
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
Connectomics Lab Toolkit
|
|
3
3
|
========================
|
|
4
4
|
|
|
5
|
+
.. image:: docs/source/_static/clabtoolkit_logo.png
|
|
6
|
+
:alt: clabtoolkit logo
|
|
7
|
+
:align: center
|
|
8
|
+
:width: 400
|
|
9
|
+
|
|
5
10
|
|
|
6
11
|
.. image:: https://img.shields.io/pypi/v/clabtoolkit.svg
|
|
7
12
|
:target: https://pypi.python.org/pypi/clabtoolkit
|
|
@@ -389,7 +389,18 @@ def insert_entity(
|
|
|
389
389
|
# If `entity2add` is empty after filtering, return the original entity
|
|
390
390
|
if not entity2add:
|
|
391
391
|
if is_string:
|
|
392
|
+
# Restore `suffix` and `extension` if they were removed
|
|
393
|
+
if suffix:
|
|
394
|
+
entity["suffix"] = suffix
|
|
395
|
+
if extension:
|
|
396
|
+
entity["extension"] = extension
|
|
392
397
|
return entity2str(entity)
|
|
398
|
+
|
|
399
|
+
# Restore `suffix` and `extension` if they were removed
|
|
400
|
+
if suffix:
|
|
401
|
+
entity["suffix"] = suffix
|
|
402
|
+
if extension:
|
|
403
|
+
entity["extension"] = extension
|
|
393
404
|
return entity
|
|
394
405
|
|
|
395
406
|
else:
|
|
@@ -561,6 +572,7 @@ def recursively_replace_entity_key(root_dir: str, replacements: dict):
|
|
|
561
572
|
cltmisc.rename_folders(all_dirs, replacements)
|
|
562
573
|
|
|
563
574
|
|
|
575
|
+
####################################################################################################
|
|
564
576
|
def recursively_delete_entity(root_dir: str, key2rem: Union[List[str], str, dict]):
|
|
565
577
|
"""
|
|
566
578
|
This method deletes entities in all the files and folders of a BIDs dataset.
|
|
@@ -627,6 +639,7 @@ def recursively_delete_entity(root_dir: str, key2rem: Union[List[str], str, dict
|
|
|
627
639
|
cltmisc.rename_folders(all_dirs, key2rem_dict)
|
|
628
640
|
|
|
629
641
|
|
|
642
|
+
####################################################################################################
|
|
630
643
|
def recursively_insert_entity(
|
|
631
644
|
root_dir: str, entity2add: Dict[str, str], prev_entity: str = None
|
|
632
645
|
) -> None:
|
|
@@ -788,7 +801,6 @@ def get_all_entities(root_dir: str) -> Tuple[Dict[str, Set[str]], List[str]]:
|
|
|
788
801
|
suffix = ent_dict.pop("suffix")
|
|
789
802
|
|
|
790
803
|
ent_dict.pop("extension", None)
|
|
791
|
-
ent_dict.pop("run", None)
|
|
792
804
|
|
|
793
805
|
return list(ent_dict.keys()), suffix
|
|
794
806
|
|
|
@@ -1040,7 +1052,12 @@ def entities_to_table(
|
|
|
1040
1052
|
entities_dict.pop("extension")
|
|
1041
1053
|
|
|
1042
1054
|
# Extract suffix before removing it
|
|
1043
|
-
|
|
1055
|
+
if "suffix" in entities_dict:
|
|
1056
|
+
if include_suffix:
|
|
1057
|
+
# Add an entity at the end called "Type"
|
|
1058
|
+
tmp_suffix = entities_dict["suffix"]
|
|
1059
|
+
|
|
1060
|
+
entities_dict.pop("suffix")
|
|
1044
1061
|
|
|
1045
1062
|
if entities_to_extract is not None:
|
|
1046
1063
|
if isinstance(entities_to_extract, str):
|
|
@@ -1079,8 +1096,8 @@ def entities_to_table(
|
|
|
1079
1096
|
result_df.insert(0, entity.capitalize(), value)
|
|
1080
1097
|
|
|
1081
1098
|
# Append Type column at the end if requested
|
|
1082
|
-
if include_suffix:
|
|
1083
|
-
result_df
|
|
1099
|
+
if "tmp_suffix" in locals() and include_suffix:
|
|
1100
|
+
result_df.insert(0, "Type", tmp_suffix)
|
|
1084
1101
|
|
|
1085
1102
|
else:
|
|
1086
1103
|
if result_df.empty:
|
|
@@ -1754,36 +1771,106 @@ def get_derivatives_folders(
|
|
|
1754
1771
|
|
|
1755
1772
|
|
|
1756
1773
|
####################################################################################################
|
|
1757
|
-
def is_bids_filename(filename: str) -> bool:
|
|
1774
|
+
def is_bids_filename(filename: str, extensive: bool = False) -> bool:
|
|
1758
1775
|
"""
|
|
1759
1776
|
Validates a BIDS filename structure, handling extensions and entity order.
|
|
1760
1777
|
|
|
1761
|
-
|
|
1762
|
-
|
|
1778
|
+
Parameters:
|
|
1779
|
+
-----------
|
|
1780
|
+
filename : str
|
|
1781
|
+
The filename to validate, which may include extensions (e.g., .nii.gz).
|
|
1782
|
+
|
|
1783
|
+
extensive : bool, default=False
|
|
1784
|
+
If True, performs additional checks against a BIDS configuration file to ensure that all
|
|
1785
|
+
entities in the filename are defined in the config. If False, only checks the basic structure
|
|
1786
|
+
of the filename.
|
|
1787
|
+
|
|
1788
|
+
Returns:
|
|
1789
|
+
--------
|
|
1790
|
+
bool
|
|
1791
|
+
True if the filename follows BIDS conventions, False otherwise.
|
|
1792
|
+
|
|
1793
|
+
Examples:
|
|
1794
|
+
---------
|
|
1795
|
+
>>> is_bids_filename("sub-01_ses-pre_task-rest_bold.nii.gz")
|
|
1796
|
+
True
|
|
1797
|
+
>>> is_bids_filename("sub-01_ses-pre_task-rest_bold")
|
|
1798
|
+
True
|
|
1799
|
+
>>> is_bids_filename("sub-01_ses-pre_task-rest.nii.gz")
|
|
1800
|
+
True
|
|
1801
|
+
>>> is_bids_filename("sub-01_ses-pre_task-rest")
|
|
1802
|
+
True
|
|
1803
|
+
>>> is_bids_filename("sub-01_ses-pre_task-rest_bold_extra.nii.gz")
|
|
1804
|
+
False
|
|
1805
|
+
>>> is_bids_filename("sub-01_ses-pre_task-rest_bold_extra")
|
|
1763
1806
|
|
|
1764
|
-
Returns
|
|
1765
|
-
bool: True if valid BIDS filename, False otherwise.
|
|
1766
1807
|
"""
|
|
1767
1808
|
# Remove extension if present
|
|
1768
1809
|
filename = cltmisc.get_real_basename(filename)
|
|
1769
1810
|
base_filename = filename.split(".")[0]
|
|
1770
1811
|
|
|
1771
1812
|
parts = base_filename.split("_")
|
|
1772
|
-
if
|
|
1813
|
+
if len(parts) < 2:
|
|
1814
|
+
# Need at least one entity-label pair + a suffix
|
|
1773
1815
|
return False
|
|
1774
1816
|
|
|
1775
1817
|
entity_pattern = re.compile(r"^[a-zA-Z0-9]+-[a-zA-Z0-9]+$")
|
|
1818
|
+
suffix_pattern = re.compile(r"^[a-zA-Z0-9]+$")
|
|
1776
1819
|
|
|
1777
|
-
#
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
if not has_entity_label:
|
|
1820
|
+
# All parts except the last must be valid entity-label pairs (e.g. sub-01, ses-M00)
|
|
1821
|
+
for part in parts[:-1]:
|
|
1822
|
+
if not entity_pattern.match(part):
|
|
1823
|
+
return False
|
|
1824
|
+
|
|
1825
|
+
# The last part is the suffix (e.g. T1w, bold) — no dash allowed
|
|
1826
|
+
if not suffix_pattern.match(parts[-1]):
|
|
1785
1827
|
return False
|
|
1786
1828
|
|
|
1829
|
+
# Check also that all the entities are on the json config file
|
|
1830
|
+
cwd = os.path.dirname(os.path.abspath(__file__))
|
|
1831
|
+
default_config_path = os.path.join(cwd, "config", "bids.json")
|
|
1832
|
+
|
|
1833
|
+
if extensive:
|
|
1834
|
+
try:
|
|
1835
|
+
with open(default_config_path, "r") as f:
|
|
1836
|
+
config_data = json.load(f)
|
|
1837
|
+
|
|
1838
|
+
if (
|
|
1839
|
+
"bids_entities" in config_data
|
|
1840
|
+
and "raw_entities" in config_data["bids_entities"]
|
|
1841
|
+
and "derivatives_entities" in config_data["bids_entities"]
|
|
1842
|
+
):
|
|
1843
|
+
valid_entities = set(
|
|
1844
|
+
list(config_data["bids_entities"]["raw_entities"].keys())
|
|
1845
|
+
+ list(config_data["bids_entities"]["derivatives_entities"].keys())
|
|
1846
|
+
)
|
|
1847
|
+
valid_suffixes = set(
|
|
1848
|
+
config_data["bids_entities"].get("raw_suffix", [])
|
|
1849
|
+
+ config_data["bids_entities"].get("derivatives_suffix", [])
|
|
1850
|
+
)
|
|
1851
|
+
else:
|
|
1852
|
+
raise ValueError(
|
|
1853
|
+
"Default config JSON does not have the expected structure."
|
|
1854
|
+
)
|
|
1855
|
+
except FileNotFoundError:
|
|
1856
|
+
raise FileNotFoundError(
|
|
1857
|
+
f"Default configuration file not found at: {default_config_path}"
|
|
1858
|
+
)
|
|
1859
|
+
except json.JSONDecodeError:
|
|
1860
|
+
raise ValueError(
|
|
1861
|
+
f"Error parsing the default configuration file: {default_config_path}"
|
|
1862
|
+
)
|
|
1863
|
+
|
|
1864
|
+
# Validate each entity key against the known BIDS entities
|
|
1865
|
+
for part in parts[:-1]:
|
|
1866
|
+
entity_key = part.split("-")[0]
|
|
1867
|
+
if entity_key not in valid_entities:
|
|
1868
|
+
return False
|
|
1869
|
+
|
|
1870
|
+
# Validate the suffix against the known BIDS suffixes
|
|
1871
|
+
if parts[-1] not in valid_suffixes:
|
|
1872
|
+
return False
|
|
1873
|
+
|
|
1787
1874
|
return True
|
|
1788
1875
|
|
|
1789
1876
|
|
|
@@ -122,6 +122,9 @@ class bcolors:
|
|
|
122
122
|
BOLD = "\033[1m"
|
|
123
123
|
ITALIC = "\033[3m"
|
|
124
124
|
UNDERLINE = "\033[4m"
|
|
125
|
+
DIM = "\033[2m"
|
|
126
|
+
NORMAL = "\033[22m"
|
|
127
|
+
RESET_ALL = "\033[0m"
|
|
125
128
|
|
|
126
129
|
|
|
127
130
|
####################################################################################################
|
|
@@ -899,27 +902,38 @@ def harmonize_colors(
|
|
|
899
902
|
|
|
900
903
|
>>> harmonize_colors(colors, output_format='rgb')
|
|
901
904
|
array([[255, 87, 51],
|
|
902
|
-
|
|
903
|
-
|
|
905
|
+
[255, 87, 51],
|
|
906
|
+
[ 51, 87, 255]], dtype=uint8)
|
|
904
907
|
|
|
905
908
|
>>> harmonize_colors(colors, output_format='rgbnorm')
|
|
906
909
|
array([[1. , 0.34117647, 0.2 ],
|
|
907
|
-
|
|
908
|
-
|
|
910
|
+
[1. , 0.34117647, 0.2 ],
|
|
911
|
+
[0.2 , 0.34117647, 1. ]])
|
|
909
912
|
|
|
910
913
|
>>> # Single color input
|
|
911
914
|
>>> harmonize_colors((255, 87, 51))
|
|
912
915
|
['#ff5733']
|
|
913
916
|
"""
|
|
914
917
|
|
|
915
|
-
#
|
|
918
|
+
# Normalize input into iterable of colors
|
|
916
919
|
if isinstance(colors, str):
|
|
917
920
|
colors = [colors]
|
|
921
|
+
|
|
918
922
|
elif isinstance(colors, tuple):
|
|
919
923
|
colors = [colors]
|
|
920
924
|
|
|
921
|
-
|
|
922
|
-
|
|
925
|
+
elif isinstance(colors, np.ndarray):
|
|
926
|
+
if colors.ndim == 1:
|
|
927
|
+
# Single color (e.g., [R,G,B] or [R,G,B,A])
|
|
928
|
+
colors = [colors]
|
|
929
|
+
elif colors.ndim == 2:
|
|
930
|
+
# Multiple colors (Nx3 or Nx4)
|
|
931
|
+
colors = [row for row in colors]
|
|
932
|
+
else:
|
|
933
|
+
raise ValueError("NumPy array must be 1D or 2D for colors")
|
|
934
|
+
|
|
935
|
+
# Final validation
|
|
936
|
+
if not isinstance(colors, list):
|
|
923
937
|
raise TypeError("Input must be a string, tuple, list, or numpy array")
|
|
924
938
|
|
|
925
939
|
# Validate output format
|