Skip to content

Commit

Permalink
Add multiple fieldmap and b0shim tests
Browse files Browse the repository at this point in the history
  • Loading branch information
po09i committed Oct 9, 2023
1 parent aba2810 commit eab2ed6
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 22 deletions.
29 changes: 23 additions & 6 deletions fsleyes_plugin_shimming_toolbox/tabs/fieldmap_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
class FieldMapTab(Tab):
def __init__(self, parent, title="Fieldmap"):

self.component_save_mask1 = None
self.component_save_mask2 = None
self.run_component = None
self.component_input2 = None
self.component_output = None
Expand Down Expand Up @@ -84,16 +86,30 @@ def create_fieldmap_sizer(self):
input_text_box_metadata=mask_metadata,
cli=prepare_fieldmap_cli
)
save_mask_metadata = [
{
"button_label": "Output Calculated Mask",
"name": "savemask",
"load_in_overlay": True
}
]

self.component_save_mask1 = InputComponent(
panel=self,
input_text_box_metadata=save_mask_metadata,
cli=prepare_fieldmap_cli
)

self.component_save_mask2 = InputComponent(
panel=self,
input_text_box_metadata=save_mask_metadata,
cli=prepare_fieldmap_cli
)

threshold_metadata = [
{
"button_label": "Threshold",
"name": "threshold",
},
{
"button_label": "Output Calculated Mask",
"name": "savemask",
"load_in_overlay": True
}
]
self.component_threshold = InputComponent(
Expand Down Expand Up @@ -123,7 +139,8 @@ def create_fieldmap_sizer(self):
label="Unwrapping region",
info_text="Masking methods either with a file input or a threshold",
option_name='no_arg_roi',
list_components=[self.create_empty_component(), self.component_mask, self.component_threshold],
list_components=[self.component_save_mask1, self.component_mask, self.component_threshold, self.component_save_mask2],
component_to_dropdown_choice=[0, 1, 2, 2],
cli=prepare_fieldmap_cli
)

Expand Down
98 changes: 88 additions & 10 deletions test/gui/test_b0shim_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,67 @@
from fsleyes_plugin_shimming_toolbox.tabs.b0shim_tab import B0ShimTab


def test_st_plugin_b0shim_run():
run_with_orthopanel(_test_st_plugin_b0shim_run)


def _test_st_plugin_b0shim_run(view, overlayList, displayCtx):
def test_st_plugin_b0shim_dyn_lsq_mse():
options = {'optimizer-method': 'Least Squares',
'optimizer-criteria': 'Mean Squared Error',
'slices': 'Auto detect',
'scanner-coil-order': '1',
'output-file-format-scanner': 'Slicewise per Channel',
'output-file-format-coil': 'Slicewise per Channel',
'fatsat': 'Auto detect',
'output-value-format': 'delta'
}

def _test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options=options):
__test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options=options)
run_with_orthopanel(_test_st_plugin_b0shim_dyn)


def test_st_plugin_b0shim_dyn_lsq_mae():
options = {'optimizer-method': 'Least Squares',
'optimizer-criteria': 'Mean Absolute Error',
'slices': 'Auto detect',
'scanner-coil-order': '1',
'output-file-format-scanner': 'Slicewise per Channel',
'output-file-format-coil': 'Slicewise per Channel',
'output-value-format': 'delta'
}

def _test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options=options):
__test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options=options)
run_with_orthopanel(_test_st_plugin_b0shim_dyn)


def test_st_plugin_b0shim_dyn_pi():
options = {'optimizer-method': 'Pseudo Inverse',
'slices': 'Auto detect',
'scanner-coil-order': '1',
'output-file-format-scanner': 'Slicewise per Channel',
'output-file-format-coil': 'Slicewise per Channel',
'output-value-format': 'delta'
}

def _test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options=options):
__test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options=options)
run_with_orthopanel(_test_st_plugin_b0shim_dyn)


def test_st_plugin_b0shim_dyn_qp():
options = {'optimizer-method': 'Quad Prog',
'optimizer-criteria': 'Mean Squared Error',
'slices': 'Auto detect',
'scanner-coil-order': '1',
'output-file-format-scanner': 'Slicewise per Channel',
'output-file-format-coil': 'Slicewise per Channel',
'output-value-format': 'delta'
}

def _test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options=options):
__test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options=options)
run_with_orthopanel(_test_st_plugin_b0shim_dyn)


def __test_st_plugin_b0shim_dyn(view, overlayList, displayCtx, options):
""" Makes sure the B0 shim tab runs (Add dummy input and simulate a click) """
nb_terminal = get_notebook(view)

Expand Down Expand Up @@ -61,17 +117,39 @@ def _test_st_plugin_b0shim_run(view, overlayList, displayCtx):
for widget in list_widgets:
if isinstance(widget, wx.Choice) and widget.IsShown():
if widget.GetName() == 'optimizer-method':
assert set_dropdown_selection(widget, 'Least Squares')
assert set_dropdown_selection(widget, options['optimizer-method'])
if widget.GetName() == 'scanner-coil-order':
assert set_dropdown_selection(widget, options['scanner-coil-order'])
if widget.GetName() == 'slices':
assert set_dropdown_selection(widget, options['slices'])
if widget.GetName() == 'scanner-coil-order':
assert set_dropdown_selection(widget, '1')
# optimizer-criteria, slices, scanner-coil-order, output-file-format-scanner, output-file-format-coil,
# fatsat, output-value-format
assert set_dropdown_selection(widget, options['scanner-coil-order'])
if widget.GetName() == 'output-value-format':
assert set_dropdown_selection(widget, options['output-value-format'])
# Select the dropdowns that are nested
list_widgets = []
get_all_children(b0shim_tab.sizer_run, list_widgets)
for widget in list_widgets:
if isinstance(widget, wx.Choice) and widget.IsShown():
if widget.GetName() == 'optimizer-criteria':
assert set_dropdown_selection(widget, options['optimizer-criteria'])
if widget.GetName() == 'output-file-format-scanner':
assert set_dropdown_selection(widget, options['output-file-format-scanner'])
if widget.GetName() == 'output-file-format-scanner':
assert set_dropdown_selection(widget, options['output-file-format-coil'])
# Select the dropdowns that are nested
list_widgets = []
get_all_children(b0shim_tab.sizer_run, list_widgets)
for widget in list_widgets:
if isinstance(widget, wx.Choice) and widget.IsShown():
if widget.GetName() == 'fatsat':
assert set_dropdown_selection(widget, options['fatsat'])

# Fill in the text boxes
list_widgets = []
get_all_children(b0shim_tab.sizer_run, list_widgets)
for widget in list_widgets:
if isinstance(widget, wx.TextCtrl):
if isinstance(widget, wx.TextCtrl) and widget.IsShown():
if widget.GetName() == 'no_arg_ncoils_dyn':
widget.SetValue('0')
realYield()
Expand Down
2 changes: 1 addition & 1 deletion test/gui/test_dicom_to_nifti_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def _test_st_plugin_dcm2niix_run(view, overlayList, displayCtx):
list_widgets = []
get_all_children(dcm2nifti_tab.sizer_run, list_widgets)
for widget in list_widgets:
if isinstance(widget, wx.TextCtrl):
if isinstance(widget, wx.TextCtrl) and widget.IsShown():
if widget.GetName() == 'input':
widget.SetValue(path_input)
realYield()
Expand Down
91 changes: 86 additions & 5 deletions test/gui/test_fieldmap_tab.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,62 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import nibabel as nib
import numpy as np
import os
import pathlib
from shimmingtoolbox.masking.shapes import shapes
import tempfile
import time
import wx

from .test_tabs import get_notebook, set_notebook_page, get_tab, get_all_children
from .test_tabs import get_notebook, set_notebook_page, get_tab, get_all_children, set_dropdown_selection
from .. import realYield, run_with_orthopanel
from fsleyes_plugin_shimming_toolbox import __dir_testing__
from fsleyes_plugin_shimming_toolbox.tabs.fieldmap_tab import FieldMapTab


def test_st_plugin_fieldmap_run():
run_with_orthopanel(_test_st_plugin_fieldmap_run)
def test_st_plugin_fieldmap_prelude():
options = {'no_arg_roi': 'auto threshold',
'unwrapper': 'Prelude'}

def _test_st_plugin_fieldmap(view, overlayList, displayCtx, options=options):
__test_st_plugin_fieldmap(view, overlayList, displayCtx, options=options)

def _test_st_plugin_fieldmap_run(view, overlayList, displayCtx):
run_with_orthopanel(_test_st_plugin_fieldmap)


def test_st_plugin_fieldmap_skimage():
options = {'no_arg_roi': 'auto threshold',
'unwrapper': 'Skimage'}

def _test_st_plugin_fieldmap(view, overlayList, displayCtx, options=options):
__test_st_plugin_fieldmap(view, overlayList, displayCtx, options=options)

run_with_orthopanel(_test_st_plugin_fieldmap)


def test_st_plugin_fieldmap_input_mask():
options = {'no_arg_roi': 'mask',
'unwrapper': 'Skimage'}

def _test_st_plugin_fieldmap(view, overlayList, displayCtx, options=options):
__test_st_plugin_fieldmap(view, overlayList, displayCtx, options=options)

run_with_orthopanel(_test_st_plugin_fieldmap)


def test_st_plugin_fieldmap_threshold():
options = {'no_arg_roi': 'threshold',
'unwrapper': 'Skimage'}

def _test_st_plugin_fieldmap(view, overlayList, displayCtx, options=options):
__test_st_plugin_fieldmap(view, overlayList, displayCtx, options=options)

run_with_orthopanel(_test_st_plugin_fieldmap)


def __test_st_plugin_fieldmap(view, overlayList, displayCtx, options):
""" Makes sure fieldmap tab can be run (Add dummy input and simulate a click) """
nb_terminal = get_notebook(view)

Expand All @@ -33,6 +72,8 @@ def _test_st_plugin_fieldmap_run(view, overlayList, displayCtx):
fname_phase1 = os.path.join(__dir_testing__, 'ds_b0', 'sub-fieldmap', 'fmap', 'sub-fieldmap_phase1.nii.gz')
fname_phase2 = os.path.join(__dir_testing__, 'ds_b0', 'sub-fieldmap', 'fmap', 'sub-fieldmap_phase2.nii.gz')
fname_output = os.path.join(tmp, 'fieldmap.nii.gz')
fname_input_mask = os.path.join(tmp, 'input_mask.nii.gz')
fname_output_mask = os.path.join(tmp, 'output_mask.nii.gz')

# Fill in Fieldmap tab options
list_widgets = []
Expand All @@ -45,7 +86,17 @@ def _test_st_plugin_fieldmap_run(view, overlayList, displayCtx):
list_widgets = []
get_all_children(fmap_tab.sizer_run, list_widgets)
for widget in list_widgets:
if isinstance(widget, wx.TextCtrl):
if isinstance(widget, wx.Choice) and widget.IsShown():
if widget.GetName() == 'no_arg_roi':
assert set_dropdown_selection(widget, options['no_arg_roi'])
# auto threshold, mask, threshold
if widget.GetName() == 'unwrapper':
assert set_dropdown_selection(widget, options['unwrapper'])
# Prelude, Skimage
list_widgets = []
get_all_children(fmap_tab.sizer_run, list_widgets)
for widget in list_widgets:
if isinstance(widget, wx.TextCtrl) and widget.IsShown():
if widget.GetName() == 'input_phase_1':
widget.SetValue(fname_phase1)
realYield()
Expand All @@ -61,6 +112,14 @@ def _test_st_plugin_fieldmap_run(view, overlayList, displayCtx):
if widget.GetName() == 'output':
widget.SetValue(fname_output)
realYield()
if widget.GetName() == 'mask':
nii_mask = get_mask_from_fmap()
nib.save(nii_mask, fname_input_mask)
widget.SetValue(fname_input_mask)
realYield()
if widget.GetName() == 'savemask':
widget.SetValue(fname_output_mask)
realYield()

# Call the function ran when clicking run button
fmap_tab.run_component.run()
Expand All @@ -77,3 +136,25 @@ def _test_st_plugin_fieldmap_run(view, overlayList, displayCtx):
# Make sure there is an output in the overlay (that would mean the ST CLI ran)
assert overlay_file is not None
assert os.path.exists(fname_output)
if options['no_arg_roi'] == 'mask':
assert not os.path.exists(fname_output_mask)
elif options['no_arg_roi'] == 'threshold':
assert os.path.exists(fname_output_mask)
else:
# auto threshold
assert os.path.exists(fname_output_mask)



def get_mask_from_fmap():
fname_mag = os.path.join(__dir_testing__, 'ds_b0', 'sub-fieldmap', 'fmap', 'sub-fieldmap_magnitude1.nii.gz')
nii_fmap = nib.load(fname_mag)
nx, ny, nz = nii_fmap.shape

mask = shapes(nii_fmap.get_fdata(), 'cube',
center_dim1=int(nx / 2),
center_dim2=int(ny / 2),
len_dim1=10, len_dim2=10, len_dim3=nz - 10)

nii_mask = nib.Nifti1Image(mask.astype(np.uint8), nii_fmap.affine)
return nii_mask

0 comments on commit eab2ed6

Please sign in to comment.