clabtoolkit 0.4.0__tar.gz → 0.4.2__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.
Files changed (78) hide show
  1. clabtoolkit-0.4.2/HISTORY.rst +35 -0
  2. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/MANIFEST.in +3 -0
  3. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/PKG-INFO +1 -1
  4. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/__init__.py +1 -1
  5. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/bidstools.py +41 -67
  6. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/colorstools.py +491 -154
  7. clabtoolkit-0.4.2/clabtoolkit/connectivitytools.py +1285 -0
  8. clabtoolkit-0.4.2/clabtoolkit/connectome.py +723 -0
  9. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/dicomtools.py +147 -1
  10. clabtoolkit-0.4.2/clabtoolkit/dwitools.py +797 -0
  11. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/freesurfertools.py +203 -66
  12. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/imagetools.py +4 -10
  13. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/misctools.py +1763 -1625
  14. clabtoolkit-0.4.2/clabtoolkit/misctools_utils.py +949 -0
  15. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/morphometrytools.py +117 -37
  16. clabtoolkit-0.4.0/clabtoolkit/dwitools.py → clabtoolkit-0.4.2/clabtoolkit/old_dwitool.py +0 -465
  17. clabtoolkit-0.4.2/clabtoolkit/parcellationtools.py +3439 -0
  18. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/pipelinetools.py +459 -16
  19. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/pointstools.py +58 -10
  20. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/segmentationtools.py +2 -2
  21. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/surfacetools.py +108 -163
  22. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/tracttools.py +22 -25
  23. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/visualization_utils.py +5 -0
  24. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/visualizationtools.py +10 -8
  25. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit.egg-info/PKG-INFO +1 -1
  26. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit.egg-info/SOURCES.txt +9 -4
  27. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/pyproject.toml +1 -1
  28. clabtoolkit-0.4.2/usage_examples/examples-colorstools-methods.ipynb +855 -0
  29. clabtoolkit-0.4.2/usage_examples/examples-misctools-methods.ipynb +2514 -0
  30. clabtoolkit-0.4.2/usage_examples/examples-parcellationtools-methods.ipynb +1808 -0
  31. clabtoolkit-0.4.2/usage_examples/examples-surfacetools-methods.ipynb +2068 -0
  32. clabtoolkit-0.4.2/usage_examples/examples-visualizationtools-methods.ipynb +1751 -0
  33. clabtoolkit-0.4.0/HISTORY.rst +0 -20
  34. clabtoolkit-0.4.0/clabtoolkit/connectivitytools.py +0 -0
  35. clabtoolkit-0.4.0/clabtoolkit/parcellationtools.py +0 -2654
  36. clabtoolkit-0.4.0/docs/build/html/_static/file.png +0 -0
  37. clabtoolkit-0.4.0/docs/build/html/_static/minus.png +0 -0
  38. clabtoolkit-0.4.0/docs/build/html/_static/plus.png +0 -0
  39. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/AUTHORS.rst +0 -0
  40. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/CONTRIBUTING.rst +0 -0
  41. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/LICENSE +0 -0
  42. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/README.rst +0 -0
  43. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/build_visualization_layout.py +0 -0
  44. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/config/bids.json +0 -0
  45. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/config/config.json +0 -0
  46. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/config/lobes.json +0 -0
  47. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/config/stats_mapping.json +0 -0
  48. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/config/viz_views.json +0 -0
  49. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/config/viz_views_test.json +0 -0
  50. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/networktools.py +0 -0
  51. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/plottools.py +0 -0
  52. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit/qcqatools.py +0 -0
  53. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit.egg-info/dependency_links.txt +0 -0
  54. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit.egg-info/requires.txt +0 -0
  55. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/clabtoolkit.egg-info/top_level.txt +0 -0
  56. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/Makefile +0 -0
  57. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/clabtoolkit.rst +0 -0
  58. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/make.bat +0 -0
  59. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/modules.rst +0 -0
  60. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/conf.py +0 -0
  61. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/index.rst +0 -0
  62. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/bidstools.rst +0 -0
  63. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/connectivitytools.rst +0 -0
  64. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/dicomtools.rst +0 -0
  65. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/dwitools.rst +0 -0
  66. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/freesurfertools.rst +0 -0
  67. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/imagetools.rst +0 -0
  68. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/misctools.rst +0 -0
  69. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/morphometrytools.rst +0 -0
  70. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/networktools.rst +0 -0
  71. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/parcellationtools.rst +0 -0
  72. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/pipelinetools.rst +0 -0
  73. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/plottools.rst +0 -0
  74. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/qcqatools.rst +0 -0
  75. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/segmentationtools.rst +0 -0
  76. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/surfacetools.rst +0 -0
  77. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/docs/source/modules/visualizationtools.rst +0 -0
  78. {clabtoolkit-0.4.0 → clabtoolkit-0.4.2}/setup.cfg +0 -0
@@ -0,0 +1,35 @@
1
+ =======
2
+ History
3
+ =======
4
+
5
+ 0.4.1 (2026-02-19)
6
+ ------------------
7
+
8
+ * Major refactoring of Parcellation class with improved attribute handling
9
+ * Enhanced color table loading and export with multiple format support
10
+ * Added region adjacency computation to Parcellation
11
+ * Improved BIDS file entity extraction with parallel processing
12
+ * Added DiffusionScheme class for gradient visualization
13
+ * Enhanced Connectome class initialization and metrics computation
14
+ * Added derivatives inventory functionality
15
+ * Improved surface tools with PyVista fallback support
16
+ * Added usage examples notebooks
17
+ * Multiple bug fixes in mask handling, color processing, and data type conversion
18
+ * Improved documentation and code organization
19
+
20
+ 0.3.4 (2025-01-09)
21
+ ------------------
22
+
23
+ * Enhanced documentation and ReadTheDocs configuration
24
+ * Moved region growing method to imagetools module
25
+ * Improved Sphinx autodoc configuration for better API documentation
26
+ * Multiple improvements to surface visualization and plotting functionality
27
+ * Added new morphometry and connectivity analysis tools
28
+ * Enhanced BIDS dataset handling and entity management
29
+ * Improved surface mesh operations and color mapping
30
+ * Added network analysis tools and visualization capabilities
31
+
32
+ 0.3.1 (2025-05-22)
33
+ ------------------
34
+
35
+ * Fourth release on PyPI.
@@ -14,6 +14,9 @@ recursive-include docs *.rst *.py *.bat *.png
14
14
  recursive-include docs Makefile
15
15
  include docs/make.bat
16
16
 
17
+ # Include usage examples
18
+ recursive-include usage_examples *.ipynb *.py *.md
19
+
17
20
  # EXCLUDE tests data completely
18
21
  prune tests
19
22
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clabtoolkit
3
- Version: 0.4.0
3
+ Version: 0.4.2
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>
@@ -2,4 +2,4 @@
2
2
 
3
3
  __author__ = """Yasser Alemán-Gómez"""
4
4
  __email__ = "yasseraleman@protonmail.com"
5
- __version__ = "0.4.0"
5
+ __version__ = "0.4.1"
@@ -23,6 +23,8 @@ from rich.progress import (
23
23
  )
24
24
  from rich.console import Console
25
25
  from rich.panel import Panel
26
+ import concurrent.futures
27
+
26
28
 
27
29
  # Importing the clabtoolkit modules
28
30
  from . import misctools as cltmisc
@@ -777,29 +779,29 @@ def get_all_entities(root_dir: str) -> Tuple[Dict[str, Set[str]], List[str]]:
777
779
  # Leave only the files that are BIDs files
778
780
  bids_files = cltmisc.filter_by_substring(bids_files, bids_folders)
779
781
 
780
- # Initialize a set to store all unique entities
781
- all_entities = []
782
- all_suffixes = []
783
- for file in bids_files:
784
-
782
+ def process_file(file):
785
783
  filename = os.path.basename(file)
786
784
  ent_dict = str2entity(filename)
787
785
 
788
- # Remove suffix and extension from the entity dictionary
786
+ suffix = None
789
787
  if "suffix" in ent_dict:
790
- suffix = ent_dict["suffix"]
791
- all_suffixes.append(suffix)
792
- del ent_dict["suffix"]
788
+ suffix = ent_dict.pop("suffix")
789
+
790
+ ent_dict.pop("extension", None)
791
+ ent_dict.pop("run", None)
793
792
 
794
- if "extension" in ent_dict:
795
- del ent_dict["extension"]
793
+ return list(ent_dict.keys()), suffix
796
794
 
797
- if "run" in ent_dict:
798
- del ent_dict["run"]
795
+ all_entities = []
796
+ all_suffixes = []
799
797
 
800
- file_ent_keys = list(ent_dict.keys())
798
+ with concurrent.futures.ThreadPoolExecutor() as executor:
799
+ results = executor.map(process_file, bids_files)
801
800
 
802
- all_entities.extend(file_ent_keys)
801
+ for entity_keys, suffix in results:
802
+ all_entities.extend(entity_keys)
803
+ if suffix is not None:
804
+ all_suffixes.append(suffix)
803
805
 
804
806
  # Unique entities
805
807
  all_entities = sorted(set(all_entities))
@@ -952,14 +954,12 @@ def entities4table(
952
954
  def entities_to_table(
953
955
  filepath: str,
954
956
  entities_to_extract: Optional[Union[str, List[str], Dict[str, str]]] = None,
957
+ include_suffix: bool = False,
955
958
  ) -> pd.DataFrame:
956
959
  """
957
960
  Creates a DataFrame with BIDS entities extracted from a filename.
958
961
 
959
- This function parses BIDS-compliant filenames to extract specified entities
960
- (such as subject, session, task) and organizes them into a DataFrame with
961
- appropriate column names. It supports special handling for certain entities
962
- like atlas and description fields.
962
+ ...
963
963
 
964
964
  Parameters
965
965
  ----------
@@ -971,42 +971,27 @@ def entities_to_table(
971
971
  - If list: Multiple entity names to extract
972
972
  - If dict: Keys are entity names, values are custom column names
973
973
  - If None: Returns a single column with the full filename
974
+ include_suffix : bool, default=True
975
+ If True, adds a 'Type' column containing the BIDS suffix
976
+ (e.g., 'bold', 'T1w', 'dwi') extracted from the filename.
974
977
 
975
978
  Returns
976
979
  -------
977
980
  pd.DataFrame
978
981
  DataFrame containing the extracted entities as columns.
982
+ If include_suffix is True, a 'Type' column is appended at the end.
979
983
  If the file is not BIDS-compliant, returns an empty DataFrame.
980
984
 
981
985
  Examples
982
986
  --------
983
- >>> # Extract subject and session from a BIDS file
984
987
  >>> df = entities_to_table(
985
988
  ... '/data/sub-01/ses-pre/sub-01_ses-pre_task-rest_bold.nii.gz',
986
- ... ['sub', 'ses']
987
- ... )
988
- >>> print(df)
989
- Participant Session
990
- 0 01 pre
991
-
992
- >>> # Extract entities with custom column names
993
- >>> df = entities_to_table(
994
- ... '/data/sub-01/anat/sub-01_T1w.nii.gz',
995
- ... {'sub': 'SubjectID'}
996
- ... )
997
- >>> print(df)
998
- SubjectID
999
- 0 01
1000
-
1001
- >>> # Extract atlas with special handling
1002
- >>> df = entities_to_table(
1003
- ... '/data/sub-01/atlas-chimera123_desc-parcellation.nii.gz',
1004
- ... ['atlas', 'desc']
989
+ ... ['sub', 'ses'],
990
+ ... include_suffix=True
1005
991
  ... )
1006
992
  >>> print(df)
1007
- Atlas ChimeraCode Description
1008
- 0 chimera 123 parcellation
1009
-
993
+ Participant Session Type
994
+ 0 01 pre bold
1010
995
  """
1011
996
  # Type checking
1012
997
  if filepath is None or not isinstance(filepath, str):
@@ -1019,7 +1004,6 @@ def entities_to_table(
1019
1004
  with open(default_config_path, "r") as f:
1020
1005
  config_data = json.load(f)
1021
1006
 
1022
- # Merge raw and derivatives entities
1023
1007
  if (
1024
1008
  "bids_entities" in config_data
1025
1009
  and "raw_entities" in config_data["bids_entities"]
@@ -1042,63 +1026,49 @@ def entities_to_table(
1042
1026
  f"Error parsing the default configuration file: {default_config_path}"
1043
1027
  )
1044
1028
 
1045
- # Extract file directory and name
1046
1029
  file_directory = os.path.dirname(filepath)
1047
- filename = os.path.basename(filepath)
1030
+ filename = cltmisc.get_real_basename(filepath)
1031
+ filename = filename.split(".")[0]
1048
1032
 
1049
- # Create an empty DataFrame
1050
1033
  result_df = pd.DataFrame()
1051
1034
 
1052
- # Only process if the file follows BIDS naming convention
1053
1035
  if is_bids_filename(filename):
1054
1036
 
1055
- # Parse entities from the filename
1056
1037
  entities_dict = str2entity(filename)
1057
1038
 
1058
- # Remove the 'extension' key if it exists
1059
1039
  if "extension" in entities_dict:
1060
1040
  entities_dict.pop("extension")
1061
- # Remove the 'suffix' key if it exists
1062
- if "suffix" in entities_dict:
1063
- entities_dict.pop("suffix")
1041
+
1042
+ # Extract suffix before removing it
1043
+ suffix = entities_dict.pop("suffix", "")
1064
1044
 
1065
1045
  if entities_to_extract is not None:
1066
- # Convert string input to list
1067
1046
  if isinstance(entities_to_extract, str):
1068
1047
  entities_to_extract = [entities_to_extract]
1069
1048
 
1070
- # Convert list to dictionary for unified processing
1071
1049
  if isinstance(entities_to_extract, list):
1072
- # Create dict with entity names as both keys and values
1073
1050
  entities_to_extract = {entity: "" for entity in entities_to_extract}
1074
1051
  else:
1075
1052
  entities_to_extract = {entity: "" for entity in entities_dict.keys()}
1076
1053
 
1077
- # Initialize DataFrame with one empty row
1078
1054
  if result_df.empty:
1079
1055
  result_df = pd.DataFrame([{}])
1080
1056
 
1081
- # Process entities in reverse order to maintain column order
1082
1057
  entity_keys = list(entities_to_extract.keys())
1083
1058
  for entity in reversed(entity_keys):
1084
- # Get entity value from filename or empty string if not found
1085
1059
  value = entities_dict.get(entity, "")
1086
1060
 
1087
1061
  if entity in ent_out_dict.keys():
1088
- # If entity is in the mapping dictionary, use its value
1089
1062
  var_name = ent_out_dict[entity]
1090
1063
  if entity == "atlas":
1091
- # Special handling for atlas
1092
1064
  if "chimera" in value:
1093
1065
  result_df.insert(0, "ChimeraCode", value.replace("chimera", ""))
1094
1066
  result_df.insert(0, "Atlas", "chimera")
1095
-
1096
1067
  else:
1097
1068
  result_df.insert(0, "ChimeraCode", "")
1098
1069
  result_df.insert(0, "Atlas", value)
1099
1070
 
1100
1071
  elif entity == "desc":
1101
- # Special handling for description
1102
1072
  result_df.insert(0, "Description", value)
1103
1073
  if "grow" in value:
1104
1074
  result_df.insert(0, "GrowIntoWM", value.replace("grow", ""))
@@ -1106,21 +1076,24 @@ def entities_to_table(
1106
1076
  else:
1107
1077
  result_df.insert(0, var_name, value)
1108
1078
  else:
1109
-
1110
1079
  result_df.insert(0, entity.capitalize(), value)
1111
1080
 
1081
+ # Append Type column at the end if requested
1082
+ if include_suffix:
1083
+ result_df["Type"] = suffix
1084
+
1112
1085
  else:
1113
- # If no entities specified, use full filename as Participant
1114
1086
  if result_df.empty:
1115
1087
  result_df = pd.DataFrame([{}])
1116
1088
 
1117
1089
  if "Participant" not in result_df.columns:
1118
- # If 'Participant' column doesn't exist, create it
1119
- # Remove the extension from the filename in case it exists
1120
1090
  temp = os.path.splitext(filename)[0]
1121
1091
  result_df.insert(0, "Participant", temp)
1122
1092
 
1123
- # Declaring all the columns as string type
1093
+ # No suffix available for non-BIDS files
1094
+ if include_suffix:
1095
+ result_df["Type"] = ""
1096
+
1124
1097
  for col in result_df.columns:
1125
1098
  result_df[col] = result_df[col].astype(str)
1126
1099
 
@@ -1792,6 +1765,7 @@ def is_bids_filename(filename: str) -> bool:
1792
1765
  bool: True if valid BIDS filename, False otherwise.
1793
1766
  """
1794
1767
  # Remove extension if present
1768
+ filename = cltmisc.get_real_basename(filename)
1795
1769
  base_filename = filename.split(".")[0]
1796
1770
 
1797
1771
  parts = base_filename.split("_")