stouputils 1.2.40__tar.gz → 1.2.41__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 (106) hide show
  1. {stouputils-1.2.40 → stouputils-1.2.41}/PKG-INFO +27 -2
  2. {stouputils-1.2.40 → stouputils-1.2.41}/README.md +26 -1
  3. {stouputils-1.2.40 → stouputils-1.2.41}/pyproject.toml +3 -1
  4. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/all_doctests.py +28 -7
  5. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/ctx.py +2 -2
  6. stouputils-1.2.41/stouputils/data_science/config/get.py +51 -0
  7. stouputils-1.2.41/stouputils/data_science/config/set.py +103 -0
  8. stouputils-1.2.41/stouputils/data_science/data_processing/image/__init__.py +66 -0
  9. stouputils-1.2.41/stouputils/data_science/data_processing/image/auto_contrast.py +79 -0
  10. stouputils-1.2.41/stouputils/data_science/data_processing/image/axis_flip.py +58 -0
  11. stouputils-1.2.41/stouputils/data_science/data_processing/image/bias_field_correction.py +74 -0
  12. stouputils-1.2.41/stouputils/data_science/data_processing/image/binary_threshold.py +73 -0
  13. stouputils-1.2.41/stouputils/data_science/data_processing/image/blur.py +59 -0
  14. stouputils-1.2.41/stouputils/data_science/data_processing/image/brightness.py +54 -0
  15. stouputils-1.2.41/stouputils/data_science/data_processing/image/canny.py +110 -0
  16. stouputils-1.2.41/stouputils/data_science/data_processing/image/clahe.py +92 -0
  17. stouputils-1.2.41/stouputils/data_science/data_processing/image/common.py +30 -0
  18. stouputils-1.2.41/stouputils/data_science/data_processing/image/contrast.py +53 -0
  19. stouputils-1.2.41/stouputils/data_science/data_processing/image/curvature_flow_filter.py +74 -0
  20. stouputils-1.2.41/stouputils/data_science/data_processing/image/denoise.py +378 -0
  21. stouputils-1.2.41/stouputils/data_science/data_processing/image/histogram_equalization.py +123 -0
  22. stouputils-1.2.41/stouputils/data_science/data_processing/image/invert.py +64 -0
  23. stouputils-1.2.41/stouputils/data_science/data_processing/image/laplacian.py +60 -0
  24. stouputils-1.2.41/stouputils/data_science/data_processing/image/median_blur.py +52 -0
  25. stouputils-1.2.41/stouputils/data_science/data_processing/image/noise.py +59 -0
  26. stouputils-1.2.41/stouputils/data_science/data_processing/image/normalize.py +65 -0
  27. stouputils-1.2.41/stouputils/data_science/data_processing/image/random_erase.py +66 -0
  28. stouputils-1.2.41/stouputils/data_science/data_processing/image/resize.py +69 -0
  29. stouputils-1.2.41/stouputils/data_science/data_processing/image/rotation.py +80 -0
  30. stouputils-1.2.41/stouputils/data_science/data_processing/image/salt_pepper.py +68 -0
  31. stouputils-1.2.41/stouputils/data_science/data_processing/image/sharpening.py +55 -0
  32. stouputils-1.2.41/stouputils/data_science/data_processing/image/shearing.py +64 -0
  33. stouputils-1.2.41/stouputils/data_science/data_processing/image/threshold.py +64 -0
  34. stouputils-1.2.41/stouputils/data_science/data_processing/image/translation.py +71 -0
  35. stouputils-1.2.41/stouputils/data_science/data_processing/image/zoom.py +83 -0
  36. stouputils-1.2.41/stouputils/data_science/data_processing/image_augmentation.py +118 -0
  37. stouputils-1.2.41/stouputils/data_science/data_processing/image_preprocess.py +183 -0
  38. stouputils-1.2.41/stouputils/data_science/data_processing/prosthesis_detection.py +359 -0
  39. stouputils-1.2.41/stouputils/data_science/data_processing/technique.py +481 -0
  40. stouputils-1.2.41/stouputils/data_science/dataset/__init__.py +45 -0
  41. stouputils-1.2.41/stouputils/data_science/dataset/dataset.py +292 -0
  42. stouputils-1.2.41/stouputils/data_science/dataset/dataset_loader.py +135 -0
  43. stouputils-1.2.41/stouputils/data_science/dataset/grouping_strategy.py +296 -0
  44. stouputils-1.2.41/stouputils/data_science/dataset/image_loader.py +100 -0
  45. stouputils-1.2.41/stouputils/data_science/dataset/xy_tuple.py +696 -0
  46. stouputils-1.2.41/stouputils/data_science/metric_dictionnary.py +94 -0
  47. stouputils-1.2.41/stouputils/data_science/metric_utils.py +692 -0
  48. stouputils-1.2.41/stouputils/data_science/mlflow_utils.py +200 -0
  49. stouputils-1.2.41/stouputils/data_science/models/abstract_model.py +149 -0
  50. stouputils-1.2.41/stouputils/data_science/models/all.py +99 -0
  51. stouputils-1.2.41/stouputils/data_science/models/base_keras.py +765 -0
  52. stouputils-1.2.41/stouputils/data_science/models/keras/all.py +56 -0
  53. stouputils-1.2.41/stouputils/data_science/models/keras/convnext.py +62 -0
  54. stouputils-1.2.41/stouputils/data_science/models/keras/densenet.py +50 -0
  55. stouputils-1.2.41/stouputils/data_science/models/keras/efficientnet.py +60 -0
  56. stouputils-1.2.41/stouputils/data_science/models/keras/mobilenet.py +56 -0
  57. stouputils-1.2.41/stouputils/data_science/models/keras/resnet.py +99 -0
  58. stouputils-1.2.41/stouputils/data_science/models/keras/squeezenet.py +233 -0
  59. stouputils-1.2.41/stouputils/data_science/models/keras/vgg.py +42 -0
  60. stouputils-1.2.41/stouputils/data_science/models/keras/xception.py +38 -0
  61. stouputils-1.2.41/stouputils/data_science/models/keras_utils/callbacks/__init__.py +18 -0
  62. stouputils-1.2.41/stouputils/data_science/models/keras_utils/callbacks/colored_progress_bar.py +219 -0
  63. stouputils-1.2.41/stouputils/data_science/models/keras_utils/callbacks/learning_rate_finder.py +148 -0
  64. stouputils-1.2.41/stouputils/data_science/models/keras_utils/callbacks/progressive_unfreezing.py +249 -0
  65. stouputils-1.2.41/stouputils/data_science/models/keras_utils/callbacks/warmup_scheduler.py +66 -0
  66. stouputils-1.2.41/stouputils/data_science/models/keras_utils/losses/__init__.py +12 -0
  67. stouputils-1.2.41/stouputils/data_science/models/keras_utils/losses/next_generation_loss.py +56 -0
  68. stouputils-1.2.41/stouputils/data_science/models/keras_utils/visualizations.py +413 -0
  69. stouputils-1.2.41/stouputils/data_science/models/model_interface.py +887 -0
  70. stouputils-1.2.41/stouputils/data_science/models/sandbox.py +116 -0
  71. stouputils-1.2.41/stouputils/data_science/range_tuple.py +234 -0
  72. stouputils-1.2.41/stouputils/data_science/scripts/augment_dataset.py +77 -0
  73. stouputils-1.2.41/stouputils/data_science/scripts/exhaustive_process.py +128 -0
  74. stouputils-1.2.41/stouputils/data_science/scripts/preprocess_dataset.py +70 -0
  75. stouputils-1.2.41/stouputils/data_science/scripts/routine.py +168 -0
  76. stouputils-1.2.41/stouputils/data_science/utils.py +218 -0
  77. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/io.py +32 -2
  78. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/parallel.py +312 -294
  79. {stouputils-1.2.40 → stouputils-1.2.41}/.gitignore +0 -0
  80. {stouputils-1.2.40 → stouputils-1.2.41}/LICENSE +0 -0
  81. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/__init__.py +0 -0
  82. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/applications/__init__.py +0 -0
  83. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/applications/automatic_docs.py +0 -0
  84. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/applications/upscaler/__init__.py +0 -0
  85. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/applications/upscaler/config.py +0 -0
  86. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/applications/upscaler/image.py +0 -0
  87. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/applications/upscaler/video.py +0 -0
  88. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/archive.py +0 -0
  89. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/backup.py +0 -0
  90. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/collections.py +0 -0
  91. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/continuous_delivery/__init__.py +0 -0
  92. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/continuous_delivery/cd_utils.py +0 -0
  93. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/continuous_delivery/github.py +0 -0
  94. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/continuous_delivery/pypi.py +0 -0
  95. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/continuous_delivery/pyproject.py +0 -0
  96. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/decorators.py +0 -0
  97. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/dont_look/zip_file_override.py +0 -0
  98. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/image.py +0 -0
  99. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/installer/__init__.py +0 -0
  100. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/installer/common.py +0 -0
  101. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/installer/downloader.py +0 -0
  102. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/installer/linux.py +0 -0
  103. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/installer/main.py +0 -0
  104. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/installer/windows.py +0 -0
  105. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/print.py +0 -0
  106. {stouputils-1.2.40 → stouputils-1.2.41}/stouputils/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stouputils
3
- Version: 1.2.40
3
+ Version: 1.2.41
4
4
  Summary: Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more.
5
5
  Project-URL: Homepage, https://github.com/Stoupy51/stouputils
6
6
  Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
@@ -62,7 +62,7 @@ It includes a range of tools for tasks such as execution of doctests, display ut
62
62
  <pre class="code-tree">stouputils/
63
63
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.html">applications/</a>
64
64
  │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.automatic_docs.html">automatic_docs.py</a> <span class="comment"># 📚 Documentation generation utilities (used to create this documentation)</span>
65
- │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.upscaler.html">upscaler/</a> <span class="comment"># 🔎 Image & Video upscaler (configurable)</span>
65
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.upscaler.html">upscaler/</a> <span class="comment"># 🔎 Image & Video upscaler (configurable)</span>
66
66
  │ └── ...
67
67
 
68
68
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.html">continuous_delivery/</a>
@@ -72,6 +72,31 @@ It includes a range of tools for tasks such as execution of doctests, display ut
72
72
  │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.pyproject.html">pyproject.py</a> <span class="comment"># 📝 Pyproject.toml utilities</span>
73
73
  │ └── ...
74
74
 
75
+ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.html">data_science/</a>
76
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.config.html">config/</a> <span class="comment"># ⚙️ Configuration utilities for data science</span>
77
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.dataset.html">dataset/</a> <span class="comment"># 📊 Dataset handling (dataset, dataset_loader, grouping_strategy)</span>
78
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.data_processing.html">data_processing/</a> <span class="comment"># 🔄 Data processing utilities (image augmentation, preprocessing)</span>
79
+ │ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.data_processing.image.html">image/</a> <span class="comment"># 🖼️ Image processing techniques</span>
80
+ │ │ └── ...
81
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.models.html">models/</a> <span class="comment"># 🧠 ML/DL model interfaces and implementations</span>
82
+ │ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.models.keras.html">keras/</a> <span class="comment"># 🤖 Keras model implementations</span>
83
+ │ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.models.keras_utils.html">keras_utils/</a> <span class="comment"># 🛠️ Keras utilities (callbacks, losses, visualizations)</span>
84
+ │ │ └── ...
85
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.scripts.html">scripts/</a> <span class="comment"># 📜 Data science scripts (augment, preprocess, routine)</span>
86
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.metric_utils.html">metric_utils.py</a> <span class="comment"># 📏 Metrics utilities for ML/DL models</span>
87
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.mlflow_utils.html">mlflow_utils.py</a> <span class="comment"># 📊 MLflow integration utilities</span>
88
+ │ └── ...
89
+
90
+ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.dont_look.html">dont_look/</a> <span class="comment"># 🙈 Internal utilities (zip_file_override)</span>
91
+
92
+ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.html">installer/</a>
93
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.common.html">common.py</a> <span class="comment"># 🔧 Common installer utilities</span>
94
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.downloader.html">downloader.py</a> <span class="comment"># ⬇️ File download utilities</span>
95
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.linux.html">linux.py</a> <span class="comment"># 🐧 Linux-specific installer utilities</span>
96
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.main.html">main.py</a> <span class="comment"># 🚀 Main installer functionality</span>
97
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.windows.html">windows.py</a> <span class="comment"># 💻 Windows-specific installer utilities</span>
98
+ │ └── ...
99
+
75
100
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.all_doctests.html">all_doctests.py</a> <span class="comment"># ✅ Execution of all doctests for a given path</span>
76
101
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.archive.html">archive.py</a> <span class="comment"># 📦 Archive utilities (zip, repair_zip)</span>
77
102
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.backup.html">backup.py</a> <span class="comment"># 📦 Backup utilities (delta backup, consolidate)</span>
@@ -41,7 +41,7 @@ It includes a range of tools for tasks such as execution of doctests, display ut
41
41
  <pre class="code-tree">stouputils/
42
42
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.html">applications/</a>
43
43
  │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.automatic_docs.html">automatic_docs.py</a> <span class="comment"># 📚 Documentation generation utilities (used to create this documentation)</span>
44
- │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.upscaler.html">upscaler/</a> <span class="comment"># 🔎 Image & Video upscaler (configurable)</span>
44
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.applications.upscaler.html">upscaler/</a> <span class="comment"># 🔎 Image & Video upscaler (configurable)</span>
45
45
  │ └── ...
46
46
 
47
47
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.html">continuous_delivery/</a>
@@ -51,6 +51,31 @@ It includes a range of tools for tasks such as execution of doctests, display ut
51
51
  │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.continuous_delivery.pyproject.html">pyproject.py</a> <span class="comment"># 📝 Pyproject.toml utilities</span>
52
52
  │ └── ...
53
53
 
54
+ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.html">data_science/</a>
55
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.config.html">config/</a> <span class="comment"># ⚙️ Configuration utilities for data science</span>
56
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.dataset.html">dataset/</a> <span class="comment"># 📊 Dataset handling (dataset, dataset_loader, grouping_strategy)</span>
57
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.data_processing.html">data_processing/</a> <span class="comment"># 🔄 Data processing utilities (image augmentation, preprocessing)</span>
58
+ │ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.data_processing.image.html">image/</a> <span class="comment"># 🖼️ Image processing techniques</span>
59
+ │ │ └── ...
60
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.models.html">models/</a> <span class="comment"># 🧠 ML/DL model interfaces and implementations</span>
61
+ │ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.models.keras.html">keras/</a> <span class="comment"># 🤖 Keras model implementations</span>
62
+ │ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.models.keras_utils.html">keras_utils/</a> <span class="comment"># 🛠️ Keras utilities (callbacks, losses, visualizations)</span>
63
+ │ │ └── ...
64
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.scripts.html">scripts/</a> <span class="comment"># 📜 Data science scripts (augment, preprocess, routine)</span>
65
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.metric_utils.html">metric_utils.py</a> <span class="comment"># 📏 Metrics utilities for ML/DL models</span>
66
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.data_science.mlflow_utils.html">mlflow_utils.py</a> <span class="comment"># 📊 MLflow integration utilities</span>
67
+ │ └── ...
68
+
69
+ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.dont_look.html">dont_look/</a> <span class="comment"># 🙈 Internal utilities (zip_file_override)</span>
70
+
71
+ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.html">installer/</a>
72
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.common.html">common.py</a> <span class="comment"># 🔧 Common installer utilities</span>
73
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.downloader.html">downloader.py</a> <span class="comment"># ⬇️ File download utilities</span>
74
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.linux.html">linux.py</a> <span class="comment"># 🐧 Linux-specific installer utilities</span>
75
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.main.html">main.py</a> <span class="comment"># 🚀 Main installer functionality</span>
76
+ │ ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.installer.windows.html">windows.py</a> <span class="comment"># 💻 Windows-specific installer utilities</span>
77
+ │ └── ...
78
+
54
79
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.all_doctests.html">all_doctests.py</a> <span class="comment"># ✅ Execution of all doctests for a given path</span>
55
80
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.archive.html">archive.py</a> <span class="comment"># 📦 Archive utilities (zip, repair_zip)</span>
56
81
  ├── <a href="https://stoupy51.github.io/stouputils/latest/modules/stouputils.backup.html">backup.py</a> <span class="comment"># 📦 Backup utilities (delta backup, consolidate)</span>
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "stouputils"
8
- version = "1.2.40"
8
+ version = "1.2.41"
9
9
  description = "Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -64,6 +64,8 @@ ignore = [
64
64
  "W191",
65
65
  "N803",
66
66
  "N806",
67
+ "F403",
68
+ "F405",
67
69
  ]
68
70
 
69
71
  [tool.hatch.build]
@@ -16,6 +16,7 @@ from types import ModuleType
16
16
  from . import decorators
17
17
  from .decorators import LogLevels, handle_error, measure_time
18
18
  from .print import error, info, progress
19
+ from .io import clean_path, relative_path
19
20
 
20
21
 
21
22
  def test_module_with_progress(module: ModuleType, separator: str) -> TestResults:
@@ -60,19 +61,39 @@ def launch_tests(root_dir: str, importing_errors: LogLevels = LogLevels.WARNING_
60
61
  old_value: bool = strict
61
62
  decorators.force_raise_exception = True
62
63
  strict = old_value
63
-
64
+
65
+ # Get the path of the directory to check modules from
66
+ working_dir: str = clean_path(os.getcwd())
67
+ root_dir = clean_path(os.path.abspath(root_dir))
68
+ dir_to_check: str = os.path.dirname(root_dir) if working_dir != root_dir else root_dir
64
69
 
65
70
  # Get all modules from folder
66
- sys.path.insert(0, root_dir)
71
+ sys.path.insert(0, dir_to_check)
67
72
  modules_file_paths: list[str] = []
68
73
  for directory_path, _, _ in os.walk(root_dir):
74
+ directory_path = clean_path(directory_path)
69
75
  for module_info in pkgutil.walk_packages([directory_path]):
70
- absolute_module_path: str = os.path.join(directory_path, module_info.name)
71
- path: str = absolute_module_path.split(root_dir, 1)[1].replace(os.sep, ".")[1:]
72
- if path not in modules_file_paths:
73
- modules_file_paths.append(path)
76
+
77
+ # Extract root and module name
78
+ module_root: str = str(module_info.module_finder.path) # type: ignore
79
+ module_name: str = module_info.name.split(".")[-1]
80
+
81
+ # Get the absolute path
82
+ absolute_module_path: str = clean_path(os.path.join(module_root, module_name))
83
+
84
+ # Check if the module is in the root directory that we want to check
85
+ if root_dir in absolute_module_path:
86
+
87
+ # Get the path of the module like 'stouputils.io'
88
+ path: str = absolute_module_path.split(dir_to_check, 1)[1].replace("/", ".")[1:]
89
+
90
+ # If the module is not already in the list, add it
91
+ if path not in modules_file_paths:
92
+ modules_file_paths.append(path)
93
+
94
+ # If no modules are found, raise an error
74
95
  if not modules_file_paths:
75
- raise ValueError(f"No modules found in '{root_dir}'")
96
+ raise ValueError(f"No modules found in '{relative_path(root_dir)}'")
76
97
 
77
98
  # Find longest module path for alignment
78
99
  max_length: int = max(len(path) for path in modules_file_paths)
@@ -222,8 +222,8 @@ class MeasureTime:
222
222
  total_ms: float = total_ns / 1_000_000
223
223
  total_s: float = total_ns / 1_000_000_000
224
224
 
225
- # Print the execution time (nanoseconds if less than 0.3s, seconds otherwise)
226
- if total_ms < 300:
225
+ # Print the execution time (nanoseconds if less than 0.1s, seconds otherwise)
226
+ if total_ms < 100:
227
227
  self.print_func(f"{self.message}: {total_ms:.3f}ms ({total_ns}ns)")
228
228
  elif total_s < 60:
229
229
  self.print_func(f"{self.message}: {(total_s):.5f}s")
@@ -0,0 +1,51 @@
1
+ """ Load configuration from the set.py file and handle some special cases.
2
+
3
+ Proper way to get the configuration is by importing this module, not the set.py file directly.
4
+ """
5
+
6
+ # pyright: reportUnknownMemberType=false
7
+ # pyright: reportUnknownVariableType=false
8
+ # pyright: reportMissingTypeStubs=false
9
+
10
+ # Imports
11
+ import os
12
+ from typing import Any
13
+
14
+ from .set import DataScienceConfig
15
+
16
+ # Special cases
17
+ # Hide GPU when using CPU
18
+ if DataScienceConfig.TENSORFLOW_DEVICE.lower().startswith("/cpu"):
19
+ os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
20
+
21
+ # Precise which GPU we use
22
+ elif DataScienceConfig.TENSORFLOW_DEVICE.lower().startswith("/gpu"):
23
+ os.environ["CUDA_VISIBLE_DEVICES"] = DataScienceConfig.TENSORFLOW_DEVICE.split(":")[-1]
24
+
25
+ # Configure TensorFlow (if available)
26
+ try:
27
+ from tensorflow import config as tf_config
28
+
29
+ # Get the physical devices
30
+ physical_devices: list[Any] = tf_config.list_physical_devices("GPU")
31
+
32
+ # Configure TensorFlow GPU memory management to allocate memory dynamically
33
+ # This prevents TensorFlow from allocating all GPU memory upfront
34
+ # Instead, memory will grow as needed, allowing better resource sharing
35
+ for device in physical_devices:
36
+ tf_config.experimental.set_memory_growth(device, True)
37
+
38
+ # Disable eager execution mode in TensorFlow
39
+ # This improves performance by allowing TensorFlow to create an optimized graph
40
+ # of operations instead of executing operations one by one (at the cost of debugging difficulty)
41
+ tf_config.run_functions_eagerly(False)
42
+ except ImportError:
43
+ pass
44
+
45
+ # Enable mixed precision training (if available)
46
+ try:
47
+ from keras import mixed_precision
48
+ mixed_precision.set_global_policy(DataScienceConfig.MIXED_PRECISION_POLICY)
49
+ except ImportError:
50
+ pass
51
+
@@ -0,0 +1,103 @@
1
+ """ Configuration file for the project. """
2
+
3
+ # Imports
4
+ import os
5
+ from typing import Literal
6
+
7
+ from stouputils.decorators import LogLevels
8
+ from stouputils.io import get_root_path
9
+
10
+ # Environment variables
11
+ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "9" # Suppress TensorFlow logging
12
+ os.environ["GRPC_VERBOSITY"] = "ERROR" # Suppress gRPC logging
13
+
14
+
15
+ # Configuration class
16
+ class DataScienceConfig:
17
+ """ Configuration class for the project. """
18
+
19
+ # Common
20
+ SEED: int = 42
21
+ """ Seed for the random number generator. """
22
+
23
+ ERROR_LOG: LogLevels = LogLevels.WARNING_TRACEBACK
24
+ """ Log level for errors for all functions. """
25
+
26
+ AUGMENTED_FILE_SUFFIX: str = "_aug_"
27
+ """ Suffix for augmented files, ex: 'image_008_aug_1.png'. """
28
+
29
+ AUGMENTED_DIRECTORY_PREFIX: str = "aug_"
30
+ """ Prefix for augmented directories, ex: 'data/hip_implant' -> 'data/aug_hip_implant'. """
31
+
32
+ PREPROCESSED_DIRECTORY_SUFFIX: str = "_preprocessed"
33
+ """ Suffix for preprocessed directories, ex: 'data/hip_implant' -> 'data/hip_implant_preprocessed'. """
34
+
35
+
36
+ # Directories
37
+ ROOT: str = get_root_path(__file__, go_up=3)
38
+ """ Root directory of the project. """
39
+
40
+ MLFLOW_FOLDER: str = f"{ROOT}/mlruns"
41
+ """ Folder containing the mlflow data. """
42
+ MLFLOW_URI: str = f"file://{MLFLOW_FOLDER}"
43
+ """ URI to the mlflow data. """
44
+
45
+ DATA_FOLDER: str = f"{ROOT}/data"
46
+ """ Folder containing all the data (e.g. subfolders containing images). """
47
+
48
+ TEMP_FOLDER: str = f"{ROOT}/temp"
49
+ """ Folder containing temporary files (e.g. models checkpoints, plots, etc.). """
50
+
51
+ LOGS_FOLDER: str = f"{ROOT}/logs"
52
+ """ Folder containing the logs. """
53
+
54
+ TENSORBOARD_FOLDER: str = f"{ROOT}/tensorboard"
55
+ """ Folder containing the tensorboard logs. """
56
+
57
+
58
+ # Behaviours
59
+ TEST_SIZE: float = 0.2
60
+ """ Size of the test set by default (0.2 means 80% training, 20% test). """
61
+
62
+ VALIDATION_SIZE: float = 0.2
63
+ """ Size of the validation set by default (0.2 means 80% training, 20% validation). """
64
+
65
+ # Machine learning
66
+ SAVE_MODEL: bool = False
67
+ """ If the model should be saved in the mlflow folder using mlflow.*.save_model. """
68
+
69
+ DO_SALIENCY_AND_GRADCAM: bool = True
70
+ """ If the saliency and gradcam should be done during the run. """
71
+
72
+ DO_LEARNING_RATE_FINDER: Literal[0, 1, 2] = 1
73
+ """ If the learning rate finder should be done during the run.
74
+ 0: no, 1: only plot, 2: plot and use value for the remaining run
75
+ """
76
+
77
+ DO_UNFREEZE_FINDER: Literal[0, 1, 2] = 0
78
+ """ If the unfreeze finder should be done during the run.
79
+ 0: no, 1: only plot, 2: plot and use value for the remaining run
80
+ """
81
+
82
+ DO_FIT_IN_SUBPROCESS: bool = True
83
+ """ If the model should be fitted in a subprocess.
84
+ Is memory efficient, and more stable. Turn it off only if you are having issues.
85
+
86
+ Note: This allow a program to make lots of runs without getting killed by the OS for using too much resources.
87
+ (e.g. LeaveOneOut Cross Validation, Grid Search, etc.)
88
+ """
89
+
90
+ MIXED_PRECISION_POLICY: Literal["mixed_float16", "mixed_bfloat16", "float32"] = "mixed_float16"
91
+ """ Mixed precision policy to use. Turn back to "float32" if you are having issues with a specific model or metrics.
92
+ See: https://www.tensorflow.org/guide/mixed_precision
93
+ """
94
+
95
+ TENSORFLOW_DEVICE: str = "/gpu:1"
96
+ """ TensorFlow device to use. """
97
+
98
+
99
+
100
+ # Fix MLFLOW_URI for Windows by adding a missing slash
101
+ if os.name == "nt":
102
+ DataScienceConfig.MLFLOW_URI = DataScienceConfig.MLFLOW_URI.replace("file:", "file:/")
103
+
@@ -0,0 +1,66 @@
1
+
2
+ # Imports
3
+ from .auto_contrast import auto_contrast_image
4
+ from .axis_flip import flip_image
5
+ from .bias_field_correction import bias_field_correction_image
6
+ from .binary_threshold import binary_threshold_image
7
+ from .blur import blur_image
8
+ from .brightness import brightness_image
9
+ from .canny import canny_image
10
+ from .clahe import clahe_image
11
+ from .contrast import contrast_image
12
+ from .curvature_flow_filter import curvature_flow_filter_image
13
+ from .denoise import (
14
+ adaptive_denoise_image,
15
+ bilateral_denoise_image,
16
+ nlm_denoise_image,
17
+ tv_denoise_image,
18
+ wavelet_denoise_image,
19
+ )
20
+ from .invert import invert_image
21
+ from .laplacian import laplacian_image
22
+ from .median_blur import median_blur_image
23
+ from .noise import noise_image
24
+ from .normalize import normalize_image
25
+ from .random_erase import random_erase_image
26
+ from .resize import resize_image
27
+ from .rotation import rotate_image
28
+ from .salt_pepper import salt_pepper_image
29
+ from .sharpening import sharpen_image
30
+ from .shearing import shear_image
31
+ from .threshold import threshold_image
32
+ from .translation import translate_image
33
+ from .zoom import zoom_image
34
+
35
+ __all__ = [
36
+ "adaptive_denoise_image",
37
+ "auto_contrast_image",
38
+ "bias_field_correction_image",
39
+ "bilateral_denoise_image",
40
+ "binary_threshold_image",
41
+ "blur_image",
42
+ "brightness_image",
43
+ "canny_image",
44
+ "clahe_image",
45
+ "contrast_image",
46
+ "curvature_flow_filter_image",
47
+ "flip_image",
48
+ "invert_image",
49
+ "laplacian_image",
50
+ "median_blur_image",
51
+ "nlm_denoise_image",
52
+ "noise_image",
53
+ "normalize_image",
54
+ "random_erase_image",
55
+ "resize_image",
56
+ "rotate_image",
57
+ "salt_pepper_image",
58
+ "sharpen_image",
59
+ "shear_image",
60
+ "threshold_image",
61
+ "translate_image",
62
+ "tv_denoise_image",
63
+ "wavelet_denoise_image",
64
+ "zoom_image",
65
+ ]
66
+
@@ -0,0 +1,79 @@
1
+
2
+ # pyright: reportUnusedImport=false
3
+ # ruff: noqa: F401
4
+
5
+ # Imports
6
+ from .common import Any, NDArray, check_image, cv2, np
7
+
8
+
9
+ # Functions
10
+ def auto_contrast_image(image: NDArray[Any], ignore_dtype: bool = False) -> NDArray[Any]:
11
+ """ Adjust the contrast of an image.
12
+
13
+ Args:
14
+ image (NDArray[Any]): Image to adjust contrast
15
+ ignore_dtype (bool): Ignore the dtype check
16
+ Returns:
17
+ NDArray[Any]: Image with adjusted contrast
18
+
19
+ >>> ## Basic tests
20
+ >>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint8)
21
+ >>> adjusted = auto_contrast_image(image)
22
+ >>> adjusted.tolist()
23
+ [[0, 36, 73], [109, 146, 182], [219, 255, 255]]
24
+ >>> adjusted.shape == image.shape
25
+ True
26
+ >>> adjusted.dtype == image.dtype
27
+ True
28
+
29
+ >>> ## Test invalid inputs
30
+ >>> auto_contrast_image("not an image")
31
+ Traceback (most recent call last):
32
+ ...
33
+ AssertionError: Image must be a numpy array
34
+ """
35
+ # Check input data
36
+ check_image(image, ignore_dtype=ignore_dtype)
37
+
38
+ # Perform histogram clipping
39
+ clip_hist_percent: float = 1.0
40
+
41
+ # Calculate the histogram of the image
42
+ hist: NDArray[Any] = cv2.calcHist([image], [0], None, [256], [0, 256])
43
+
44
+ # Create an accumulator list to store the cumulative histogram
45
+ accumulator: list[float] = []
46
+ accumulator.append(hist[0])
47
+ for i in range(1, 256):
48
+ accumulator.append(accumulator[i - 1] + hist[i])
49
+
50
+ # Find the maximum value in the accumulator
51
+ max_value: float = accumulator[-1]
52
+
53
+ # Calculate the clipping threshold
54
+ clip_hist_percent = clip_hist_percent * (max_value / 100.0)
55
+ clip_hist_percent = clip_hist_percent / 2.0
56
+
57
+ # Find the minimum and maximum gray levels after clipping
58
+ min_gray: int = 0
59
+ while accumulator[min_gray] < clip_hist_percent:
60
+ min_gray = min_gray + 1
61
+ max_gray: int = 256 - 1
62
+ while (max_gray >= 0 and accumulator[max_gray] >= (max_value - clip_hist_percent)):
63
+ max_gray = max_gray - 1
64
+
65
+ # Calculate the input range after clipping
66
+ input_range: int = max_gray - min_gray
67
+
68
+ # If the input range is 0, return the original image
69
+ if input_range == 0:
70
+ return image
71
+
72
+ # Calculate the scaling factors for contrast adjustment
73
+ alpha: float = (256 - 1) / input_range
74
+ beta: float = -min_gray * alpha
75
+
76
+ # Apply the contrast adjustment
77
+ adjusted: NDArray[Any] = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
78
+ return adjusted
79
+
@@ -0,0 +1,58 @@
1
+
2
+ # pyright: reportUnusedImport=false
3
+ # ruff: noqa: F401
4
+
5
+ # Imports
6
+ from typing import Literal
7
+
8
+ from .common import Any, NDArray, check_image, cv2, np
9
+
10
+
11
+ # Functions
12
+ def flip_image(
13
+ image: NDArray[Any], axis: Literal["horizontal", "vertical", "both"], ignore_dtype: bool = True
14
+ ) -> NDArray[Any]:
15
+ """ Flip an image along specified axis
16
+
17
+ Args:
18
+ image (NDArray[Any]): Image to flip
19
+ axis (str): Axis along which to flip ("horizontal" or "vertical" or "both")
20
+ ignore_dtype (bool): Ignore the dtype check
21
+ Returns:
22
+ NDArray[Any]: Flipped image
23
+
24
+ >>> ## Basic tests
25
+ >>> image = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
26
+ >>> flip_image(image, "horizontal").tolist()
27
+ [[3, 2, 1], [6, 5, 4], [9, 8, 7]]
28
+
29
+ >>> flip_image(image, "vertical").tolist()
30
+ [[7, 8, 9], [4, 5, 6], [1, 2, 3]]
31
+
32
+ >>> flip_image(image, "both").tolist()
33
+ [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
34
+
35
+ >>> ## Test invalid inputs
36
+ >>> flip_image(image, "diagonal")
37
+ Traceback (most recent call last):
38
+ AssertionError: axis must be either 'horizontal' or 'vertical' or 'both', got 'diagonal'
39
+
40
+ >>> flip_image("not an image", "horizontal")
41
+ Traceback (most recent call last):
42
+ ...
43
+ AssertionError: Image must be a numpy array
44
+ """
45
+ # Check input data
46
+ check_image(image, ignore_dtype=ignore_dtype)
47
+ assert axis in ("horizontal", "vertical", "both"), (
48
+ f"axis must be either 'horizontal' or 'vertical' or 'both', got '{axis}'"
49
+ )
50
+
51
+ # Apply the flip
52
+ if axis == "horizontal":
53
+ return cv2.flip(image, 1) # 1 for horizontal flip
54
+ elif axis == "vertical":
55
+ return cv2.flip(image, 0) # 0 for vertical flip
56
+ else:
57
+ return cv2.flip(image, -1) # -1 for both flips
58
+
@@ -0,0 +1,74 @@
1
+
2
+ # pyright: reportUnknownMemberType=false
3
+ # pyright: reportUnknownArgumentType=false
4
+ # pyright: reportUnknownVariableType=false
5
+
6
+ # Imports
7
+ import SimpleITK as Sitk
8
+
9
+ from .common import Any, NDArray, check_image, np
10
+
11
+
12
+ # Functions
13
+ def bias_field_correction_image(image: NDArray[Any], ignore_dtype: bool = False) -> NDArray[Any]:
14
+ """ Apply a bias field correction to an image. (N4 Filter)
15
+
16
+ Args:
17
+ image (NDArray[Any]): Image to apply the bias field correction (can't be 8-bit unsigned integer)
18
+ ignore_dtype (bool): Ignore the dtype check
19
+ Returns:
20
+ NDArray[Any]: Image with the curvature flow filter applied
21
+
22
+ >>> ## Basic tests
23
+ >>> image = np.random.randint(0, 255, size=(10,10), dtype=np.uint8) / 255
24
+ >>> corrected = bias_field_correction_image(image)
25
+ >>> corrected.shape == image.shape
26
+ True
27
+ >>> corrected.dtype == np.float64
28
+ True
29
+
30
+ >>> ## Test invalid inputs
31
+ >>> bias_field_correction_image("not an image")
32
+ Traceback (most recent call last):
33
+ ...
34
+ AssertionError: Image must be a numpy array
35
+ """
36
+ # Check input data
37
+ check_image(image, ignore_dtype=ignore_dtype)
38
+
39
+ # If the image is 3D, convert to grayscale first
40
+ if image.ndim == 3:
41
+ image = np.mean(image, axis=-1)
42
+
43
+ # Convert numpy array to SimpleITK image
44
+ image_sitk: Sitk.Image = Sitk.GetImageFromArray(image)
45
+
46
+ # Create binary mask of the head region
47
+ transformed: Sitk.Image = Sitk.RescaleIntensity(image_sitk) # Normalize intensities
48
+ transformed = Sitk.LiThreshold(transformed, 0, 1) # Apply Li thresholding
49
+ head_mask: Sitk.Image = transformed
50
+
51
+ # Downsample images to speed up bias field estimation
52
+ shrink_factor: int = 4 # Reduce image size by factor of 4
53
+ input_image: Sitk.Image = Sitk.Shrink(
54
+ image_sitk,
55
+ [shrink_factor] * image_sitk.GetDimension() # Apply shrink factor to all dimensions
56
+ )
57
+ mask_image: Sitk.Image = Sitk.Shrink(
58
+ head_mask,
59
+ [shrink_factor] * image_sitk.GetDimension()
60
+ )
61
+
62
+ # Apply N4 bias field correction
63
+ corrector = Sitk.N4BiasFieldCorrectionImageFilter()
64
+ corrector.Execute(input_image, mask_image)
65
+
66
+ # Get estimated bias field and apply correction
67
+ log_bias_field: Sitk.Image = Sitk.Cast(
68
+ corrector.GetLogBiasFieldAsImage(image_sitk), Sitk.sitkFloat64
69
+ )
70
+ corrected_image_full_resolution: Sitk.Image = image_sitk / Sitk.Exp(log_bias_field)
71
+
72
+ # Convert back to numpy array and return
73
+ return Sitk.GetArrayFromImage(corrected_image_full_resolution)
74
+