def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    try:
        devnull = open(os.devnull)
        subprocess.call(args.eddy_cmd, stderr=devnull)
    except:
        parser.error("Please download the {} command.".format(args.eddy_cmd))

    if args.verbose:
        logging.basicConfig(level=logging.INFO)

    required_args = [args.input_dwi, args.bvals, args.bvecs, args.mask]

    assert_inputs_exist(parser, required_args)

    if os.path.splitext(args.output_prefix)[1] != '':
        parser.error('The prefix must not contain any extension.')

    bvals, bvecs = read_bvals_bvecs(args.bvals, args.bvecs)
    bvals_min = bvals.min()
    b0_threshold = args.b0_thr
    if bvals_min < 0 or bvals_min > b0_threshold:
        raise ValueError('The minimal b-value is lesser than 0 or greater '
                         'than {0}. This is highly suspicious. Please check '
                         'your data to ensure everything is correct. '
                         'Value found: {1}'.format(b0_threshold, bvals_min))

    gtab = gradient_table(bvals, bvecs, b0_threshold=b0_threshold)

    acqparams = create_acqparams(gtab, args.readout, args.encoding_direction)
    index = create_index(bvals)
    bvecs = create_non_zero_norm_bvecs(bvecs)

    if not os.path.exists(args.output_directory):
        os.makedirs(args.output_directory)

    acqparams_path = os.path.join(args.output_directory, 'acqparams.txt')
    np.savetxt(acqparams_path, acqparams, fmt='%1.4f', delimiter=' ')
    bvecs_path = os.path.join(args.output_directory, 'non_zero_norm.bvecs')
    np.savetxt(bvecs_path, bvecs.T, fmt="%.8f")
    index_path = os.path.join(args.output_directory, 'index.txt')
    np.savetxt(index_path, index, fmt='%i', newline=" ")

    additional_args = ""
    if args.topup is not None:
        additional_args += "--topup={} ".format(args.topup)

    if args.slice_drop_correction:
        additional_args += "--repol "

    if args.fix_seed:
        additional_args += "--initrand "

    output_path = os.path.join(args.output_directory, args.output_prefix)
    eddy = '{0} --imain={1} --mask={2} --acqp={3} --index={4}' \
           ' --bvecs={5} --bvals={6} --out={7} --data_is_shelled {8}' \
        .format(args.eddy_cmd, args.input_dwi, args.mask, acqparams_path,
                index_path, bvecs_path, args.bvals, output_path,
                additional_args)

    if args.output_script:
        with open("eddy.sh", 'w') as f:
            f.write(eddy)
    else:
        print(eddy)
Example #2
0
def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    try:
        devnull = open(os.devnull)
        subprocess.call("topup", stderr=devnull)
    except:
        logging.warning(
            "topup not found. If executing locally, please install "
            "the command from the FSL library and make sure it is "
            "available in your path.")

    if args.verbose:
        logging.basicConfig(level=logging.INFO)

    required_args = [args.in_forward_b0, args.in_reverse_b0]

    assert_inputs_exist(parser, required_args)
    assert_outputs_exist(parser, args, [], args.out_b0s)
    assert_fsl_options_exist(parser, args.topup_options, 'topup')

    if os.path.splitext(args.out_prefix)[1] != '':
        parser.error('The prefix must not contain any extension.')

    b0_img = nib.load(args.in_forward_b0)
    b0 = b0_img.get_fdata(dtype=np.float32)

    if len(b0.shape) == 4 and b0.shape[3] > 1:
        logging.warning("B0 is 4D. To speed up Topup, we recommend "
                        "using only one b0 in both phase encoding "
                        "direction, unless necessary.")
    elif len(b0.shape) == 3:
        b0 = b0[..., None]

    rev_b0_img = nib.load(args.in_reverse_b0)
    rev_b0 = rev_b0_img.get_fdata(dtype=np.float32)

    if len(rev_b0.shape) == 4 and rev_b0.shape[3] > 1:
        logging.warning("Reverse B0 is 4D. To speed up Topup, we "
                        "recommend using only one b0 in both phase "
                        "encoding direction, unless necessary.")
    elif len(rev_b0.shape) == 3:
        rev_b0 = rev_b0[..., None]

    fused_b0s = np.concatenate((b0, rev_b0), axis=-1)
    fused_b0s_path = os.path.join(args.out_directory, args.out_b0s)
    nib.save(nib.Nifti1Image(fused_b0s, b0_img.affine), fused_b0s_path)

    acqparams = create_acqparams(args.readout, args.encoding_direction,
                                 b0.shape[-1], rev_b0.shape[-1])

    if not os.path.exists(args.out_directory):
        os.makedirs(args.out_directory)

    acqparams_path = os.path.join(args.out_directory, args.out_params)
    np.savetxt(acqparams_path, acqparams, fmt='%1.4f', delimiter=' ')

    output_path = os.path.join(args.out_directory, args.out_prefix)
    fout_path = os.path.join(args.out_directory, "correction_field")
    iout_path = os.path.join(args.out_directory, "corrected_b0s")

    additional_args = ""
    if args.topup_options:
        additional_args = args.topup_options

    topup = 'topup --imain={0} --datain={1}'\
            ' --config={2} --verbose --out={3}'\
            ' --fout={4} --iout={5} --subsamp=1 {6}\n'\
        .format(fused_b0s_path, acqparams_path, args.config, output_path,
                fout_path, iout_path, additional_args)

    if args.out_script:
        with open("topup.sh", 'w') as f:
            f.write(topup)
    else:
        print(topup)
Example #3
0
def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    try:
        devnull = open(os.devnull)
        subprocess.call(args.eddy_cmd, stderr=devnull)
    except:
        logging.warning("{} not found. If executing locally, please install "
                        "the command from the FSL library and make sure it is "
                        "available in your path.".format(args.eddy_cmd))

    if args.verbose:
        logging.basicConfig(level=logging.INFO)

    required_args = [args.in_dwi, args.in_bvals, args.in_bvecs, args.in_mask]

    assert_inputs_exist(parser, required_args)
    assert_fsl_options_exist(parser, args.eddy_options, 'eddy')

    if os.path.splitext(args.out_prefix)[1] != '':
        parser.error('The prefix must not contain any extension.')

    if args.n_reverse and not args.lsr_resampling:
        logging.warning(
            'Multiple reverse phase images supplied, but least-square '
            'resampling is disabled. If the reverse phase image was acquired '
            'with the same sampling as the forward phase image, '
            'use --lsr_resampling for better results from Eddy.')

    bvals, bvecs = read_bvals_bvecs(args.in_bvals, args.in_bvecs)
    bvals_min = bvals.min()
    b0_threshold = args.b0_thr
    if bvals_min < 0 or bvals_min > b0_threshold:
        raise ValueError('The minimal b-value is lesser than 0 or greater '
                         'than {0}. This is highly suspicious. Please check '
                         'your data to ensure everything is correct. '
                         'Value found: {1}'.format(b0_threshold, bvals_min))

    n_rev = args.n_reverse

    if args.topup_params:
        acqparams = np.loadtxt(args.topup_params)

        if acqparams.shape[0] == 2:
            index = create_index(bvals, n_rev=n_rev)
        elif acqparams.shape[0] == np.sum(bvals <= b0_threshold):
            index = create_multi_topup_index(bvals, 'none', n_rev,
                                             b0_threshold)
        else:
            b_mask = np.ma.array(bvals, mask=[bvals > b0_threshold])
            n_b0_clusters = len(np.ma.clump_unmasked(b_mask[:n_rev])) + \
                len(np.ma.clump_unmasked(b_mask[n_rev:]))
            if acqparams.shape[0] == n_b0_clusters:
                index = create_multi_topup_index(bvals, 'cluster', n_rev,
                                                 b0_threshold)
            else:
                raise ValueError('Could not determine a valid index file '
                                 'from the provided acquisition parameters '
                                 'file: {}'.format(args.topup_params))
    else:
        acqparams = create_acqparams(args.readout,
                                     args.encoding_direction,
                                     nb_rev_b0s=int(n_rev > 0))

        index = create_index(bvals, n_rev=n_rev)

    bvecs = create_non_zero_norm_bvecs(bvecs)

    if not os.path.exists(args.out_directory):
        os.makedirs(args.out_directory)

    acqparams_path = os.path.join(args.out_directory, 'acqparams.txt')
    np.savetxt(acqparams_path, acqparams, fmt='%1.4f', delimiter=' ')
    index_path = os.path.join(args.out_directory, 'index.txt')
    np.savetxt(index_path, index, fmt='%i', newline=" ")
    bvecs_path = os.path.join(args.out_directory, 'non_zero_norm.bvecs')
    np.savetxt(bvecs_path, bvecs.T, fmt="%.8f")

    additional_args = ""
    if args.topup is not None:
        additional_args += "--topup={} ".format(args.topup)

    if args.slice_drop_correction:
        additional_args += "--repol "

    if args.fix_seed:
        additional_args += "--initrand "

    if args.lsr_resampling:
        if len(bvals) - n_rev == n_rev:
            forward_bb = bvals[:n_rev, None] * bvecs[:n_rev, :]
            reverse_bb = bvals[n_rev:, None] * bvecs[n_rev:, :]
            if np.allclose(forward_bb, reverse_bb):
                additional_args += "--resamp=lsr --fep=true "
            else:
                logging.warning('Least-square resampling disabled since '
                                'directions in both phase directions differ.')
        else:
            logging.warning('Least-square resampling disabled since number of '
                            'directions in both phase directions differ.')

    if args.eddy_options:
        additional_args += args.eddy_options

    output_path = os.path.join(args.out_directory, args.out_prefix)
    eddy = '{0} --imain={1} --mask={2} --acqp={3} --index={4}' \
           ' --bvecs={5} --bvals={6} --out={7} --data_is_shelled {8}' \
        .format(args.eddy_cmd, args.in_dwi, args.in_mask, acqparams_path,
                index_path, bvecs_path, args.in_bvals, output_path,
                additional_args)

    if args.out_script:
        with open("eddy.sh", 'w') as f:
            f.write(eddy)
    else:
        print(eddy)
def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.INFO)

    required_args = [args.input_dwi, args.bvals, args.bvecs, args.reverse_b0]

    assert_inputs_exist(parser, required_args)
    assert_outputs_exist(parser, args, [], args.output_b0s)

    if os.path.splitext(args.output_prefix)[1] != '':
        parser.error('The prefix must not contain any extension.')

    bvals, bvecs = read_bvals_bvecs(args.bvals, args.bvecs)
    bvals_min = bvals.min()

    # TODO refactor this
    b0_threshold = args.b0_thr
    if bvals_min < 0 or bvals_min > b0_threshold:
        raise ValueError('The minimal b-value is lesser than 0 or greater '
                         'than {0}. This is highly suspicious. Please check '
                         'your data to ensure everything is correct. '
                         'Value found: {1}'.format(b0_threshold, bvals_min))

    gtab = gradient_table(bvals, bvecs, b0_threshold=b0_threshold)

    acqparams = create_acqparams(gtab, args.readout, args.encoding_direction)

    if not os.path.exists(args.output_directory):
        os.makedirs(args.output_directory)

    acqparams_path = os.path.join(args.output_directory, 'acqparams.txt')
    np.savetxt(acqparams_path, acqparams, fmt='%1.4f', delimiter=' ')

    rev_b0_img = nib.load(args.reverse_b0)
    rev_b0 = rev_b0_img.get_data()

    dwi_image = nib.load(args.input_dwi)
    dwi = dwi_image.get_data()
    b0s = dwi[..., gtab.b0s_mask]

    b0_idx = np.where(gtab.b0s_mask)[0]
    fused_b0s = np.zeros(b0s.shape[:-1] + (len(b0_idx) + 1, ))
    fused_b0s[..., 0:-1] = b0s
    fused_b0s[..., -1] = rev_b0
    fused_b0s_path = os.path.join(args.output_directory, args.output_b0s)
    nib.save(nib.Nifti1Image(fused_b0s, rev_b0_img.affine), fused_b0s_path)

    output_path = os.path.join(args.output_directory, args.output_prefix)
    fout_path = os.path.join(args.output_directory, "correction_field")
    iout_path = os.path.join(args.output_directory, "corrected_b0s")
    topup = 'topup --imain={0} --datain={1}'\
            ' --config={2} --verbose --out={3}'\
            ' --fout={4} --iout={5} --subsamp=1 \n'\
        .format(fused_b0s_path, acqparams_path, args.config, output_path,
                fout_path, iout_path)

    if args.output_script:
        with open("topup.sh", 'w') as f:
            f.write(topup)
    else:
        print(topup)
def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.INFO)

    required_args = [args.in_dwi, args.in_bvals, args.in_bvecs,
                     args.in_reverse_b0]

    assert_inputs_exist(parser, required_args)
    assert_outputs_exist(parser, args, [], args.out_b0s)

    if os.path.splitext(args.out_prefix)[1] != '':
        parser.error('The prefix must not contain any extension.')

    bvals, bvecs = read_bvals_bvecs(args.in_bvals, args.in_bvecs)
    bvals_min = bvals.min()

    # TODO refactor this
    b0_threshold = args.b0_thr
    if bvals_min < 0 or bvals_min > b0_threshold:
        raise ValueError('The minimal b-value is lesser than 0 or greater '
                         'than {0}. This is highly suspicious. Please check '
                         'your data to ensure everything is correct. '
                         'Value found: {1}'.format(b0_threshold, bvals_min))

    rev_b0_img = nib.load(args.in_reverse_b0)
    rev_b0 = rev_b0_img.get_fdata(dtype=np.float32)

    if len(rev_b0.shape) == 4:
        logging.warning("Reverse B0 is 4D. To speed up Topup, the mean of all "
                        "reverse B0 will be taken.")
        rev_b0 = np.mean(rev_b0, axis=3)

    gtab = gradient_table(bvals, bvecs, b0_threshold=b0_threshold)

    dwi_image = nib.load(args.in_dwi)
    dwi = dwi_image.get_fdata(dtype=np.float32)
    b0 = dwi[..., gtab.b0s_mask]

    if b0.shape[3] > 1:
        logging.warning("More than one B0 was found. To speed up Topup, "
                        "the mean of all B0 will be taken.")
        b0 = np.mean(b0, axis=3)
    else:
        b0 = np.squeeze(b0, axis=3)

    fused_b0s = np.zeros(b0.shape+(2,))
    fused_b0s[..., 0] = b0
    fused_b0s[..., 1] = rev_b0
    fused_b0s_path = os.path.join(args.out_directory, args.out_b0s)
    nib.save(nib.Nifti1Image(fused_b0s,
                             rev_b0_img.affine),
             fused_b0s_path)

    acqparams = create_acqparams(args.readout, args.encoding_direction)

    if not os.path.exists(args.out_directory):
        os.makedirs(args.out_directory)

    acqparams_path = os.path.join(args.out_directory, 'acqparams.txt')
    np.savetxt(acqparams_path, acqparams, fmt='%1.4f', delimiter=' ')

    output_path = os.path.join(args.out_directory, args.out_prefix)
    fout_path = os.path.join(args.out_directory, "correction_field")
    iout_path = os.path.join(args.out_directory, "corrected_b0s")
    topup = 'topup --imain={0} --datain={1}'\
            ' --config={2} --verbose --out={3}'\
            ' --fout={4} --iout={5} --subsamp=1 \n'\
        .format(fused_b0s_path, acqparams_path, args.config, output_path,
                fout_path, iout_path)

    if args.out_script:
        with open("topup.sh", 'w') as f:
            f.write(topup)
    else:
        print(topup)