Skip to content

Commit

Permalink
fix: adapt the filenames of the predictions in pred_masks as per targ…
Browse files Browse the repository at this point in the history
…et_suffix (#1173)

Fixes #1135

Currently, `--test` command doesn't support multiple annotations for 
the ground truth. So, adding a test to document this behaviour.

Co-authored-by: mariehbourget <54086142+mariehbourget@users.noreply.github.com>
  • Loading branch information
kanishk16 and mariehbourget committed Jun 28, 2022
1 parent b9a208d commit c9e69c9
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 2 deletions.
2 changes: 1 addition & 1 deletion ivadomed/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def check_multiple_raters(is_train, loader_params):
if not is_train:
logger.error(
"Please provide only one annotation per class in 'target_suffix' when not training a model.\n")
exit()
sys.exit()


def film_normalize_data(context, model_params, ds_train, ds_valid, path_output):
Expand Down
2 changes: 1 addition & 1 deletion ivadomed/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def run_inference(test_loader, model, model_params, testing_params, ofolder, cud
# save the completely processed file as a NifTI file
if ofolder:
fname_pred = str(Path(ofolder, Path(fname_ref).name))
fname_pred = fname_pred.rsplit("_", 1)[0] + '_pred.nii.gz'
fname_pred = fname_pred.split(testing_params['target_suffix'][0])[0] + '_pred.nii.gz'
# If Uncertainty running, then we save each simulation result
if testing_params['uncertainty']['applied']:
fname_pred = fname_pred.split('.nii.gz')[0] + '_' + str(i_monte_carlo).zfill(2) + '.nii.gz'
Expand Down
14 changes: 14 additions & 0 deletions testing/unit_tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest

from ivadomed.main import check_multiple_raters

@pytest.mark.parametrize(
'is_train, loader_params', [
(False, {"target_suffix":
[["_seg-axon-manual1", "_seg-axon-manual2"],
["_seg-myelin-manual1", "_seg-myelin-manual2"]]
})
])
def test_check_multiple_raters(is_train, loader_params):
with pytest.raises(SystemExit):
check_multiple_raters(is_train, loader_params)
95 changes: 95 additions & 0 deletions testing/unit_tests/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,5 +211,100 @@ def test_inference_2d_microscopy(download_data_testing_test_files, transforms_di
assert len([x for x in __output_dir__.iterdir() if x.name.endswith(".png")]) == 2*len(test_lst)


@pytest.mark.parametrize('transforms_dict', [{
"CenterCrop": {
"size": [128, 128]
},
"NormalizeInstance": {"applied_to": ["im"]}
}])
@pytest.mark.parametrize('test_lst',
[['sub-rat3_ses-01_sample-data9_SEM.png', 'sub-rat3_ses-02_sample-data10_SEM.png']])
@pytest.mark.parametrize('target_lst', [["_seg-axon_manual", "_seg-myelin_manual"]])
@pytest.mark.parametrize('roi_params', [{"suffix": None, "slice_filter_roi": None}])
@pytest.mark.parametrize('testing_params', [{
"binarize_maxpooling": {},
"uncertainty": {
"applied": False,
"epistemic": False,
"aleatoric": False,
"n_it": 0
}}])
def test_inference_target_suffix(download_data_testing_test_files, transforms_dict, test_lst, target_lst, roi_params,
testing_params):
"""
This test checks if the filename(s) of the prediction(s) saved as NifTI file(s) in the pred_masks
dir conform to the target_suffix or not. Thus, independent of underscore(s) in the target_suffix. As a result,
_seg-axon-manual or _seg-axon_manual should yield the same filename(s).
(c.f: https://github.com/ivadomed/ivadomed/issues/1135)
"""
cuda_available, device = imed_utils.define_device(GPU_ID)

model_params = {"name": "Unet", "is_2d": True, "out_channel": 3}
loader_params = {
"transforms_params": transforms_dict,
"data_list": test_lst,
"dataset_type": "testing",
"requires_undo": True,
"contrast_params": {"contrast_lst": ['SEM'], "balance": {}},
"path_data": [str(Path(__data_testing_dir__, "microscopy_png"))],
"bids_config": f"{path_repo_root}/ivadomed/config/config_bids.json",
"target_suffix": target_lst,
"extensions": [".png"],
"roi_params": roi_params,
"slice_filter_params": {"filter_empty_mask": False, "filter_empty_input": True},
"patch_filter_params": {"filter_empty_mask": False, "filter_empty_input": False},
"slice_axis": SLICE_AXIS,
"multichannel": False
}
loader_params.update({"model_params": model_params})

# restructuring the dataset
gt_path = f'{loader_params["path_data"][0]}/derivatives/labels/'
for file_path in Path(gt_path).rglob('*.png'):
src_filename = file_path.resolve()
dst_filename = '_'.join(str(src_filename).rsplit('-', 1))
src_filename.rename(Path(dst_filename))

bids_df = BidsDataframe(loader_params, __tmp_dir__, derivatives=True)

ds_test = imed_loader.load_dataset(bids_df, **loader_params)
test_loader = DataLoader(ds_test, batch_size=BATCH_SIZE,
shuffle=False, pin_memory=True,
collate_fn=imed_loader_utils.imed_collate,
num_workers=0)

# Undo transform
val_undo_transform = imed_transforms.UndoCompose(imed_transforms.Compose(transforms_dict))

# Update testing_params
testing_params.update({
"slice_axis": loader_params["slice_axis"],
"target_suffix": loader_params["target_suffix"],
"undo_transforms": val_undo_transform
})

# Model
model = imed_models.Unet(out_channel=model_params['out_channel'])

if cuda_available:
model.cuda()
model.eval()

if not __output_dir__.is_dir():
__output_dir__.mkdir(parents=True, exist_ok=True)

preds_npy, gt_npy = imed_testing.run_inference(test_loader=test_loader,
model=model,
model_params=model_params,
testing_params=testing_params,
ofolder=str(__output_dir__),
cuda_available=cuda_available)

for x in __output_dir__.iterdir():
if x.name.endswith('_pred.nii.gz'):
assert x.name.rsplit('_', 1)[0].endswith(loader_params['contrast_params']['contrast_lst'][-1]), (
'Incompatible filename(s) of the prediction(s) saved as NifTI file(s)!'
)

def teardown_function():
remove_tmp_dir()

0 comments on commit c9e69c9

Please sign in to comment.