def setup(self):
        # Fieldmap
        fname_fieldmap = os.path.join(__dir_testing__,
                                      'realtime_zshimming_data', 'nifti',
                                      'sub-example', 'fmap',
                                      'sub-example_fieldmap.nii.gz')
        nii_fieldmap = nib.load(fname_fieldmap)
        self.nii_fieldmap = nii_fieldmap

        # anat image
        fname_anat = os.path.join(__dir_testing__, 'realtime_zshimming_data',
                                  'nifti', 'sub-example', 'anat',
                                  'sub-example_unshimmed_e1.nii.gz')
        nii_anat = nib.load(fname_anat)
        self.nii_anat = nii_anat

        # Set up mask
        # static
        nx, ny, nz = nii_anat.shape
        mask = shapes(nii_anat.get_fdata(),
                      'cube',
                      center_dim1=int(nx / 2),
                      center_dim2=int(ny / 2),
                      len_dim1=30,
                      len_dim2=30,
                      len_dim3=nz)

        nii_mask_static = nib.Nifti1Image(mask.astype(int), nii_anat.affine)
        self.nii_mask_static = nii_mask_static

        # Riro
        mask = shapes(nii_anat.get_fdata(),
                      'cube',
                      center_dim1=int(nx / 2),
                      center_dim2=int(ny / 2),
                      len_dim1=30,
                      len_dim2=30,
                      len_dim3=nz)

        nii_mask_riro = nib.Nifti1Image(mask.astype(int), nii_anat.affine)
        self.nii_mask_riro = nii_mask_riro

        # Pmu
        fname_resp = os.path.join(__dir_testing__, 'realtime_zshimming_data',
                                  'PMUresp_signal.resp')
        pmu = PmuResp(fname_resp)
        self.pmu = pmu

        # Path for json file
        fname_json = os.path.join(__dir_testing__, 'realtime_zshimming_data',
                                  'nifti', 'sub-example', 'fmap',
                                  'sub-example_magnitude1.json')
        with open(fname_json) as json_file:
            json_data = json.load(json_file)

        self.json = json_data
def test_zslice():

    # Set up unshimmed fieldmap
    num_vox = 100
    model_obj = NumericalModel('shepp-logan', num_vox=num_vox)
    model_obj.generate_deltaB0('linear', [0.05, 0.01])
    tr = 0.025  # in s
    te = [0.004, 0.008]  # in s
    model_obj.simulate_measurement(tr, te)
    phase_meas1 = model_obj.get_phase()
    phase_e1 = phase_meas1[:, :, 0, 0]
    phase_e2 = phase_meas1[:, :, 0, 1]
    b0_map = (phase_e2 - phase_e1)/(te[1] - te[0])
    nz = 3

    # Construct synthetic field map based on a manipulation of model_obj across slices
    unshimmed = np.zeros([num_vox, num_vox, nz])
    unshimmed[:, :, 0] = b0_map
    unshimmed[:, :, 1] = (np.rot90(unshimmed[:, :, 0]) + unshimmed[:, :, 0]) / 2
    unshimmed[:, :, 2] = unshimmed[:, :, 0] ** 2

    # Set up coil profile
    x, y, z = np.meshgrid(
        np.array(range(int(-num_vox/2), int(num_vox/2))),
        np.array(range(int(-num_vox/2), int(num_vox/2))),
        np.array(range(nz)),
        indexing='ij')
    coils = siemens_basis(x, y, z)

    # Set up bounds for output currents
    max_coef = 5000
    min_coef = -5000
    bounds = []
    for _ in range(coils.shape[3]):
        bounds.append((min_coef, max_coef))

    # Set up mask
    full_mask = shapes(unshimmed, 'cube', len_dim1=40, len_dim2=40, len_dim3=nz)

    # Optimize
    z_slices = np.array(range(nz))
    currents = sequential_zslice(unshimmed, coils, full_mask, z_slices, bounds=bounds)

    # Calculate theoretical shimmed map
    shimmed = unshimmed + np.sum(currents * coils, axis=3, keepdims=False)

    for i_slice in z_slices:
        assert(np.sum(np.abs(full_mask[:, :, i_slice] * shimmed[:, :, i_slice])) <
               np.sum(np.abs(full_mask[:, :, i_slice] * unshimmed[:, :, i_slice])))
Exemple #3
0
def test_cli_realtime_zshim():
    """Test CLI for performing realtime zshimming experiments"""
    with tempfile.TemporaryDirectory(prefix='st_' +
                                     pathlib.Path(__file__).stem) as tmp:
        runner = CliRunner()

        # Local
        fname_fieldmap = os.path.join(__dir_testing__,
                                      'realtime_zshimming_data', 'nifti',
                                      'sub-example', 'fmap',
                                      'sub-example_fieldmap.nii.gz')

        # Path for mag anat image
        fname_anat = os.path.join(__dir_testing__, 'realtime_zshimming_data',
                                  'nifti', 'sub-example', 'anat',
                                  'sub-example_unshimmed_e1.nii.gz')
        nii_anat = nib.load(fname_anat)
        anat = nii_anat.get_fdata()

        # Set up mask
        # Cube
        nx, ny, nz = anat.shape
        mask = shapes(anat,
                      'cube',
                      center_dim1=int(nx / 2),
                      center_dim2=int(ny / 2),
                      len_dim1=30,
                      len_dim2=30,
                      len_dim3=nz)

        nii_mask = nib.Nifti1Image(mask.astype(int), nii_anat.affine)
        fname_mask = os.path.join(tmp, 'mask.nii.gz')
        nib.save(nii_mask, fname_mask)

        # Path for resp data
        fname_resp = os.path.join(__dir_testing__, 'realtime_zshimming_data',
                                  'PMUresp_signal.resp')

        # Specify output for text file and figures
        path_output = os.path.join(tmp, 'test_realtime_zshim')

        # Run the CLI
        result = runner.invoke(realtime_zshim_cli, [
            '-fmap', fname_fieldmap, '-mask', fname_mask, '-output',
            path_output, '-resp', fname_resp, '-anat', fname_anat
        ],
                               catch_exceptions=False)
        assert len(os.listdir(path_output)) != 0
        assert result.exit_code == 0
Exemple #4
0
def test_timing_images():
    """Check the matching of timing between MR images and PMU timestamps"""

    # Get fieldmap
    fname_fieldmap = os.path.join(__dir_testing__, 'realtime_zshimming_data',
                                  'nifti', 'sub-example', 'fmap',
                                  'sub-example_fieldmap.nii.gz')
    nii_fieldmap = nib.load(fname_fieldmap)
    fieldmap = nii_fieldmap.get_fdata()

    # Get the pressure values
    fname_pmu = os.path.join(__dir_testing__, 'realtime_zshimming_data',
                             'PMUresp_signal.resp')
    pmu = PmuResp(fname_pmu)

    # Get acquisition timestamps
    fname_phase_diff_json = os.path.join(__dir_testing__,
                                         'realtime_zshimming_data', 'nifti',
                                         'sub-example', 'fmap',
                                         'sub-example_phasediff.json')
    with open(fname_phase_diff_json) as json_file:
        json_data = json.load(json_file)
    fieldmap_timestamps = get_acquisition_times(nii_fieldmap, json_data)

    # Interpolate PMU values onto MRI acquisition timestamp
    acquisition_pressures = pmu.interp_resp_trace(fieldmap_timestamps)

    # Set up mask
    mask_len1 = 15
    mask_len2 = 5
    mask_len3 = fieldmap.shape[2]
    mask = shapes(fieldmap[:, :, :, 0],
                  shape='cube',
                  center_dim1=int(fieldmap.shape[0] / 2 - 8),
                  center_dim2=int(fieldmap.shape[1] / 2 - 20),
                  len_dim1=mask_len1,
                  len_dim2=mask_len2,
                  len_dim3=mask_len3)

    # Apply mask and compute the average for each timepoint
    fieldmap_masked = np.zeros_like(fieldmap)
    fieldmap_avg = np.zeros([fieldmap.shape[3]])
    for i_time in range(fieldmap.shape[3]):
        fieldmap_masked[:, :, :, i_time] = fieldmap[:, :, :, i_time] * mask
        masked_array = np.ma.array(fieldmap[:, :, :, i_time],
                                   mask=mask == False)
        fieldmap_avg[i_time] = np.ma.average(masked_array)

    # Reshape pmu datapoints to fit those of the acquisition
    pmu_times = np.linspace(pmu.start_time_mdh, pmu.stop_time_mdh,
                            len(pmu.data))
    pmu_times_within_range = pmu_times[pmu_times > fieldmap_timestamps[0]]
    pmu_data_within_range = pmu.data[pmu_times > fieldmap_timestamps[0]]
    pmu_data_within_range = pmu_data_within_range[
        pmu_times_within_range < fieldmap_timestamps[fieldmap.shape[3] - 1]]
    pmu_times_within_range = pmu_times_within_range[
        pmu_times_within_range < fieldmap_timestamps[fieldmap.shape[3] - 1]]

    # Compute correlation
    pmu_data_within_range_ds = scipy.signal.resample(pmu_data_within_range,
                                                     fieldmap_avg.shape[0])
    pearson = np.corrcoef(fieldmap_avg, pmu_data_within_range_ds)

    assert (np.isclose(pearson[0, 1], 0.6031485150782748))