Esempio n. 1
0
def test_slope_corrector_slice_wise_slope_5d_fail():

    in_data = np.random.normal(5, 10, [2, 3, 4, 5, 6])
    sl = np.random.normal(5, 10, 7)

    with assert_raises(IOError):
        data_corrector(in_data, sl, kind='slope')
Esempio n. 2
0
def test_slope_corrector_slice_wise_slope_3d_fail():

    in_data = np.random.normal(5, 10, [4, 5, 3])
    sl = np.random.normal(5, 10, 5)

    with assert_raises(IOError):
        data_corrector(in_data, sl)
Esempio n. 3
0
def test_slope_corrector_int_float_slope():

    in_data = np.random.normal(5, 10, [3, 4, 5])
    sl1 = 5
    sl2 = 5.3

    out_data1 = data_corrector(in_data, sl1, kind='slope', dtype=np.float64)
    out_data2 = data_corrector(in_data, sl2, kind='slope', dtype=np.float64)

    assert_equal(out_data1.dtype, np.float64)
    assert_equal(out_data2.dtype, np.float64)
    assert_array_equal(out_data1, sl1 * in_data)
    assert_array_equal(out_data2, sl2 * in_data)
Esempio n. 4
0
def test_slope_corrector_slice_wise_slope_5d():

    in_data = np.random.normal(5, 10, [2, 3, 4, 5, 6])
    sl = np.random.normal(5, 10, 5)
    out_data = data_corrector(in_data, sl, kind='slope', dtype=np.float64)

    for t in range(6):
        for k in range(5):
            assert_array_equal(out_data[..., k, t], in_data[..., k, t] * sl[k])
Esempio n. 5
0
def test_slope_corrector_slice_wise_slope_3d():

    in_data = np.random.normal(5, 10, [4, 5, 3])
    sl = np.random.normal(5, 10, 3)

    out_data = data_corrector(in_data, sl, kind='slope', dtype=np.float64)

    for k in range(3):
        assert_array_equal(out_data[..., k], in_data[..., k] * sl[k])
def slope_corrector_path(slopes_array,
                         path_im_input,
                         path_im_output,
                         eliminate_consec_duplicates=False):
    """
    Correct for the slope from the path of the elements
    :param slopes_array:
    :param path_im_input:
    :param path_im_output:
    :param eliminate_consec_duplicates:
    :return:
    """
    im_input = nib.load(path_im_input)
    # slopes = np.loadtxt(slopes_txt_path)
    if eliminate_consec_duplicates:
        slopes_array = np.array(
            eliminates_consecutive_duplicates(list(slopes_array)))
    data_output = data_corrector(im_input.get_data(),
                                 slopes_array,
                                 kind='slope')
    im_output = set_new_data(im_input, data_output)
    nib.save(im_output, path_im_output)
    msg = 'Scaled image saved in ' + path_im_output
    print(msg)
Esempio n. 7
0
def nifti_getter(img_data_vol,
                 visu_pars,
                 correct_slope,
                 correct_offset,
                 sample_upside_down,
                 nifti_version,
                 qform_code,
                 sform_code,
                 frame_body_as_frame_head=False,
                 keep_same_det=True,
                 consider_subject_position=False):
    """
    Passage method to get a nifti image from the volume and the element contained into visu_pars.
    :param img_data_vol: volume of the image.
    :param visu_pars: corresponding dictionary to the 'visu_pars' data file.
    :param correct_slope: [True/False] if you want to correct the slope.
    :param correct_offset: [True/False] if you want to correct the offset.
    :param sample_upside_down: [True/False] if you want to have the sample rotated 180 around the Ant-Post axis.
    :param nifti_version: [1/2] according to the required nifti output
    :param qform_code: required nifti ouptut qform code.
    :param sform_code: required nifti ouput sform code
    :param frame_body_as_frame_head: [True/False] if the frame is the same for head and body [monkey] or not [mouse].
    :param keep_same_det: flag to constrain the determinant to be as the one provided into the orientation parameter.
    :param consider_subject_position: [False] if taking into account the 'Head_prone' 'Head_supine' input.
    :return:
    """
    # Check units of measurements:
    if not [
            'mm',
    ] * len(visu_pars['VisuCoreSize']) == visu_pars['VisuCoreUnits']:
        # if the UoM is not mm, change here. Add other measurements and refer to xyzt_units from nibabel convention.
        print(
            'Warning, measurement not in mm. This version of the converter deals with data in mm only.'
        )

    # get pre-shape and re-shape volume: (pre-shape is the shape compatible with the slope).
    vol_pre_shape = [int(i) for i in visu_pars['VisuCoreSize']]
    if int(visu_pars['VisuCoreFrameCount']) > 1:
        vol_pre_shape += [int(visu_pars['VisuCoreFrameCount'])]

    if np.prod(vol_pre_shape) == img_data_vol.shape[0]:
        vol_data = img_data_vol.reshape(vol_pre_shape, order='F')
    else:
        echo = img_data_vol.shape[0] / np.prod(vol_pre_shape)
        vol_pre_shape += [echo]
        vol_pre_shape = [int(k) for k in vol_pre_shape]
        vol_data = img_data_vol.reshape(vol_pre_shape, order='F')

    # correct slope if required
    if correct_slope:
        vol_data = data_corrector(vol_data,
                                  visu_pars['VisuCoreDataSlope'],
                                  kind='slope')
    # correct offset (AFTER slope) if required
    if correct_offset:
        vol_data = data_corrector(vol_data,
                                  visu_pars['VisuCoreDataOffs'],
                                  kind='offset')

    # get number sub-volumes
    num_sub_volumes = len(
        eliminate_consecutive_duplicates(list(
            visu_pars['VisuCoreOrientation'])))

    if num_sub_volumes > 1:

        output_nifti = []

        assert vol_pre_shape[2] % num_sub_volumes == 0
        vol_shape = vol_pre_shape[0], vol_pre_shape[1], int(vol_pre_shape[2] /
                                                            num_sub_volumes)

        # get resolution - same for all sub-volumes.
        resolution = compute_resolution_from_visu_pars(
            visu_pars['VisuCoreExtent'], visu_pars['VisuCoreSize'],
            visu_pars['VisuCoreFrameThickness'])

        for id_sub_vol in range(num_sub_volumes):

            # compute affine
            affine_transf = compute_affine_from_visu_pars(
                list(visu_pars['VisuCoreOrientation'])[id_sub_vol *
                                                       vol_shape[2]],
                list(visu_pars['VisuCorePosition'])[id_sub_vol * vol_shape[2]],
                visu_pars['VisuSubjectPosition'],
                resolution,
                frame_body_as_frame_head=frame_body_as_frame_head,
                keep_same_det=keep_same_det,
                consider_subject_position=consider_subject_position)

            if sample_upside_down:
                affine_transf = affine_transf.dot(np.diag([-1, 1, -1, 1]))

            # get sub volume in the correct shape
            img_data_sub_vol = vol_data[..., id_sub_vol *
                                        vol_shape[2]:(id_sub_vol + 1) *
                                        vol_shape[2]]

            if nifti_version == 1:
                nib_im_sub_vol = nib.Nifti1Image(img_data_sub_vol,
                                                 affine=affine_transf)
            elif nifti_version == 2:
                nib_im_sub_vol = nib.Nifti2Image(img_data_sub_vol,
                                                 affine=affine_transf)
            else:
                raise IOError('Nifti versions allowed are 1 or 2.')

            hdr_sub_vol = nib_im_sub_vol.header
            hdr_sub_vol.set_qform(affine_transf, code=qform_code)
            hdr_sub_vol.set_sform(affine_transf, code=sform_code)
            hdr_sub_vol['xyzt_units'] = 10  # default mm, seconds
            nib_im_sub_vol.update_header()

            output_nifti.append(nib_im_sub_vol)

    else:

        # get shape
        sh = vol_pre_shape

        # check for frame groups:  -- Very convoluted scaffolding. Waiting to have more infos to refactor this part.
        # ideally an external function read VisuFGOrderDesc should provide the sh and the choice between # A and # B
        # while testing for exception.

        if 'VisuFGOrderDescDim' in visu_pars.keys():  # see manuals D-2-73
            if visu_pars['VisuFGOrderDescDim'] > 0:
                if isinstance(visu_pars['VisuFGOrderDesc'], list):
                    if len(visu_pars['VisuFGOrderDesc']) > 1:
                        descr = visu_pars['VisuFGOrderDesc'][:]
                        # sort descr so that FG_SLICE is the first one, all the others came as they are after swapping.
                        fg_slice_pos = -1
                        fg_echo = -1
                        fg_movie = -1
                        for d in range(len(descr)):
                            if '<FG_SLICE>' in descr[d]:
                                fg_slice_pos = d
                            if '<FG_ECHO>' in descr[d]:
                                fg_echo = d
                            if '<FG_MOVIE>' in descr[d]:
                                fg_movie = d
                        if fg_slice_pos == -1:
                            raise IOError(
                                'FG_SLICE not found in the order descriptor, can not tell the ordering.'
                            )

                        descr[fg_slice_pos], descr[0] = descr[0], descr[
                            fg_slice_pos]

                        dims = []
                        for dd in descr:
                            dims.append(
                                int(
                                    dd.replace('(',
                                               '').replace(')',
                                                           '').split(',')[0]))

                        if np.prod(dims) == sh[-1]:
                            sh = vol_pre_shape[:-1] + dims
                            # A
                            if fg_echo > -1:
                                # MSME
                                stack_data = np.zeros(sh, dtype=vol_data.dtype)
                                for t in range(sh[3]):
                                    for z in range(sh[2]):
                                        stack_data[:, :, z,
                                                   t] = vol_data[:, :,
                                                                 z * sh[3] + t]

                                vol_data = np.copy(stack_data)
                            # B
                            elif fg_movie > -1:
                                # DTI
                                vol_data = vol_data.reshape(sh, order='F')
                            else:
                                # Else ?
                                vol_data = vol_data.reshape(sh, order='F')

        # get resolution
        resolution = compute_resolution_from_visu_pars(
            visu_pars['VisuCoreExtent'], visu_pars['VisuCoreSize'],
            visu_pars['VisuCoreFrameThickness'])

        # compute affine
        affine_transf = compute_affine_from_visu_pars(
            list(visu_pars['VisuCoreOrientation'])[0],
            list(visu_pars['VisuCorePosition'])[0],
            visu_pars['VisuSubjectPosition'],
            resolution,
            frame_body_as_frame_head=frame_body_as_frame_head,
            keep_same_det=keep_same_det,
            consider_subject_position=consider_subject_position)

        if sample_upside_down:
            affine_transf = affine_transf.dot(np.diag([-1, 1, -1, 1]))

        if nifti_version == 1:
            output_nifti = nib.Nifti1Image(vol_data, affine=affine_transf)
        elif nifti_version == 2:
            output_nifti = nib.Nifti2Image(vol_data, affine=affine_transf)
        else:
            raise IOError('Nifti versions allowed are 1 or 2.')

        hdr_sub_vol = output_nifti.header
        hdr_sub_vol.set_qform(affine_transf, code=qform_code)
        hdr_sub_vol.set_sform(affine_transf, code=sform_code)
        hdr_sub_vol['xyzt_units'] = 10
        output_nifti.update_header()

    return output_nifti