Пример #1
0
def coil_combine(in_filepaths,
                 out_filepaths,
                 method='block_adaptive_iter',
                 method_kws=None,
                 compression='compress_svd',
                 compression_kws=None,
                 coil_axis=-1,
                 split_axis=None,
                 q_filepath=None,
                 force=False,
                 verbose=D_VERB_LVL):
    in_mag_filepath, in_phs_filepath = in_filepaths
    out_mag_filepath, out_phs_filepath = out_filepaths
    msg('Input-MAG: {}'.format(in_mag_filepath))
    msg('Input-PHS: {}'.format(in_phs_filepath))
    msg('Output-MAG: {}'.format(out_mag_filepath))
    msg('Output-PHS: {}'.format(out_phs_filepath))
    msg('Method: {}'.format(method))
    msg('Compression: {}'.format(compression))
    msg('Quality: {}'.format(q_filepath))
    # in_filepaths = [in_mag_filepath, in_phs_filepath]
    # out_filepaths = [out_mag_filepath, out_phs_filepath]
    if fc.check_redo(in_filepaths, out_filepaths, force):
        mag_coils_arr, meta = mrt.input_output.load(in_mag_filepath, meta=True)
        phs_coils_arr = mrt.input_output.load(in_phs_filepath)
        coils_arr = fcn.polar2complex(mag_coils_arr, phs_coils_arr)
        del mag_coils_arr, phs_coils_arr
        arr = coils.combine(coils_arr,
                            method=method,
                            method_kws=method_kws,
                            compression=compression,
                            compression_kws=compression_kws,
                            coil_axis=coil_axis,
                            split_axis=split_axis,
                            verbose=verbose)
        mag_arr, phs_arr = fc.complex2polar(arr)
        mrt.input_output.save(out_mag_filepath, mag_arr, **meta)
        mrt.input_output.save(out_phs_filepath, phs_arr, **meta)
        if fc.check_redo(out_filepaths, q_filepath):
            q_arr = coils.quality(coils_arr,
                                  arr,
                                  coil_axis=coil_axis,
                                  verbose=verbose)
            mrt.input_output.save(q_filepath, q_arr)
Пример #2
0
def calc_nii(in_dirpath, compress=True, force=False, verbose=D_VERB_LVL):
    """
    Reconstruct MRI image from Bruker dataset with standard parameters.
    """
    data_filepath = os.path.join(in_dirpath, 'fid')
    in_filename_list = 'method', 'acqp'
    in_filepath_list = [
        os.path.join(in_dirpath, in_filename)
        for in_filename in in_filename_list
    ]
    out_dirpath = os.path.join(in_dirpath, 'pdata/1')
    out_filename_list = 'bildabs.nii.gz', 'bildphs.nii.gz'
    out_filepath_list = [
        os.path.join(out_dirpath, out_filename)
        for out_filename in out_filename_list
    ]
    if os.path.exists(data_filepath):
        if fc.check_redo(in_filepath_list, out_filepath_list, force):
            # remove files checked by matlab reco to avoid new folders
            matlab_output = os.path.join(out_dirpath, 'bildabs.mat')
            if os.path.exists(matlab_output):
                os.remove(matlab_output)
            if verbose > VERB_LVL['none']:
                print('Target:\t{}'.format(in_dirpath))
            cmd = [
                'matlab', '-nodesktop', '-nosplash', '-nojvm',
                '-r "calc_nii(\'{}\'); quit;"'.format(in_dirpath)
            ]
            cwd = os.path.expanduser('~')
            subprocess.call(cmd, cwd=cwd)
            if compress:
                for out_filepath in out_filepath_list:
                    uncompressed = out_filepath[:-len('.gz')]
                    if os.path.exists(uncompressed):
                        subprocess.call(['gzip', '-f', uncompressed])
    return out_filepath_list
Пример #3
0
def sample2d(
        arr,
        axis=None,
        start=None,
        stop=None,
        step=None,
        duration=10000,
        title=None,
        array_interval=None,
        ticks_limit=None,
        orientation=None,
        flip_ud=False,
        flip_lr=False,
        cmap=None,
        cbar_kws=None,
        cbar_txt=None,
        text_color=None,
        resolution=None,
        size_info=None,
        more_texts=None,
        more_elements=None,
        ax=None,
        save_filepath=None,
        save_kws=None,
        force=False,
        verbose=D_VERB_LVL):
    """
    Plot a 2D sample image of a 3D array.

    Parameters
    ==========
    arr : ndarray
        The original 3D array.
    axis : int (optional)
        The slicing axis. If None, use the shortest one.
    step : int (optional)
        The slicing index. Must be 1 or more.
    title : str (optional)
        The title of the plot.
    array_interval : 2-tuple (optional)
        The (min, max) values interval.
    cmap : MatPlotLib ColorMap (optional)
        The colormap to be used for displaying the histogram.
    use_new_figure : bool (optional)
        Plot the histogram in a new figure.
    close_figure : bool (optional)
        Close the figure after saving (useful for batch processing).
    save_filepath : str (optional)
        The path to which the plot is to be saved. If unset, no output.

    Returns
    =======
    sample : ndarray
        The sliced (N-1)D-array.
    plot : matplotlib.pyplot.Figure
        The figure object containing the plot.

    """
    if arr.ndim != 3:
        raise IndexError('3D array required')

    fig, ax = mrt.plot._ensure_fig_ax(ax)

    n_frames = arr.shape[axis]

    if start is None:
        start = 0
    if stop is None:
        stop = n_frames
    if step is None:
        step = 1

    # prepare data
    sample = fcn.ndim_slice(arr, axis, start)

    if title:
        ax.set_title(title)

    if array_interval is None:
        array_interval = fcn.minmax(arr)

    if not text_color:
        text_color = 'k'

    ax.set_aspect('equal')

    mrt.plot._manage_ticks_limit(ticks_limit, ax)

    plots = []
    datas = []
    for i in range(start, stop, step):
        data = mrt.plot._reorient_2d(
            fcn.ndim_slice(arr, axis, i), orientation, flip_ud, flip_lr)
        pax = ax.imshow(
            data, cmap=cmap,
            vmin=array_interval[0], vmax=array_interval[1], animated=True)
        # include additional text
        if more_texts is not None:
            for text_kws in more_texts:
                ax.text(**dict(text_kws))
        datas.append(data)
        if len(plots) <= 0:
            mrt.plot._manage_colorbar(cbar_kws, cbar_txt, ax, pax)
        plots.append([pax])

        # print resolution information and draw a ruler
        mrt.plot._manage_resolution_info(
            size_info, resolution, data.shape, text_color, ax)

        mrt.plot._more_texts(more_texts, ax)
        mrt.plot._more_elements(more_elements, ax)

    mov = mpl.animation.ArtistAnimation(fig, plots, blit=False)
    if save_filepath and fc.check_redo(None, [save_filepath], force):
        fig.tight_layout()
        save_kws = {'fps': n_frames / step / duration / MSEC_IN_SEC}
        if save_kws is None:
            save_kws = {}
        save_kws.update(save_kws)
        mov.save(save_filepath, **dict(save_kws))
        msg('Anim: {}'.format(save_filepath, verbose, VERB_LVL['medium']))
        plt.close(fig)
    return datas, fig, mov
Пример #4
0
def trajectory_2d(
        trajectory,
        duration=10000,
        last_frame_duration=3000,
        support_intervals=None,
        plot_kws=(('marker', 'o'), ('linewidth', 1)),
        ticks_limit=None,
        title=None,
        more_texts=None,
        more_elements=None,
        ax=None,
        save_filepath=None,
        save_kws=None,
        force=False,
        verbose=D_VERB_LVL):
    n_dims, n_points = trajectory.shape
    if n_dims != 2:
        raise IndexError('2D trajectory required')
    if ax is None:
        fig = plt.figure()
        ax = fig.gca()
    else:
        fig = plt.gcf()
    if title:
        ax.set_title(title)
    if support_intervals is None:
        support_intervals = (
            fcn.minmax(trajectory[0]), fcn.minmax(trajectory[1]))

    n_frames = int(n_points * (1 + last_frame_duration / duration))
    data = trajectory

    if plot_kws is None:
        plot_kws = {}

    line, = ax.plot([], [], **dict(plot_kws))
    # points = ax.scatter([], [])
    ax.grid()
    x_data, y_data = [], []

    def data_gen():
        for i in range(n_points):
            yield trajectory[0, i], trajectory[1, i]
        for i in range(n_frames - n_points):
            yield None, None

    def init():
        xlim_size = np.ptp(support_intervals[0])
        ylim_size = np.ptp(support_intervals[1])
        ax.set_xlim(
            (support_intervals[0][0] - 0.1 * xlim_size,
             support_intervals[0][1] + 0.1 * xlim_size))
        ax.set_ylim(
            (support_intervals[1][0] - 0.1 * ylim_size,
             support_intervals[1][1] + 0.1 * ylim_size))
        del x_data[:]
        del y_data[:]
        line.set_data(x_data, y_data)
        # points.set_offsets(np.c_[x_data, y_data])
        return line,  # points

    def run(data_generator):
        # update the data
        x, y = data_generator
        x_data.append(x)
        y_data.append(y)
        line.set_data(x_data, y_data)
        # points.set_offsets(np.c_[x_data, y_data])
        return line,  # points

    mrt.plot._more_texts(more_texts, ax)
    mrt.plot._more_elements(more_elements, ax)
    mov = mpl.animation.FuncAnimation(
        fig, run, data_gen, init_func=init, save_count=n_frames,
        blit=False, repeat=False, repeat_delay=None,
        interval=duration / n_frames)

    if save_filepath and fc.check_redo(None, [save_filepath], force):
        fig.tight_layout()
        save_kws = dict(
            fps=n_frames / duration / MSEC_IN_SEC, save_count=n_frames)
        if save_kws is None:
            save_kws = {}
        save_kws.update(save_kws)
        mov.save(save_filepath, **dict(save_kws))
        msg('Anim: {}'.format(save_filepath, verbose, VERB_LVL['medium']))
        # plt.close(fig)
    return trajectory, fig, mov
Пример #5
0
def compute_generic(sources,
                    out_dirpath,
                    params=None,
                    opts=None,
                    force=False,
                    verbose=D_VERB_LVL):
    """
    Perform the specified computation on source files.

    Args:
        sources (list[str]): Directory containing data files.
        out_dirpath (str): Directory containing metadata files.
        params (dict): Parameters associated with the sources.
        opts (dict):
            Accepted options:
                - types (list[str]): List of image types to use for results.
                - mask: (Iterable[Iterable[int]): Slicing for each dimension.
                - adapt_mask (bool): adapt over- or under-sized mask.
                - dtype (str): data type to be used for the target images.
                - compute_func (str): function used for the computation.

                  compute_func(images, params, compute_args, compute_kwargs)
                  -> img_list, img_type_list
                - compute_args (list): additional positional parameters for
                  compute_func
                - compute_kwargs (dict): additional keyword parameters for
                  compute_func
                - affine_func (str): name of the function for affine
                  computation: affine_func(affines, affine_args...) -> affine
                - affine_args (list): additional parameters for affine_func
        force (bool): Force calculation of output.
        verbose (int): Set level of verbosity.

    Returns:
        targets ():

    See Also:
        pymrt.computation.sources_generic,
        pymrt.computation.compute,
        pymrt.computation.D_OPTS
    """
    # TODO: implement affine_func, affine_args, affine_kwargs?
    # get the num, name and seq from first source file
    opts = fc.join_(D_OPTS, opts)

    if params is None:
        params = {}
    if opts is None:
        opts = {}

    targets = []
    info = mrt.naming.parse_filename(sources[0])
    if 'ProtocolName' in params:
        info['name'] = params['ProtocolName']
    for image_type in opts['types']:
        info['type'] = image_type
        targets.append(os.path.join(out_dirpath, mrt.naming.to_filename(info)))

    # perform the calculation
    if fc.check_redo(sources, targets, force):
        if verbose > VERB_LVL['none']:
            print('{}:\t{}'.format('Object', os.path.basename(info['name'])))
        if verbose >= VERB_LVL['medium']:
            print('Opts:\t{}'.format(json.dumps(opts)))
        images, affines = [], []
        mask = tuple((slice(*dim) if dim is not None else slice(None))
                     for dim in opts['mask'])
        for source in sources:
            if verbose > VERB_LVL['none']:
                print('Source:\t{}'.format(os.path.basename(source)))
            if verbose > VERB_LVL['none']:
                print('Params:\t{}'.format(params))
            image, affine, header = mrt.input_output.load(source, meta=True)
            # fix mask if shapes are different
            if opts['adapt_mask']:
                mask = tuple((mask[i] if i < len(mask) else slice(None))
                             for i in range(len(image.shape)))
            images.append(image[mask])
            affines.append(affine)
        if 'compute_func' in opts:
            compute_func = eval(opts['compute_func'])
            if 'compute_args' not in opts:
                opts['compute_args'] = []
            if 'compute_kwargs' not in opts:
                opts['compute_kwargs'] = {}
            img_list, aff_list, img_type_list, params_list = compute_func(
                images, affines, params, *opts['compute_args'],
                **opts['compute_kwargs'])
        else:
            img_list, aff_list, img_type_list = zip(
                *[(img, aff, img_type) for img, aff, img_type in zip(
                    images, affines, itertools.cycle(opts['types']))])
            params_list = ({}, ) * len(img_list)

        for target, target_type in zip(targets, opts['types']):
            for img, aff, img_type, params in \
                    zip(img_list, aff_list, img_type_list, params_list):
                if img_type == target_type:
                    if 'dtype' in opts:
                        img = img.astype(opts['dtype'])
                    if params:
                        for key, val in params.items():
                            target = mrt.naming.change_param_val(
                                target, key, val)
                    if verbose > VERB_LVL['none']:
                        print('Target:\t{}'.format(os.path.basename(target)))
                    mrt.input_output.save(target, img, affine=aff)
                    break
    return targets
Пример #6
0
def batch_extract(
        dirpath,
        out_filename='niz/{scan_num}__{acq_method}_{scan_name}_{reco_flag}',
        out_dirpath=None,
        custom_reco=None,
        custom_reco_kws=None,
        fid_name='fid',
        dseq_name='2dseq',
        acqp_name='acqp',
        method_name='method',
        reco_name='reco',
        allowed_ext=('', 'gz'),
        force=False,
        verbose=D_VERB_LVL):
    """
    Extract images from experiment folder.

    EXPERIMENTAL!

    Args:
        dirpath (str):
        out_filename (str|None):
        out_dirpath (str|None):
        custom_reco (str|None):
            Determines how results will be saved.
            Accepted values are:
             - 'mag_phs': saves magnitude and phase.
             - 're_im': saves real and imaginary parts.
             - 'cx': saves the complex data.
        custom_reco_kws (Mappable|None):
        fid_name ():
        dseq_name ():
        acqp_name ():
        method_name ():
        reco_name ():
        allowed_ext ():
        force ():
        verbose ():

    Returns:

    """
    text = '\n'.join(
        ('EXPERIMENTAL!', 'Use at your own risk!', 'Known issues:',
         ' - orientation not adjusted to method (i.e. 0->RO, 1->PE, 2->SL)',
         ' - FOV is centered out', ' - voxel size is not set', ''))
    warnings.warn(text)

    if allowed_ext is None:
        allowed_ext = ''
    elif isinstance(allowed_ext, str):
        allowed_ext = (allowed_ext, )
    fid_filepaths = sorted(
        fc.flistdir(_to_patterns(fid_name, allowed_ext), dirpath))

    for fid_filepath in sorted(fid_filepaths):
        msg('FID: {}'.format(fid_filepath), verbose, D_VERB_LVL)
        fid_dirpath = os.path.dirname(fid_filepath)
        if out_dirpath is None:
            out_dirpath = dirpath
        out_filepath = os.path.join(out_dirpath, out_filename)

        acqp_filepath = _get_single(fid_dirpath, acqp_name, allowed_ext)
        method_filepath = _get_single(fid_dirpath, method_name, allowed_ext)

        dseq_filepaths = sorted(
            fc.flistdir(_to_patterns(dseq_name, allowed_ext), fid_dirpath))
        reco_filepaths = sorted(
            fc.flistdir(_to_patterns(reco_name, allowed_ext), fid_dirpath))

        acqp_s, acqp, acqp_c = jcampdx.read(acqp_filepath)
        method_s, method, method_c = jcampdx.read(method_filepath)
        scan_num, sample_id = _get_scan_num_sample_id(acqp_c)
        scan_name = fc.safe_filename(acqp['ACQ_scan_name'])
        acq_method = fc.safe_filename(acqp['ACQ_method'])
        reco_flag = mrt.naming.NEW_RECO_ID

        if custom_reco:
            load_info = _get_load_bin_info_fid(acqp, method)

            if custom_reco == 'cx':
                reco_flag = mrt.naming.ITYPES['cx']
                cx_filepath = fc.change_ext(fmtm(out_filepath),
                                            mrt.util.EXT['niz'])
                if not os.path.isdir(os.path.dirname(cx_filepath)):
                    os.makedirs(os.path.dirname(cx_filepath))

                if fc.check_redo(
                    [fid_filepath, acqp_filepath, method_filepath],
                    [cx_filepath], force):
                    arr = _load_bin(fid_filepath, **load_info)
                    arr = _reco_from_fid(arr, acqp, method, verbose=verbose)
                    mrt.input_output.save(cx_filepath, arr)
                    msg('CX:  {}'.format(os.path.basename(cx_filepath)),
                        verbose, D_VERB_LVL)

            elif custom_reco == 'mag_phs':
                reco_flag = mrt.naming.ITYPES['mag']
                mag_filepath = fc.change_ext(fmtm(out_filepath),
                                             mrt.util.EXT['niz'])
                if not os.path.isdir(os.path.dirname(mag_filepath)):
                    os.makedirs(os.path.dirname(mag_filepath))

                reco_flag = mrt.naming.ITYPES['phs']
                phs_filepath = fc.change_ext(fmtm(out_filepath),
                                             mrt.util.EXT['niz'])
                if not os.path.isdir(os.path.dirname(phs_filepath)):
                    os.makedirs(os.path.dirname(phs_filepath))

                if fc.check_redo(
                    [fid_filepath, acqp_filepath, method_filepath],
                    [mag_filepath, phs_filepath], force):
                    reco_flag = mrt.naming.ITYPES['mag']

                    arr = _load_bin(fid_filepath, **load_info)
                    arr = _reco_from_fid(arr, acqp, method, verbose=verbose)
                    mrt.input_output.save(mag_filepath, np.abs(arr))
                    msg('MAG: {}'.format(os.path.basename(mag_filepath)),
                        verbose, D_VERB_LVL)
                    mrt.input_output.save(phs_filepath, np.angle(arr))
                    msg('PHS: {}'.format(os.path.basename(phs_filepath)),
                        verbose, D_VERB_LVL)

            elif custom_reco == 're_im':
                reco_flag = mrt.naming.ITYPES['re']
                re_filepath = fc.change_ext(fmtm(out_filepath),
                                            mrt.util.EXT['niz'])
                if not os.path.isdir(os.path.dirname(re_filepath)):
                    os.makedirs(os.path.dirname(re_filepath))

                reco_flag = mrt.naming.ITYPES['im']
                im_filepath = fc.change_ext(fmtm(out_filepath),
                                            mrt.util.EXT['niz'])
                if not os.path.isdir(os.path.dirname(im_filepath)):
                    os.makedirs(os.path.dirname(im_filepath))

                if fc.check_redo(
                    [fid_filepath, acqp_filepath, method_filepath],
                    [re_filepath, im_filepath], force):
                    arr = _load_bin(fid_filepath, **load_info)
                    arr = _reco_from_fid(arr, acqp, method, verbose=verbose)
                    mrt.input_output.save(re_filepath, np.abs(arr))
                    msg('RE: {}'.format(os.path.basename(re_filepath)),
                        verbose, D_VERB_LVL)
                    mrt.input_output.save(im_filepath, np.angle(arr))
                    msg('IM: {}'.format(os.path.basename(im_filepath)),
                        verbose, D_VERB_LVL)

        else:
            text = 'Voxel data and shapes may be incorrect.'
            warnings.warn(text)
            for dseq_filepath, reco_filepath \
                    in zip(dseq_filepaths, reco_filepaths):
                reco_s, reco, reco_c = jcampdx.read(reco_filepath)
                reco_flag = _get_reco_num(reco_c)

                cx_filepath = fc.change_ext(fmtm(out_filepath),
                                            mrt.util.EXT['niz'])
                if not os.path.isdir(os.path.dirname(cx_filepath)):
                    os.makedirs(os.path.dirname(cx_filepath))

                load_info = _get_load_bin_info_reco(reco, method)

                if fc.check_redo([dseq_filepath, reco_filepath], [cx_filepath],
                                 force):
                    arr = _load_bin(dseq_filepath, **load_info)
                    arr = _reco_from_bin(arr, reco, method, verbose=verbose)
                    mrt.input_output.save(cx_filepath, arr)
                    msg('NIZ: {}'.format(os.path.basename(cx_filepath)),
                        verbose, D_VERB_LVL)
Пример #7
0
def wip():
    # one-step QSM.. need for bias field removal?
    # convert input angles to radians
    # theta = np.deg2rad(theta)
    # phi = np.deg2rad(phi)
    #
    # k_x, k_y, k_z = coord(arr_cx.shape)
    # k_2 = (k_x ** 2 + k_y ** 2 + k_z ** 2)
    # cc = (k_z * np.cos(theta) * np.cos(phi) -
    #       k_y * np.sin(theta) * np.cos(phi) +
    #       k_x * np.sin(phi)) ** 2
    # dd = 1 / (k_2 - cc)
    # dd = subst(dd)
    # chi_arr = np.abs(idftn(3 * k_2 * dd * dftn(phs_arr)))

    import os
    import datetime
    import pymrt.input_output

    begin_time = datetime.datetime.now()

    force = False

    base_path = '/home/raid1/metere/hd3/cache/qsm_coil_reco/COIL_RECO/' \
                'HJJT161103_nifti/0091_as_gre_nifti_TE17ms'

    mag_filepath = os.path.join(base_path, 'bai_mag.nii.gz')
    phs_filepath = os.path.join(base_path, 'bai_phs.nii.gz')
    msk_filepath = os.path.join(base_path, 'mask.nii.gz')

    mag_arr, meta = mrt.input_output.load(mag_filepath, meta=True)
    phs_arr = mrt.input_output.load(phs_filepath)
    msk_arr = mrt.input_output.load(msk_filepath).astype(bool)

    uphs_filepath = os.path.join(base_path, 'bai_uphs.nii.gz')
    if fc.check_redo(phs_filepath, uphs_filepath, force):
        from pymrt.recipes import phs

        uphs_arr = phs.unwrap(phs_arr)
        mrt.input_output.save(uphs_filepath, uphs_arr)
    else:
        uphs_arr = mrt.input_output.load(uphs_filepath)

    dphs_filepath = os.path.join(base_path, 'bai_dphs.nii.gz')
    if fc.check_redo(phs_filepath, dphs_filepath, force):
        from pymrt.recipes import phs

        dphs_arr = phs.phs_to_dphs(phs_arr, 20.0)
        mrt.input_output.save(dphs_filepath, uphs_arr)
    else:
        dphs_arr = mrt.input_output.load(dphs_filepath)

    db0_filepath = os.path.join(base_path, 'bai_db0.nii.gz')
    if fc.check_redo(dphs_filepath, db0_filepath, force):
        from pymrt.recipes import db0

        db0_arr = db0.dphs_to_db0(dphs_arr, b0=2.89362)
        mrt.input_output.save(db0_filepath, db0_arr)
    else:
        db0_arr = mrt.input_output.load(db0_filepath)

    # milf_filepath = os.path.join(base_path, 'bai_db0i_milf.nii.gz')
    # if fc.check_redo(db0_filepath, milf_filepath, force):
    #     from pymrt.recipes import phs
    #
    #     milf_arr = qsm_remove_background_milf(uphs_arr, msk_arr)
    #     mrt.input_output.save(milf_filepath, milf_arr)
    #     msg('MILF')
    # else:
    #     milf_arr = mrt.input_output.load(milf_filepath)

    # sharp_filepath = os.path.join(base_path, 'bai_db0i_sharp.nii.gz')
    # if fc.check_redo(uphs_filepath, sharp_filepath, force):
    #     from pymrt.recipes import phs
    #     import scipy.ndimage
    #
    #     radius = 5
    #     mask_arr = sp.ndimage.binary_erosion(msk_arr, iterations=radius * 4)
    #     sharp_arr = qsm_remove_background_sharp(
    #         uphs_arr, mask_arr, radius, rel_radius=False)
    #     mrt.input_output.save(sharp_filepath, sharp_arr)
    #     msg('SHARP')
    # else:
    #     sharp_arr = mrt.input_output.load(sharp_filepath)

    chi_filepath = os.path.join(base_path, 'bai_chi_ptfi_minres_i0128.nii.gz')
    if fc.check_redo(db0_filepath, chi_filepath, force):
        from pymrt.recipes import db0

        mask = mag_arr > 0.5
        w_arr = mag_arr**2
        # 1 / (chi_x / chi_water)
        # non-water is assumed to be air
        pc_arr = np.full(mag_arr.shape, abs(CHI_V['water'] / CHI_V['air']))
        # mask is assumed to be mostly water
        pc_arr[mask] = abs(CHI_V['water'] / CHI_V['water'])

        chi_arr = qsm_total_field_inversion(db0_arr,
                                            w_arr,
                                            msk_arr,
                                            pc_arr,
                                            linsolve_iter_kws=dict(
                                                method='minres', max_iter=128))
        mrt.input_output.save(chi_filepath, chi_arr)
    else:
        chi_arr = mrt.input_output.load(chi_filepath)

    # chi_filepath = os.path.join(base_path, 'bai_chi_tfi_lsmr.nii.gz')
    # if fc.check_redo(db0_filepath, chi_filepath, force):
    #     from pymrt.recipes import db0
    #
    #     chi_arr = qsm_total_field_inversion(
    #         db0_arr, mag_arr, msk_arr,
    #         linsolve_iter_kws=dict(method='lsmr', max_iter=256))
    #     mrt.input_output.save(chi_filepath, chi_arr)
    # else:
    #     chi_arr = mrt.input_output.load(chi_filepath)

    msg('TotTime: {}'.format(datetime.datetime.now() - begin_time))