From b50cab006c33cc19c6d430b55650b3e270f3b6ef Mon Sep 17 00:00:00 2001 From: dbouget Date: Tue, 16 Dec 2025 10:37:29 +0000 Subject: [PATCH 1/6] Enforcing unit8 and float32 types in the prediction files --- pyproject.toml | 2 +- raidionicsseg/Utils/io.py | 8 ++++++++ .../test_inference_segmentation_reconstruction.py | 1 + tests/generic_tests/test_inference_segmentation_simple.py | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 565715f..11de846 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "raidionicsseg" -version = "1.5.0" +version = "1.5.1" description = "Raidionics segmentation and classification back-end with ONNX runtime" readme = "README.md" license = { text = "BSD-2-Clause" } diff --git a/raidionicsseg/Utils/io.py b/raidionicsseg/Utils/io.py index 83b3c39..ed6b739 100644 --- a/raidionicsseg/Utils/io.py +++ b/raidionicsseg/Utils/io.py @@ -58,11 +58,19 @@ def dump_predictions( first_class = 0 if parameters.training_activation_layer_type == "sigmoid" else 1 for c in range(first_class, predictions.shape[-1]): img = nib.Nifti1Image(predictions[..., c], affine=nib_volume.affine, header=nib_volume.header) + if parameters.predictions_reconstruction_method != "probabilities": + img.header.set_data_dtype(np.uint8) + else: + img.header.set_data_dtype(np.float32) predictions_output_path = os.path.join(storage_path, naming_suffix + "_" + class_names[c] + ".nii.gz") os.makedirs(os.path.dirname(predictions_output_path), exist_ok=True) nib.save(img, predictions_output_path) else: img = nib.Nifti1Image(predictions, affine=nib_volume.affine, header=nib_volume.header) + if parameters.predictions_reconstruction_method != "probabilities": + img.header.set_data_dtype(np.uint8) + else: + img.header.set_data_dtype(np.float32) predictions_output_path = os.path.join(storage_path, naming_suffix + "_" + "argmax" + ".nii.gz") os.makedirs(os.path.dirname(predictions_output_path), exist_ok=True) nib.save(img, predictions_output_path) diff --git a/tests/generic_tests/test_inference_segmentation_reconstruction.py b/tests/generic_tests/test_inference_segmentation_reconstruction.py index 04522e9..bbc9fee 100644 --- a/tests/generic_tests/test_inference_segmentation_reconstruction.py +++ b/tests/generic_tests/test_inference_segmentation_reconstruction.py @@ -148,6 +148,7 @@ def test_inference_segmentation_reconstruction_method(test_dir, tmp_path): segmentation_gt_nib.header.get_zooms()[0:3]) * 1e-3 logging.info(f"Volume difference: {abs(pred_volume - gt_volume)}\n") assert abs(pred_volume - gt_volume) < 0.1, "Ground truth and prediction volumes are very different" + assert pred_volume.dtype == np.float32, "Predictions is not of type float32" except Exception as e: logging.error(f"Error during inference Python package test with: {e} \n {traceback.format_exc()}.\n") if os.path.exists(tmp_test_input_fn): diff --git a/tests/generic_tests/test_inference_segmentation_simple.py b/tests/generic_tests/test_inference_segmentation_simple.py index 82af699..fcee390 100644 --- a/tests/generic_tests/test_inference_segmentation_simple.py +++ b/tests/generic_tests/test_inference_segmentation_simple.py @@ -87,6 +87,7 @@ def test_inference_cli(test_dir, tmp_path): segmentation_gt = nib.load(segmentation_gt_filename).get_fdata()[:] assert np.array_equal(segmentation_pred, segmentation_gt), "Ground truth and prediction arrays are not identical" + assert segmentation_pred.dtype == np.uint8, "Tresholded predictions is not of type unit8" except Exception as e: logging.error(f"Error during inference CLI test with: {e}\n {traceback.format_exc()}.\n") raise ValueError("Error during inference CLI test.\n") From d8a3725cbb59f3e6ec1f9dc24be79bd724bf29a9 Mon Sep 17 00:00:00 2001 From: dbouget Date: Tue, 16 Dec 2025 11:57:19 +0000 Subject: [PATCH 2/6] Enforcing unit8 and float32 types in the prediction files [skip ci] --- raidionicsseg/Utils/io.py | 18 +++++++----------- .../test_inference_segmentation_simple.py | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/raidionicsseg/Utils/io.py b/raidionicsseg/Utils/io.py index ed6b739..45f470d 100644 --- a/raidionicsseg/Utils/io.py +++ b/raidionicsseg/Utils/io.py @@ -53,24 +53,20 @@ def dump_predictions( try: naming_suffix = "pred" if parameters.predictions_reconstruction_method == "probabilities" else "labels" class_names = parameters.training_class_names - + modified_header = nib_volume.header.copy() + if parameters.predictions_reconstruction_method != "probabilities": + modified_header.set_data_dtype(np.uint8) + else: + modified_header.set_data_dtype(np.float32) if len(predictions.shape) == 4: first_class = 0 if parameters.training_activation_layer_type == "sigmoid" else 1 for c in range(first_class, predictions.shape[-1]): - img = nib.Nifti1Image(predictions[..., c], affine=nib_volume.affine, header=nib_volume.header) - if parameters.predictions_reconstruction_method != "probabilities": - img.header.set_data_dtype(np.uint8) - else: - img.header.set_data_dtype(np.float32) + img = nib.Nifti1Image(predictions[..., c], affine=nib_volume.affine, header=modified_header) predictions_output_path = os.path.join(storage_path, naming_suffix + "_" + class_names[c] + ".nii.gz") os.makedirs(os.path.dirname(predictions_output_path), exist_ok=True) nib.save(img, predictions_output_path) else: - img = nib.Nifti1Image(predictions, affine=nib_volume.affine, header=nib_volume.header) - if parameters.predictions_reconstruction_method != "probabilities": - img.header.set_data_dtype(np.uint8) - else: - img.header.set_data_dtype(np.float32) + img = nib.Nifti1Image(predictions, affine=nib_volume.affine, header=modified_header) predictions_output_path = os.path.join(storage_path, naming_suffix + "_" + "argmax" + ".nii.gz") os.makedirs(os.path.dirname(predictions_output_path), exist_ok=True) nib.save(img, predictions_output_path) diff --git a/tests/generic_tests/test_inference_segmentation_simple.py b/tests/generic_tests/test_inference_segmentation_simple.py index fcee390..aa0eb43 100644 --- a/tests/generic_tests/test_inference_segmentation_simple.py +++ b/tests/generic_tests/test_inference_segmentation_simple.py @@ -87,7 +87,7 @@ def test_inference_cli(test_dir, tmp_path): segmentation_gt = nib.load(segmentation_gt_filename).get_fdata()[:] assert np.array_equal(segmentation_pred, segmentation_gt), "Ground truth and prediction arrays are not identical" - assert segmentation_pred.dtype == np.uint8, "Tresholded predictions is not of type unit8" + assert segmentation_pred.dtype == np.uint8, "Tresholded predictions is not of type uint8" except Exception as e: logging.error(f"Error during inference CLI test with: {e}\n {traceback.format_exc()}.\n") raise ValueError("Error during inference CLI test.\n") From d3a503aa0b5414765b4649b22ae95e696999bcb6 Mon Sep 17 00:00:00 2001 From: dbouget Date: Tue, 16 Dec 2025 12:39:17 +0000 Subject: [PATCH 3/6] Enforcing unit8 and float32 types in the prediction files [skip ci] --- raidionicsseg/Utils/io.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/raidionicsseg/Utils/io.py b/raidionicsseg/Utils/io.py index 45f470d..711adb8 100644 --- a/raidionicsseg/Utils/io.py +++ b/raidionicsseg/Utils/io.py @@ -56,8 +56,10 @@ def dump_predictions( modified_header = nib_volume.header.copy() if parameters.predictions_reconstruction_method != "probabilities": modified_header.set_data_dtype(np.uint8) + assert predictions.dtype == np.uint8 else: modified_header.set_data_dtype(np.float32) + assert predictions.dtype == np.float32 if len(predictions.shape) == 4: first_class = 0 if parameters.training_activation_layer_type == "sigmoid" else 1 for c in range(first_class, predictions.shape[-1]): From 8c4920a4bb7407d6796fec24b9a079aa3101d816 Mon Sep 17 00:00:00 2001 From: dbouget Date: Tue, 16 Dec 2025 13:02:16 +0000 Subject: [PATCH 4/6] Enforcing unit8 and float32 types in the prediction files [skip ci] --- raidionicsseg/Utils/io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/raidionicsseg/Utils/io.py b/raidionicsseg/Utils/io.py index 711adb8..35923c5 100644 --- a/raidionicsseg/Utils/io.py +++ b/raidionicsseg/Utils/io.py @@ -63,12 +63,12 @@ def dump_predictions( if len(predictions.shape) == 4: first_class = 0 if parameters.training_activation_layer_type == "sigmoid" else 1 for c in range(first_class, predictions.shape[-1]): - img = nib.Nifti1Image(predictions[..., c], affine=nib_volume.affine, header=modified_header) + img = nib.Nifti1Image(predictions[..., c], affine=nib_volume.affine) predictions_output_path = os.path.join(storage_path, naming_suffix + "_" + class_names[c] + ".nii.gz") os.makedirs(os.path.dirname(predictions_output_path), exist_ok=True) nib.save(img, predictions_output_path) else: - img = nib.Nifti1Image(predictions, affine=nib_volume.affine, header=modified_header) + img = nib.Nifti1Image(predictions, affine=nib_volume.affine) predictions_output_path = os.path.join(storage_path, naming_suffix + "_" + "argmax" + ".nii.gz") os.makedirs(os.path.dirname(predictions_output_path), exist_ok=True) nib.save(img, predictions_output_path) From 6024fa0f764193a8e3ebbec59a5d7d8888ae1476 Mon Sep 17 00:00:00 2001 From: dbouget Date: Tue, 16 Dec 2025 13:14:53 +0000 Subject: [PATCH 5/6] Enforcing unit8 and float32 types in the prediction files [skip ci] --- raidionicsseg/Utils/io.py | 4 ++-- tests/generic_tests/test_inference_segmentation_simple.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/raidionicsseg/Utils/io.py b/raidionicsseg/Utils/io.py index 35923c5..711adb8 100644 --- a/raidionicsseg/Utils/io.py +++ b/raidionicsseg/Utils/io.py @@ -63,12 +63,12 @@ def dump_predictions( if len(predictions.shape) == 4: first_class = 0 if parameters.training_activation_layer_type == "sigmoid" else 1 for c in range(first_class, predictions.shape[-1]): - img = nib.Nifti1Image(predictions[..., c], affine=nib_volume.affine) + img = nib.Nifti1Image(predictions[..., c], affine=nib_volume.affine, header=modified_header) predictions_output_path = os.path.join(storage_path, naming_suffix + "_" + class_names[c] + ".nii.gz") os.makedirs(os.path.dirname(predictions_output_path), exist_ok=True) nib.save(img, predictions_output_path) else: - img = nib.Nifti1Image(predictions, affine=nib_volume.affine) + img = nib.Nifti1Image(predictions, affine=nib_volume.affine, header=modified_header) predictions_output_path = os.path.join(storage_path, naming_suffix + "_" + "argmax" + ".nii.gz") os.makedirs(os.path.dirname(predictions_output_path), exist_ok=True) nib.save(img, predictions_output_path) diff --git a/tests/generic_tests/test_inference_segmentation_simple.py b/tests/generic_tests/test_inference_segmentation_simple.py index aa0eb43..48ac419 100644 --- a/tests/generic_tests/test_inference_segmentation_simple.py +++ b/tests/generic_tests/test_inference_segmentation_simple.py @@ -87,7 +87,7 @@ def test_inference_cli(test_dir, tmp_path): segmentation_gt = nib.load(segmentation_gt_filename).get_fdata()[:] assert np.array_equal(segmentation_pred, segmentation_gt), "Ground truth and prediction arrays are not identical" - assert segmentation_pred.dtype == np.uint8, "Tresholded predictions is not of type uint8" + assert nib.load(segmentation_pred_filename).get_data_dtype() == np.uint8, "Tresholded predictions is not of type uint8" except Exception as e: logging.error(f"Error during inference CLI test with: {e}\n {traceback.format_exc()}.\n") raise ValueError("Error during inference CLI test.\n") @@ -156,6 +156,8 @@ def test_inference_package(test_dir, tmp_path): segmentation_pred = nib.load(segmentation_pred_filename).get_fdata()[:] segmentation_gt = nib.load(segmentation_gt_filename).get_fdata()[:] assert np.array_equal(segmentation_pred, segmentation_gt), "Ground truth and prediction arrays are not identical" + assert nib.load( + segmentation_pred_filename).get_data_dtype() == np.uint8, "Tresholded predictions is not of type uint8" except Exception as e: logging.error(f"Error during inference Python package test with: {e} \n {traceback.format_exc()}.\n") if os.path.exists(tmp_test_input_fn): From 7ef94f3a05a1aba79fded805450ec2cb3d46f9d7 Mon Sep 17 00:00:00 2001 From: dbouget Date: Tue, 16 Dec 2025 13:15:52 +0000 Subject: [PATCH 6/6] Enforcing unit8 and float32 types in the prediction files [skip ci] --- .../generic_tests/test_inference_segmentation_reconstruction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/generic_tests/test_inference_segmentation_reconstruction.py b/tests/generic_tests/test_inference_segmentation_reconstruction.py index bbc9fee..6798ac2 100644 --- a/tests/generic_tests/test_inference_segmentation_reconstruction.py +++ b/tests/generic_tests/test_inference_segmentation_reconstruction.py @@ -148,7 +148,7 @@ def test_inference_segmentation_reconstruction_method(test_dir, tmp_path): segmentation_gt_nib.header.get_zooms()[0:3]) * 1e-3 logging.info(f"Volume difference: {abs(pred_volume - gt_volume)}\n") assert abs(pred_volume - gt_volume) < 0.1, "Ground truth and prediction volumes are very different" - assert pred_volume.dtype == np.float32, "Predictions is not of type float32" + assert segmentation_pred_nib.get_data_dtype() == np.float32, "Predictions is not of type float32" except Exception as e: logging.error(f"Error during inference Python package test with: {e} \n {traceback.format_exc()}.\n") if os.path.exists(tmp_test_input_fn):