brainles-preprocessing 0.6.0__tar.gz → 0.6.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.
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/PKG-INFO +24 -6
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/README.md +20 -4
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/brain_extraction/brain_extractor.py +2 -7
- brainles_preprocessing-0.6.2/brainles_preprocessing/brain_extraction/synthstrip.py +231 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/modality.py +11 -4
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/preprocessor/atlas_centric_preprocessor.py +92 -89
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/preprocessor/native_space_preprocessor.py +75 -73
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/preprocessor/preprocessor.py +34 -23
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/elastix/elastix.py +2 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/greedy/greedy.py +3 -1
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/transform.py +2 -4
- brainles_preprocessing-0.6.2/brainles_preprocessing/utils/zenodo.py +209 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/pyproject.toml +9 -3
- brainles_preprocessing-0.6.0/brainles_preprocessing/utils/logging_utils.py +0 -131
- brainles_preprocessing-0.6.0/brainles_preprocessing/utils/zenodo.py +0 -189
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/LICENSE +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/brain_extraction/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/brats/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/brats/t1_centric.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/brats/t1c_centric.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/cli.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/constants.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/defacing/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/defacing/defacer.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/defacing/quickshear/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/defacing/quickshear/nipy_quickshear.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/defacing/quickshear/quickshear.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/n4_bias_correction/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/n4_bias_correction/n4_bias_corrector.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/n4_bias_correction/sitk/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/n4_bias_correction/sitk/sitk_n4_bias_corrector.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/normalization/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/normalization/normalizer_base.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/normalization/percentile_normalizer.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/normalization/windowing_normalizer.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/preprocessor/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/ANTs/ANTs.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/ANTs/TODO_ANTs_parameters.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/ANTs/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/elastix/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/greedy/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/groupwise_niftyreg_params.sh +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/groupwise_niftyreg_run.sh +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/reg_aladin +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/reg_average +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/reg_f3d +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/reg_jacobian +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/reg_measure +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/reg_resample +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/reg_tools +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/bin/reg_transform +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/AffineDeformationFieldKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/AladinContent.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/BlockMatchingKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/CPUAffineDeformationFieldKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/CPUBlockMatchingKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/CPUConvolutionKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/CPUKernelFactory.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/CPUOptimiseKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/CPUResampleImageKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/ConvolutionKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/Kernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/KernelFactory.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/OptimiseKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/Platform.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/ResampleImageKernel.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_ReadWriteImage.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_ReadWriteMatrix.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_aladin.cpp +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_aladin.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_aladin_sym.cpp +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_aladin_sym.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_base.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_blockMatching.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_dti.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_f3d.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_f3d2.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_f3d_sym.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_femTrans.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_globalTrans.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_kld.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_lncc.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_localTrans.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_localTrans_jac.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_localTrans_regul.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_macros.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_maths.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_maths_eigen.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_measure.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_mind.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_nmi.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_optimiser.cpp +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_optimiser.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_resampling.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_splineBasis.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_ssd.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_stringFormat.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/_reg_tools.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/nifti1.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/nifti1_io.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/png.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/pngconf.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/pngdebug.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/pnginfo.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/pnglibconf.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/pngpriv.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/pngstruct.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/readpng.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/reg_png.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/zlib.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/znzlib.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/niftyreg_1.5.68/include/zutil.h +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/reg_aladin +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/reg_resample +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/rigid_reg.sh +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/niftyreg/niftyreg_scripts/transform.sh +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/registration/registrator.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/utils/__init__.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/utils/citation_reminder.py +0 -0
- {brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/utils/generic.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: brainles_preprocessing
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Tool for preprocessing tasks in biomedical imaging, with a focus on (but not limited to) multi-modal brain MRI
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Keywords: brain tumor,glioma,BraTS,skullstripping,brain extraction
|
|
@@ -19,13 +19,15 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Provides-Extra: all
|
|
20
20
|
Provides-Extra: itk-elastix
|
|
21
21
|
Provides-Extra: picsl-greedy
|
|
22
|
+
Provides-Extra: synthstrip
|
|
22
23
|
Requires-Dist: antspyx (>=0.5.4,<1.0.0)
|
|
23
24
|
Requires-Dist: auxiliary (>=0.3.1)
|
|
24
25
|
Requires-Dist: brainles_hd_bet (>=0.0.10,<1.0.0)
|
|
25
26
|
Requires-Dist: itk-elastix (>=0.20.0,<0.21.0) ; extra == "all" or extra == "itk-elastix"
|
|
27
|
+
Requires-Dist: loguru (>=0.7.3,<0.8.0)
|
|
26
28
|
Requires-Dist: nibabel (>=3.2.1)
|
|
29
|
+
Requires-Dist: nipreps-synthstrip (>=0.0.1,<0.0.2) ; extra == "all" or extra == "synthstrip"
|
|
27
30
|
Requires-Dist: numpy (>=1.23.0,<2.0.0)
|
|
28
|
-
Requires-Dist: pathlib (>=1.0.1,<2.0.0)
|
|
29
31
|
Requires-Dist: picsl_greedy (>=0.0.6,<0.0.7) ; extra == "all" or extra == "picsl-greedy"
|
|
30
32
|
Requires-Dist: rich (>=13.6.0,<14.0.0)
|
|
31
33
|
Requires-Dist: scipy (<1.14)
|
|
@@ -176,17 +178,33 @@ We provide a (WIP) documentation. Have a look [here](https://brainles-preprocess
|
|
|
176
178
|
Please credit the authors by citing their work.
|
|
177
179
|
|
|
178
180
|
### Registration
|
|
179
|
-
We currently
|
|
181
|
+
We currently fully support:
|
|
182
|
+
- [ANTs](https://github.com/ANTsX/ANTs) (default)
|
|
183
|
+
- [Niftyreg](https://github.com/KCL-BMEIS/niftyreg) (Linux)
|
|
184
|
+
|
|
185
|
+
We also offer basic support for:
|
|
186
|
+
- [greedy](https://greedy.readthedocs.io/en/latest/reference.html#greedy-usage) (Optional dependency, install via: `pip install brainles_preprocessing[picsl_greedy]`)
|
|
187
|
+
- [elastix](https://pypi.org/project/itk-elastix/0.13.0/) (Optional dependency, install via: `pip install brainles_preprocessing[itk-elastix]`)
|
|
188
|
+
|
|
189
|
+
As of now we do not offer inverse transforms for greedy and elastix. Please resort to ANTs or Niftyreg for this.
|
|
180
190
|
|
|
181
191
|
### Atlas Reference
|
|
182
|
-
We provide
|
|
183
|
-
|
|
192
|
+
We provide a range of different atlases, namely:
|
|
193
|
+
- [SRI24](https://www.nitrc.org/frs/download.php/4502/sri24_anatomy_unstripped_nifti.zip) and its [skull-stripped version](https://www.nitrc.org/frs/download.php/4499/sri24_anatomy_nifti.zip)
|
|
194
|
+
- A slightly modified SRI24 atlas as found in the BraTS challenges (also with a skull-stripped version)
|
|
195
|
+
- MNI152: [MNI_ICBM_2009c_Nonlinear_Symmetric](https://nist.mni.mcgill.ca/icbm-152-nonlinear-atlases-2009/)
|
|
196
|
+
- A slightly modified MNI152 atlas as found in the BraTS challenge
|
|
197
|
+
|
|
198
|
+
We also support supplying a custom atlas in NIfTI format
|
|
199
|
+
|
|
184
200
|
|
|
185
201
|
### N4 Bias correction
|
|
186
202
|
We currently provide support for N4 Bias correction based on [SimpleITK](https://simpleitk.org/)
|
|
187
203
|
|
|
188
204
|
### Brain extraction
|
|
189
|
-
We currently
|
|
205
|
+
We currently support:
|
|
206
|
+
- [HD-BET](https://github.com/MIC-DKFZ/HD-BET)
|
|
207
|
+
- [SynthStrip](https://surfer.nmr.mgh.harvard.edu/docs/synthstrip/) (Optional dependency, install via: `pip install brainles_preprocessing[synthstrip]`)
|
|
190
208
|
|
|
191
209
|
### Defacing
|
|
192
210
|
We currently provide support for [Quickshear](https://github.com/nipy/quickshear).
|
|
@@ -138,17 +138,33 @@ We provide a (WIP) documentation. Have a look [here](https://brainles-preprocess
|
|
|
138
138
|
Please credit the authors by citing their work.
|
|
139
139
|
|
|
140
140
|
### Registration
|
|
141
|
-
We currently
|
|
141
|
+
We currently fully support:
|
|
142
|
+
- [ANTs](https://github.com/ANTsX/ANTs) (default)
|
|
143
|
+
- [Niftyreg](https://github.com/KCL-BMEIS/niftyreg) (Linux)
|
|
144
|
+
|
|
145
|
+
We also offer basic support for:
|
|
146
|
+
- [greedy](https://greedy.readthedocs.io/en/latest/reference.html#greedy-usage) (Optional dependency, install via: `pip install brainles_preprocessing[picsl_greedy]`)
|
|
147
|
+
- [elastix](https://pypi.org/project/itk-elastix/0.13.0/) (Optional dependency, install via: `pip install brainles_preprocessing[itk-elastix]`)
|
|
148
|
+
|
|
149
|
+
As of now we do not offer inverse transforms for greedy and elastix. Please resort to ANTs or Niftyreg for this.
|
|
142
150
|
|
|
143
151
|
### Atlas Reference
|
|
144
|
-
We provide
|
|
145
|
-
|
|
152
|
+
We provide a range of different atlases, namely:
|
|
153
|
+
- [SRI24](https://www.nitrc.org/frs/download.php/4502/sri24_anatomy_unstripped_nifti.zip) and its [skull-stripped version](https://www.nitrc.org/frs/download.php/4499/sri24_anatomy_nifti.zip)
|
|
154
|
+
- A slightly modified SRI24 atlas as found in the BraTS challenges (also with a skull-stripped version)
|
|
155
|
+
- MNI152: [MNI_ICBM_2009c_Nonlinear_Symmetric](https://nist.mni.mcgill.ca/icbm-152-nonlinear-atlases-2009/)
|
|
156
|
+
- A slightly modified MNI152 atlas as found in the BraTS challenge
|
|
157
|
+
|
|
158
|
+
We also support supplying a custom atlas in NIfTI format
|
|
159
|
+
|
|
146
160
|
|
|
147
161
|
### N4 Bias correction
|
|
148
162
|
We currently provide support for N4 Bias correction based on [SimpleITK](https://simpleitk.org/)
|
|
149
163
|
|
|
150
164
|
### Brain extraction
|
|
151
|
-
We currently
|
|
165
|
+
We currently support:
|
|
166
|
+
- [HD-BET](https://github.com/MIC-DKFZ/HD-BET)
|
|
167
|
+
- [SynthStrip](https://surfer.nmr.mgh.harvard.edu/docs/synthstrip/) (Optional dependency, install via: `pip install brainles_preprocessing[synthstrip]`)
|
|
152
168
|
|
|
153
169
|
### Defacing
|
|
154
170
|
We currently provide support for [Quickshear](https://github.com/nipy/quickshear).
|
|
@@ -21,8 +21,6 @@ class BrainExtractor:
|
|
|
21
21
|
input_image_path: Union[str, Path],
|
|
22
22
|
masked_image_path: Union[str, Path],
|
|
23
23
|
brain_mask_path: Union[str, Path],
|
|
24
|
-
log_file_path: Optional[Union[str, Path]],
|
|
25
|
-
mode: Union[str, Mode],
|
|
26
24
|
**kwargs,
|
|
27
25
|
) -> None:
|
|
28
26
|
"""
|
|
@@ -32,7 +30,6 @@ class BrainExtractor:
|
|
|
32
30
|
input_image_path (str or Path): Path to the input image.
|
|
33
31
|
masked_image_path (str or Path): Path where the brain-extracted image will be saved.
|
|
34
32
|
brain_mask_path (str or Path): Path where the brain mask will be saved.
|
|
35
|
-
log_file_path (str or Path, Optional): Path to the log file.
|
|
36
33
|
mode (str or Mode): Extraction mode.
|
|
37
34
|
**kwargs: Additional keyword arguments.
|
|
38
35
|
"""
|
|
@@ -86,11 +83,10 @@ class HDBetExtractor(BrainExtractor):
|
|
|
86
83
|
input_image_path: Union[str, Path],
|
|
87
84
|
masked_image_path: Union[str, Path],
|
|
88
85
|
brain_mask_path: Union[str, Path],
|
|
89
|
-
log_file_path: Optional[Union[str, Path]] = None,
|
|
90
|
-
# TODO convert mode to enum
|
|
91
86
|
mode: Union[str, Mode] = Mode.ACCURATE,
|
|
92
87
|
device: Optional[Union[int, str]] = 0,
|
|
93
|
-
do_tta:
|
|
88
|
+
do_tta: bool = True,
|
|
89
|
+
**kwargs,
|
|
94
90
|
) -> None:
|
|
95
91
|
# GPU + accurate + TTA
|
|
96
92
|
"""
|
|
@@ -100,7 +96,6 @@ class HDBetExtractor(BrainExtractor):
|
|
|
100
96
|
input_image_path (str or Path): Path to the input image.
|
|
101
97
|
masked_image_path (str or Path): Path where the brain-extracted image will be saved.
|
|
102
98
|
brain_mask_path (str or Path): Path where the brain mask will be saved.
|
|
103
|
-
log_file_path (str or Path, Optional): Path to the log file.
|
|
104
99
|
mode (str or Mode): Extraction mode ('fast' or 'accurate').
|
|
105
100
|
device (str or int): Device to use for computation (e.g., 0 for GPU 0, 'cpu' for CPU).
|
|
106
101
|
do_tta (bool): whether to do test time data augmentation by mirroring along all axes.
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Modified from:
|
|
2
|
+
# https://github.com/nipreps/synthstrip/blob/main/nipreps/synthstrip/cli.py
|
|
3
|
+
# Original copyright (c) 2024, NiPreps developers
|
|
4
|
+
# Licensed under the Apache License, Version 2.0
|
|
5
|
+
# Changes made by the BrainLesion Preprocessing team (2025)
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Optional, Union, cast
|
|
9
|
+
|
|
10
|
+
import nibabel as nib
|
|
11
|
+
import numpy as np
|
|
12
|
+
import scipy
|
|
13
|
+
import torch
|
|
14
|
+
from nibabel.nifti1 import Nifti1Image
|
|
15
|
+
from nipreps.synthstrip.model import StripModel
|
|
16
|
+
from nitransforms.linear import Affine
|
|
17
|
+
|
|
18
|
+
from brainles_preprocessing.brain_extraction.brain_extractor import BrainExtractor
|
|
19
|
+
from brainles_preprocessing.utils.zenodo import fetch_synthstrip
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SynthStripExtractor(BrainExtractor):
|
|
23
|
+
|
|
24
|
+
def __init__(self, border: int = 1):
|
|
25
|
+
"""
|
|
26
|
+
Brain extraction using SynthStrip with preprocessing conforming to model requirements.
|
|
27
|
+
|
|
28
|
+
This is an optional dependency - to use this extractor, you need to install the `brainles_preprocessing` package with the `synthstrip` extra: `pip install brainles_preprocessing[synthstrip]`
|
|
29
|
+
|
|
30
|
+
Adapted from https://github.com/nipreps/synthstrip
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
border (int): Mask border threshold in mm. Defaults to 1.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
super().__init__()
|
|
37
|
+
self.border = border
|
|
38
|
+
|
|
39
|
+
def _setup_model(self, device: torch.device) -> StripModel:
|
|
40
|
+
"""
|
|
41
|
+
Load SynthStrip model and prepare it for inference on the specified device.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
device: Device to load the model onto.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
A configured and ready-to-use StripModel.
|
|
48
|
+
"""
|
|
49
|
+
# necessary for speed gains (according to original nipreps authors)
|
|
50
|
+
torch.backends.cudnn.benchmark = True
|
|
51
|
+
torch.backends.cudnn.deterministic = True
|
|
52
|
+
|
|
53
|
+
with torch.no_grad():
|
|
54
|
+
model = StripModel()
|
|
55
|
+
model.to(device)
|
|
56
|
+
model.eval()
|
|
57
|
+
|
|
58
|
+
# Load the model weights
|
|
59
|
+
weights_folder = fetch_synthstrip()
|
|
60
|
+
weights = weights_folder / "synthstrip.1.pt"
|
|
61
|
+
checkpoint = torch.load(weights, map_location=device)
|
|
62
|
+
model.load_state_dict(checkpoint["model_state_dict"])
|
|
63
|
+
|
|
64
|
+
return model
|
|
65
|
+
|
|
66
|
+
def _conform(self, input_nii: Nifti1Image) -> Nifti1Image:
|
|
67
|
+
"""
|
|
68
|
+
Resample the input image to match SynthStrip's expected input space.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
input_nii (Nifti1Image): Input NIfTI image to conform.
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
ValueError: If the input NIfTI image does not have a valid affine.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
A new NIfTI image with conformed shape and affine.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
shape = np.array(input_nii.shape[:3])
|
|
81
|
+
affine = input_nii.affine
|
|
82
|
+
|
|
83
|
+
if affine is None:
|
|
84
|
+
raise ValueError("Input NIfTI image must have a valid affine.")
|
|
85
|
+
|
|
86
|
+
# Get corner voxel centers in index coords
|
|
87
|
+
corner_centers_ijk = (
|
|
88
|
+
np.array(
|
|
89
|
+
[
|
|
90
|
+
(i, j, k)
|
|
91
|
+
for k in (0, shape[2] - 1)
|
|
92
|
+
for j in (0, shape[1] - 1)
|
|
93
|
+
for i in (0, shape[0] - 1)
|
|
94
|
+
]
|
|
95
|
+
)
|
|
96
|
+
+ 0.5
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Get corner voxel centers in mm
|
|
100
|
+
corners_xyz = (
|
|
101
|
+
affine
|
|
102
|
+
@ np.hstack((corner_centers_ijk, np.ones((len(corner_centers_ijk), 1)))).T
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# Target affine is 1mm voxels in LIA orientation
|
|
106
|
+
target_affine = np.diag([-1.0, 1.0, -1.0, 1.0])[:, (0, 2, 1, 3)]
|
|
107
|
+
|
|
108
|
+
# Target shape
|
|
109
|
+
extent = corners_xyz.min(1)[:3], corners_xyz.max(1)[:3]
|
|
110
|
+
target_shape = ((extent[1] - extent[0]) / 1.0 + 0.999).astype(int)
|
|
111
|
+
|
|
112
|
+
# SynthStrip likes dimensions be multiple of 64 (192, 256, or 320)
|
|
113
|
+
target_shape = np.clip(
|
|
114
|
+
np.ceil(np.array(target_shape) / 64).astype(int) * 64, 192, 320
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Ensure shape ordering is LIA too
|
|
118
|
+
target_shape[2], target_shape[1] = target_shape[1:3]
|
|
119
|
+
|
|
120
|
+
# Coordinates of center voxel do not change
|
|
121
|
+
input_c = affine @ np.hstack((0.5 * (shape - 1), 1.0))
|
|
122
|
+
target_c = target_affine @ np.hstack((0.5 * (target_shape - 1), 1.0))
|
|
123
|
+
|
|
124
|
+
# Rebase the origin of the new, plumb affine
|
|
125
|
+
target_affine[:3, 3] -= target_c[:3] - input_c[:3]
|
|
126
|
+
|
|
127
|
+
nii = Affine(
|
|
128
|
+
reference=Nifti1Image(
|
|
129
|
+
np.zeros(target_shape),
|
|
130
|
+
target_affine,
|
|
131
|
+
None,
|
|
132
|
+
),
|
|
133
|
+
).apply(input_nii)
|
|
134
|
+
return cast(Nifti1Image, nii)
|
|
135
|
+
|
|
136
|
+
def _resample_like(
|
|
137
|
+
self,
|
|
138
|
+
image: Nifti1Image,
|
|
139
|
+
target: Nifti1Image,
|
|
140
|
+
output_dtype: Optional[np.dtype] = None,
|
|
141
|
+
cval: Union[int, float] = 0,
|
|
142
|
+
) -> Nifti1Image:
|
|
143
|
+
"""
|
|
144
|
+
Resample the input image to match the target's grid using an identity transform.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
image: The image to be resampled.
|
|
148
|
+
target: The reference image.
|
|
149
|
+
output_dtype: Output data type.
|
|
150
|
+
cval: Value to use for constant padding.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
A resampled NIfTI image.
|
|
154
|
+
"""
|
|
155
|
+
result = Affine(reference=target).apply(
|
|
156
|
+
image,
|
|
157
|
+
output_dtype=output_dtype,
|
|
158
|
+
cval=cval,
|
|
159
|
+
)
|
|
160
|
+
return cast(Nifti1Image, result)
|
|
161
|
+
|
|
162
|
+
def extract(
|
|
163
|
+
self,
|
|
164
|
+
input_image_path: Union[str, Path],
|
|
165
|
+
masked_image_path: Union[str, Path],
|
|
166
|
+
brain_mask_path: Union[str, Path],
|
|
167
|
+
device: Union[torch.device, str] = "cuda",
|
|
168
|
+
num_threads: int = 1,
|
|
169
|
+
**kwargs,
|
|
170
|
+
) -> None:
|
|
171
|
+
"""
|
|
172
|
+
Extract the brain from an input image using SynthStrip.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
input_image_path (Union[str, Path]): Path to the input image.
|
|
176
|
+
masked_image_path (Union[str, Path]): Path to the output masked image.
|
|
177
|
+
brain_mask_path (Union[str, Path]): Path to the output brain mask.
|
|
178
|
+
device (Union[torch.device, str], optional): Device to use for computation. Defaults to "cuda".
|
|
179
|
+
num_threads (int, optional): Number of threads to use for computation in CPU mode. Defaults to 1.
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
None: The function saves the masked image and brain mask to the specified paths.
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
device = torch.device(device) if isinstance(device, str) else device
|
|
186
|
+
model = self._setup_model(device=device)
|
|
187
|
+
|
|
188
|
+
if device.type == "cpu" and num_threads > 0:
|
|
189
|
+
torch.set_num_threads(num_threads)
|
|
190
|
+
|
|
191
|
+
# normalize intensities
|
|
192
|
+
image = nib.load(input_image_path)
|
|
193
|
+
image = cast(Nifti1Image, image)
|
|
194
|
+
conformed = self._conform(image)
|
|
195
|
+
in_data = conformed.get_fdata(dtype="float32")
|
|
196
|
+
in_data -= in_data.min()
|
|
197
|
+
in_data = np.clip(in_data / np.percentile(in_data, 99), 0, 1)
|
|
198
|
+
in_data = in_data[np.newaxis, np.newaxis]
|
|
199
|
+
|
|
200
|
+
# predict the surface distance transform
|
|
201
|
+
input_tensor = torch.from_numpy(in_data).to(device)
|
|
202
|
+
with torch.no_grad():
|
|
203
|
+
sdt = model(input_tensor).cpu().numpy().squeeze()
|
|
204
|
+
|
|
205
|
+
# unconform the sdt and extract mask
|
|
206
|
+
sdt_target = self._resample_like(
|
|
207
|
+
Nifti1Image(sdt, conformed.affine, None),
|
|
208
|
+
image,
|
|
209
|
+
output_dtype=np.dtype("int16"),
|
|
210
|
+
cval=100,
|
|
211
|
+
)
|
|
212
|
+
sdt_data = np.asanyarray(sdt_target.dataobj).astype("int16")
|
|
213
|
+
|
|
214
|
+
# find largest CC (just do this to be safe for now)
|
|
215
|
+
components = scipy.ndimage.label(sdt_data.squeeze() < self.border)[0]
|
|
216
|
+
bincount = np.bincount(components.flatten())[1:]
|
|
217
|
+
mask = components == (np.argmax(bincount) + 1)
|
|
218
|
+
mask = scipy.ndimage.morphology.binary_fill_holes(mask)
|
|
219
|
+
|
|
220
|
+
# write the masked output
|
|
221
|
+
img_data = image.get_fdata()
|
|
222
|
+
bg = np.min([0, img_data.min()])
|
|
223
|
+
img_data[mask == 0] = bg
|
|
224
|
+
Nifti1Image(img_data, image.affine, image.header).to_filename(
|
|
225
|
+
masked_image_path,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
# write the brain mask
|
|
229
|
+
hdr = image.header.copy()
|
|
230
|
+
hdr.set_data_dtype("uint8")
|
|
231
|
+
Nifti1Image(mask, image.affine, hdr).to_filename(brain_mask_path)
|
{brainles_preprocessing-0.6.0 → brainles_preprocessing-0.6.2}/brainles_preprocessing/modality.py
RENAMED
|
@@ -4,7 +4,9 @@ import warnings
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Dict, Optional, Union
|
|
6
6
|
|
|
7
|
+
import torch
|
|
7
8
|
from auxiliary.io import read_image, write_image
|
|
9
|
+
from loguru import logger
|
|
8
10
|
|
|
9
11
|
from brainles_preprocessing.brain_extraction.brain_extractor import BrainExtractor
|
|
10
12
|
from brainles_preprocessing.constants import Atlas, PreprocessorSteps
|
|
@@ -15,9 +17,7 @@ from brainles_preprocessing.registration import ( # TODO: this will throw warni
|
|
|
15
17
|
NiftyRegRegistrator,
|
|
16
18
|
)
|
|
17
19
|
from brainles_preprocessing.registration.registrator import Registrator
|
|
18
|
-
from brainles_preprocessing.utils.zenodo import
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
20
|
+
from brainles_preprocessing.utils.zenodo import fetch_atlases
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class Modality:
|
|
@@ -599,6 +599,7 @@ class CenterModality(Modality):
|
|
|
599
599
|
self,
|
|
600
600
|
brain_extractor: BrainExtractor,
|
|
601
601
|
bet_dir_path: Union[str, Path],
|
|
602
|
+
use_gpu: bool = True,
|
|
602
603
|
) -> Path:
|
|
603
604
|
"""
|
|
604
605
|
|
|
@@ -607,6 +608,7 @@ class CenterModality(Modality):
|
|
|
607
608
|
Args:
|
|
608
609
|
brain_extractor (BrainExtractor): The brain extractor object.
|
|
609
610
|
bet_dir_path (str or Path): Directory to store brain extraction results.
|
|
611
|
+
use_gpu (bool): Whether to use GPU for brain extraction if available.
|
|
610
612
|
|
|
611
613
|
Returns:
|
|
612
614
|
Path: Path to the extracted brain mask.
|
|
@@ -618,11 +620,16 @@ class CenterModality(Modality):
|
|
|
618
620
|
bet = bet_dir_path / f"{self.modality_name}_bet.nii.gz"
|
|
619
621
|
mask_path = bet_dir_path / f"{self.modality_name}_brain_mask.nii.gz"
|
|
620
622
|
|
|
623
|
+
device = torch.device(
|
|
624
|
+
"cuda" if use_gpu and torch.cuda.is_available() else "cpu"
|
|
625
|
+
)
|
|
626
|
+
|
|
621
627
|
brain_extractor.extract(
|
|
622
628
|
input_image_path=self.current,
|
|
623
629
|
masked_image_path=bet,
|
|
624
630
|
brain_mask_path=mask_path,
|
|
625
631
|
log_file_path=bet_log,
|
|
632
|
+
device=device,
|
|
626
633
|
)
|
|
627
634
|
|
|
628
635
|
# always temporarily store bet image for center modality, since e.g. quickshear defacing could require it
|
|
@@ -667,7 +674,7 @@ class CenterModality(Modality):
|
|
|
667
674
|
|
|
668
675
|
# resolve atlas image path
|
|
669
676
|
if isinstance(defacer.atlas_image_path, Atlas):
|
|
670
|
-
atlas_folder =
|
|
677
|
+
atlas_folder = fetch_atlases()
|
|
671
678
|
atlas_image_path = atlas_folder / defacer.atlas_image_path.value
|
|
672
679
|
else:
|
|
673
680
|
atlas_image_path = Path(defacer.atlas_image_path)
|
|
@@ -2,6 +2,8 @@ import shutil
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from typing import List, Optional, Union
|
|
4
4
|
|
|
5
|
+
from loguru import logger
|
|
6
|
+
|
|
5
7
|
from brainles_preprocessing.brain_extraction.brain_extractor import BrainExtractor
|
|
6
8
|
from brainles_preprocessing.constants import Atlas, PreprocessorSteps
|
|
7
9
|
from brainles_preprocessing.defacing import Defacer, QuickshearDefacer
|
|
@@ -9,11 +11,7 @@ from brainles_preprocessing.modality import CenterModality, Modality
|
|
|
9
11
|
from brainles_preprocessing.n4_bias_correction import N4BiasCorrector
|
|
10
12
|
from brainles_preprocessing.preprocessor.preprocessor import BasePreprocessor
|
|
11
13
|
from brainles_preprocessing.registration.registrator import Registrator
|
|
12
|
-
from brainles_preprocessing.utils.
|
|
13
|
-
from brainles_preprocessing.utils.zenodo import verify_or_download_atlases
|
|
14
|
-
|
|
15
|
-
logging_man = LoggingManager(name=__name__)
|
|
16
|
-
logger = logging_man.get_logger()
|
|
14
|
+
from brainles_preprocessing.utils.zenodo import fetch_atlases
|
|
17
15
|
|
|
18
16
|
|
|
19
17
|
class AtlasCentricPreprocessor(BasePreprocessor):
|
|
@@ -44,7 +42,7 @@ class AtlasCentricPreprocessor(BasePreprocessor):
|
|
|
44
42
|
atlas_image_path: Union[str, Path, Atlas] = Atlas.BRATS_SRI24,
|
|
45
43
|
n4_bias_corrector: Optional[N4BiasCorrector] = None,
|
|
46
44
|
temp_folder: Optional[Union[str, Path]] = None,
|
|
47
|
-
use_gpu:
|
|
45
|
+
use_gpu: bool = True,
|
|
48
46
|
limit_cuda_visible_devices: Optional[str] = None,
|
|
49
47
|
):
|
|
50
48
|
super().__init__(
|
|
@@ -60,7 +58,7 @@ class AtlasCentricPreprocessor(BasePreprocessor):
|
|
|
60
58
|
)
|
|
61
59
|
|
|
62
60
|
if isinstance(atlas_image_path, Atlas):
|
|
63
|
-
atlas_folder =
|
|
61
|
+
atlas_folder = fetch_atlases()
|
|
64
62
|
self.atlas_image_path = atlas_folder / atlas_image_path.value
|
|
65
63
|
else:
|
|
66
64
|
self.atlas_image_path = Path(atlas_image_path)
|
|
@@ -101,97 +99,102 @@ class AtlasCentricPreprocessor(BasePreprocessor):
|
|
|
101
99
|
Results are saved in the specified directories, allowing for modular and configurable output storage.
|
|
102
100
|
"""
|
|
103
101
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
# Co-register moving modalities to center modality
|
|
116
|
-
logger.info(f"{' Starting Coregistration ':-^80}")
|
|
117
|
-
self.run_coregistration(
|
|
118
|
-
save_dir_coregistration=save_dir_coregistration,
|
|
119
|
-
)
|
|
120
|
-
logger.info(
|
|
121
|
-
f"Coregistration complete. Output saved to {save_dir_coregistration}"
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
# Register center modality to atlas
|
|
125
|
-
logger.info(f"{' Starting atlas registration ':-^80}")
|
|
126
|
-
self.run_atlas_registration(
|
|
127
|
-
save_dir_atlas_registration=save_dir_atlas_registration,
|
|
128
|
-
)
|
|
129
|
-
logger.info(
|
|
130
|
-
f"Transformations complete. Output saved to {save_dir_atlas_registration}"
|
|
131
|
-
)
|
|
102
|
+
logger_id = self._add_log_file_handler(log_file)
|
|
103
|
+
try:
|
|
104
|
+
logger.info(f"{' Starting preprocessing ':=^80}")
|
|
105
|
+
modality_names = ", ".join(
|
|
106
|
+
[modality.modality_name for modality in self.moving_modalities]
|
|
107
|
+
)
|
|
108
|
+
logger.info(
|
|
109
|
+
f"Received center modality: {self.center_modality.modality_name} "
|
|
110
|
+
f"and moving modalities: {modality_names}"
|
|
111
|
+
)
|
|
132
112
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
113
|
+
# Co-register moving modalities to center modality
|
|
114
|
+
logger.info(f"{' Starting Coregistration ':-^80}")
|
|
115
|
+
self.run_coregistration(
|
|
116
|
+
save_dir_coregistration=save_dir_coregistration,
|
|
117
|
+
)
|
|
118
|
+
logger.info(
|
|
119
|
+
f"Coregistration complete. Output saved to {save_dir_coregistration}"
|
|
120
|
+
)
|
|
138
121
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
122
|
+
# Register center modality to atlas
|
|
123
|
+
logger.info(f"{' Starting atlas registration ':-^80}")
|
|
124
|
+
self.run_atlas_registration(
|
|
125
|
+
save_dir_atlas_registration=save_dir_atlas_registration,
|
|
126
|
+
)
|
|
127
|
+
logger.info(
|
|
128
|
+
f"Transformations complete. Output saved to {save_dir_atlas_registration}"
|
|
129
|
+
)
|
|
144
130
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
modality.raw_skull_output_path,
|
|
151
|
-
normalization=False,
|
|
152
|
-
)
|
|
153
|
-
if modality.normalized_skull_output_path:
|
|
154
|
-
modality.save_current_image(
|
|
155
|
-
modality.normalized_skull_output_path,
|
|
156
|
-
normalization=True,
|
|
157
|
-
)
|
|
131
|
+
# Optional: additional correction in atlas space
|
|
132
|
+
logger.info(f"{' Checking optional atlas correction ':-^80}")
|
|
133
|
+
self.run_atlas_correction(
|
|
134
|
+
save_dir_atlas_correction=save_dir_atlas_correction,
|
|
135
|
+
)
|
|
158
136
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
137
|
+
# Optional: N4 bias correction
|
|
138
|
+
logger.info(f"{' Checking optional N4 bias correction ':-^80}")
|
|
139
|
+
self.run_n4_bias_correction(
|
|
140
|
+
save_dir_n4_bias_correction=save_dir_n4_bias_correction,
|
|
141
|
+
)
|
|
164
142
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
143
|
+
# Now we save images that are not skullstripped (current image = atlas registered or atlas registered + corrected)
|
|
144
|
+
logger.info("Saving non skull-stripped images...")
|
|
145
|
+
for modality in self.all_modalities:
|
|
146
|
+
if modality.raw_skull_output_path:
|
|
147
|
+
modality.save_current_image(
|
|
148
|
+
modality.raw_skull_output_path,
|
|
149
|
+
normalization=False,
|
|
150
|
+
)
|
|
151
|
+
if modality.normalized_skull_output_path:
|
|
152
|
+
modality.save_current_image(
|
|
153
|
+
modality.normalized_skull_output_path,
|
|
154
|
+
normalization=True,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Optional: Brain extraction
|
|
158
|
+
logger.info(f"{' Checking optional brain extraction ':-^80}")
|
|
159
|
+
self.run_brain_extraction(
|
|
160
|
+
save_dir_brain_extraction=save_dir_brain_extraction,
|
|
161
|
+
)
|
|
170
162
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
163
|
+
# Defacing
|
|
164
|
+
logger.info(f"{' Checking optional defacing ':-^80}")
|
|
165
|
+
self.run_defacing(
|
|
166
|
+
save_dir_defacing=save_dir_defacing,
|
|
167
|
+
)
|
|
174
168
|
|
|
175
|
-
#
|
|
176
|
-
|
|
177
|
-
|
|
169
|
+
# move to separate method
|
|
170
|
+
if save_dir_transformations:
|
|
171
|
+
save_dir_transformations = Path(save_dir_transformations)
|
|
178
172
|
|
|
179
|
-
|
|
180
|
-
|
|
173
|
+
# Save transformation matrices
|
|
174
|
+
logger.info(
|
|
175
|
+
f"Saving transformation matrices to {save_dir_transformations}"
|
|
181
176
|
)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
177
|
+
for modality in self.all_modalities:
|
|
178
|
+
|
|
179
|
+
modality_transformations_dir = (
|
|
180
|
+
save_dir_transformations / modality.modality_name
|
|
181
|
+
)
|
|
182
|
+
modality_transformations_dir.mkdir(exist_ok=True, parents=True)
|
|
183
|
+
for step, path in modality.transformation_paths.items():
|
|
184
|
+
if path is not None:
|
|
185
|
+
shutil.copyfile(
|
|
186
|
+
src=str(path.absolute()),
|
|
187
|
+
dst=str(
|
|
188
|
+
modality_transformations_dir
|
|
189
|
+
/ f"{step.value}_{path.name}"
|
|
190
|
+
),
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
# End
|
|
194
|
+
logger.info(f"{' Preprocessing complete ':=^80}")
|
|
195
|
+
finally:
|
|
196
|
+
# Remove log file handler if it was added
|
|
197
|
+
logger.remove(logger_id)
|
|
195
198
|
|
|
196
199
|
def run_atlas_registration(
|
|
197
200
|
self, save_dir_atlas_registration: Optional[Union[str, Path]] = None
|