Пример #1
0
def ptk_gis_to_nifti(gis, nifti, nb_tries=10):
    """
    Function that wraps the PtkGis2NiftiConverter command line tool from
    Connectomist to make it capsul-isable.

    Parameters
    ----------
    gis: str
        path to the Gis .ima file.
    nifti: str
        path to the output Nifti file.
    nb_tries: int (optional, default 10)
        number of times to try the conversion. It often fails
        when using parallel processing.

    Returns
    -------
    nifti: str
        path to output file.

    Raises
    ------
    ConnectomistError: If call to PtkGis2NiftiConverter failed nb_tries times.
    """
    # Check input existence
    if not os.path.isfile(gis):
        raise ConnectomistBadFileError(gis)

    # The command line tool does not handle .gz properly
    compress_to_gz = False
    if nifti.endswith(".gz"):
        nifti = nifti[:-3]  # remove ".gz"
        compress_to_gz = True

    # Add .nii extension if not the case
    if not nifti.endswith(".nii"):
        nifti += ".nii"

    # Call command line tool:
    # it creates a Nifti + a .minf file (metainformation)
    cmd = [
        "PtkGis2NiftiConverter", "-i", gis, "-o", nifti, "-verbose", "False",
        "-verbosePluginLoading", "False"
    ]
    files_to_check = [nifti]
    ptkprocess = PtkWrapper(cmd)
    ptkprocess(files_to_check, nb_tries=nb_tries)

    # Compress to nifti if requested
    if compress_to_gz:
        nifti = gz_compress(nifti)

    return nifti
Пример #2
0
def gz_compress(file_to_compress, clean=True):
    """
    Compress a file with gzip, the output path is the same but with
    ".gz" extension.

    The function raises ConnectomistBadFileError if the input file does not
    exist or if the output compressed file is not created.

    Parameters
    ----------
    file_to_compress: str
        the file to compress.
    clean: bool (optional, default True)
        If 'clean' is True, the input file is deleted, to keep only the
        compressed version.

    Returns
    -------
    gz_file: str
        the compressed output file.
    """
    # Check if the input file exists
    if not os.path.isfile(file_to_compress):
        raise ConnectomistBadFileError(file_to_compress)

    # Zip the input file
    gz_file = file_to_compress + ".gz"
    with open(file_to_compress, 'rb') as f_in, \
            gzip.open(gz_file, 'wb') as f_out:
        shutil.copyfileobj(f_in, f_out)
    if clean:
        os.remove(file_to_compress)
    if not os.path.isfile(gz_file):
        raise ConnectomistBadFileError(gz_file)

    return gz_file
Пример #3
0
def ptk_concatenate_volumes(path_inputs, path_output, axis="t", nb_tries=10):
    """
    Function that wraps the PtkCat command line tool from Connectomist, with
    only the basic arguments. It allows concatenating volumes. In particular to
    concatenante T2 and DW volumes in one file at the end of the preprocessing.

    Parameters
    ----------
    path_inputs: list of str
        paths to input volumes.
    path_output: str
        path to output volume.
    axis: str (optional, default 't')
        axis along which the concatenation is done.
    nb_tries: int (optional, default 10)
        number of times to try the concatenation.
        The reason why it sometimes fails is not known.

    Returns
    -------
    path_output: str
        path to output gis volume.

    Raises
    ------
    ConnectomistError: If call to PtkCat failed.
    """
    # Check input existence
    for path in path_inputs:
        if not os.path.isfile(path):
            raise ConnectomistBadFileError(path)

    # Add extension if there is none
    if not path_output.endswith("ima"):
        path_output += ".ima"

    # Run command line tool
    cmd = ["PtkCat", "-i"] + path_inputs + [
        "-o", path_output, "-t", axis, "-verbose", "False",
        "-verbosePluginLoading", "False"
    ]
    files_to_check = [path_output]
    ptkprocess = PtkWrapper(cmd)
    ptkprocess(files_to_check, nb_tries=nb_tries)

    return path_output
Пример #4
0
def ptk_nifti_to_gis(nifti, gis, nb_tries=10):
    """
    Function that wraps the PtkNifti2GisConverter command line tool from
    Connectomist to make it capsul-isable.

    Parameters
    ----------
    nifti: str
        path to the input Nifti file to be converted.
    gis: str
        path without extension to the 3 output GIS files.
    nb_tries: int
        number of times to try the conversion. It often fails
        when using parallel processing.

    Returns
    -------
    gis: str
        path to the generated Gis file.

    Raises
    ------
    ConnectomistError: If call to PtkNifti2GisConverter failed nb_tries times.
    """
    # Check input existence
    if not os.path.isfile(nifti):
        raise ConnectomistBadFileError(nifti)

    # Add extension if there is none
    if not gis.endswith("ima"):
        gis += ".ima"

    # Call command line tool
    cmd = [
        "PtkNifti2GisConverter", "-i", nifti, "-o", gis, "-verbose", "False",
        "-verbosePluginLoading", "False"
    ]
    files_to_check = [gis]
    ptkprocess = PtkWrapper(cmd)
    ptkprocess(files_to_check, nb_tries=nb_tries)

    return gis
Пример #5
0
def tractography(outdir,
                 subjectid,
                 maskdir,
                 model,
                 modeldir,
                 registrationdir,
                 tracking_type="streamline_regularize_deterministic",
                 bundlemap="vtkbundlemap",
                 min_fiber_length=5.,
                 max_fiber_length=300.,
                 aperture_angle=30.,
                 forward_step=0.2,
                 voxel_sampler_point_count=1,
                 gibbs_temperature=1.,
                 storing_increment=10,
                 output_orientation_count=500,
                 nb_tries=10,
                 path_connectomist=(
                     "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """ Tractography algorithm.

    Parameters
    ----------
    outdir: str
        path to Connectomist output work directory.
    subjectid: str
        the subject code in study.
    model: str
        the name of the model to be estimated: 'dot', 'sd', 'sdt', 'aqbi',
        'sa-qbi', 'dti'.
    modeldir str
        the path to the Connectomist model directory.
    registrationdir str
        the path to the Connectomist registration directory.
    tracking_type: str (optional, default
            'streamline_regularize_deterministic')
        the tractography algorithm: 'streamline_regularize_deterministic',
        'streamline_deterministic' or 'streamline_probabilistic'
    bundlemap: str (optional, default 'vtkbundlemap')
        the bundle format.
    min_fiber_length: float (optional, default 5)
        the length threshold in mm from which fiber are considered.
    max_fiber_length: float (optional, default 300)
        the length threshold in mm under which fiber are considered.
    aperture_angle: float (optional, default 30)
        the search angle in degrees: for the probabilistic tractography,
        the default connectomist value is 90 degs.
    forward_step: float (optional, default 0.2)
        the propagation step in mm.
    voxel_sampler_point_count: int (optional, default 1)
        the number of seeds per voxel
    gibbs_temperature: float (optional, default 1)
        the temperature if the Gibb's sampler: only for the probabilistic
        tractography.
    storing_increment: int (optional, default 10)
        undersample the fiber with the specified rate.
    output_orientation_count: int (optional, default 500)
        the number of the point in the sphere, default is equivalent to a
        2 degs resolution.
    nb_tries: int (optional, default 10)
        nb of times to try an algorithm if it fails.
        It often crashes when running in parallel. The reason
        why it crashes is unknown.
    path_connectomist: str (optional)
        path to the Connectomist executable.

    Returns
    -------
    outdir: str
        path to Connectomist's output directory.
    """
    # Check input parameters
    if bundlemap not in bundle_map:
        raise ConnectomistError(
            "'{0}' is not a valid bundle format.".format(bundlemap))
    if tracking_type not in track_map:
        raise ConnectomistError(
            "'{0}' is not a valid track algo.".format(tracking_type))

    # Get previous steps files and check existance
    maskfile = os.path.join(maskdir, "tractography_mask.ima")
    odfsitefile = os.path.join(modeldir,
                               "{0}_odf_site_map.sitemap".format(model))
    odftexturefile = os.path.join(
        modeldir, "{0}_odf_texture_map.texturemap".format(model))
    odfrgbfile = os.path.join(modeldir, "aqbi_rgb.ima")
    t1file = os.path.join(registrationdir, "t1.ima")
    dwtot1file = os.path.join(registrationdir, "talairach_to_t1.trm")
    masktodwfile = os.path.join(registrationdir, "t1_to_talairach.trm")
    for fpath in (maskfile, odfsitefile, odftexturefile, odfrgbfile, t1file,
                  dwtot1file, masktodwfile):
        if not os.path.isfile(fpath):
            raise ConnectomistBadFileError(fpath)

    # Dict with all parameters for connectomist
    algorithm = "DWI-Tractography"
    parameters_dict = {
        '_subjectName': subjectid,
        'bundleMapFormat': bundle_map[bundlemap],
        'fileNameMask': maskfile,
        'fileNameOdfSiteMap': odfsitefile,
        'fileNameOdfTextureMap': odftexturefile,
        'fileNameRgb': odfrgbfile,
        'fileNameT1': t1file,
        'fileNameTransformationDwToT1': dwtot1file,
        'fileNameTransformationMaskToDw': masktodwfile,
        'outputOrientationCount': output_orientation_count,
        'outputWorkDirectory': outdir,
        'stepCount': 1,
        'trackingType': track_map[tracking_type]
    }
    parameters_dict.update({
        'deterministicApertureAngle':
        aperture_angle,
        'deterministicForwardStep':
        forward_step,
        'deterministicMaximumFiberLength':
        max_fiber_length,
        'deterministicMinimumFiberLength':
        min_fiber_length,
        'deterministicStoringIncrement':
        storing_increment,
        'deterministicVoxelSamplerPointCount':
        voxel_sampler_point_count
    })
    parameters_dict.update({
        'probabilisticApertureAngle':
        aperture_angle,
        'probabilisticForwardStep':
        forward_step,
        'probabilisticGibbsTemperature':
        gibbs_temperature,
        'probabilisticMaximumFiberLength':
        max_fiber_length,
        'probabilisticMinimumFiberLength':
        min_fiber_length,
        'probabilisticStoringIncrement':
        storing_increment,
        'probabilisticVoxelSamplerPointCount':
        voxel_sampler_point_count
    })
    parameters_dict.update({
        'regularizedDeterministicApertureAngle':
        aperture_angle,
        'regularizedDeterministicForwardStep':
        forward_step,
        'regularizedDeterministicLowerGFABoundary':
        -1.,
        'regularizedDeterministicMaximumFiberLength':
        max_fiber_length,
        'regularizedDeterministicMinimumFiberLength':
        min_fiber_length,
        'regularizedDeterministicStoringIncrement':
        storing_increment,
        'regularizedDeterministicUpperGFABoundary':
        -1.,
        'regularizedDeterministicVoxelSamplerPointCount':
        (voxel_sampler_point_count)
    })

    # Call with Connectomist
    connprocess = ConnectomistWrapper(path_connectomist)
    parameter_file = ConnectomistWrapper.create_parameter_file(
        algorithm, parameters_dict, outdir)
    connprocess(algorithm, parameter_file, outdir, nb_tries=nb_tries)

    return outdir
Пример #6
0
def ptk_split_t2_and_diffusion(t2_dw_input, t2_output, dw_output, nb_tries=10):
    """
    Function meant to split a Gis file containing a T2 volume (first volume)
    and diffusion-weigthed volumes (the other volumes) in 2 Gis files.
    The separation is done using the PtkSubVolume command line tool from
    Connectomist.

    Parameters
    ----------
    t2_dw_input: str
        path to input volume.
    t2_output: str
        path to output T2 volume.
    dw_output: str
        path to output diffusion-weighted volumes.
    nb_tries: int
        number of times to try the separation. The reason why it sometimes
        fails is not known.

    Returns
    -------
    t2_output: str
        the t2 diffusion Gis volume.
    dw_output: str
        the diffusion weighted Gis volume.

    Raises
    ------
    ConnectomistError: If call to PtkSubVolume failed.
    """
    # Check input existence
    if not os.path.isfile(t2_dw_input):
        raise ConnectomistBadFileError(t2_dw_input)

    # Check that input is a Gis file
    if not t2_dw_input.endswith(".ima"):
        raise ConnectomistBadFileError(t2_dw_input)

    # Set the Gis extension to output file
    if not t2_output.endswith(".ima"):
        t2_output += ".ima"
    if not dw_output.endswith(".ima"):
        dw_output += ".ima"

    # Step 1 - extract the T2 (nodif volume), assuming only one volume with
    # bvalue=0
    cmd_t2 = [
        "PtkSubVolume", "-i", t2_dw_input, "-o", t2_output, "-tIndices", "0",
        "-verbose", "false", "-verbosePluginLoading", "false"
    ]
    files_to_check = [t2_output]
    ptkprocess = PtkWrapper(cmd_t2)
    ptkprocess(files_to_check, nb_tries=nb_tries)

    # Step 2 - extract the diffusion volumes
    # assuming only all volumes except the first one are diffusion-weighted
    cmd_dw = [
        "PtkSubVolume", "-i", t2_dw_input, "-o", dw_output, "-t", "1",
        "-verbose", "false", "-verbosePluginLoading", "false"
    ]
    files_to_check = [dw_output]
    ptkprocess = PtkWrapper(cmd_dw)
    ptkprocess(files_to_check, nb_tries=nb_tries)

    return t2_output, dw_output
Пример #7
0
def dwi_to_anatomy(
    outdir,
    corrected_dwi_dir,
    rough_mask_dir,
    morphologist_dir,
    subjectid,
    nb_tries=10,
    path_connectomist=(
        "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """

    Parameters
    ----------
    outdir: str
        path to Connectomist output work directory.
    corrected_dwi_dir: str
        path to Connectomist Corrected DWI directory.
    rough_mask_dir: str
        path to Connectomist Rough Mask directory.
    morphologist_dir: str
        path to Morphologist directory.
    subjectid: str
        the subject code in study.
    nb_tries: int (optional, default 10)
        nb of times to try an algorithm if it fails.
        It often crashes when running in parallel. The reason
        why it crashes is unknown.
    path_connectomist: str (optional)
        path to the Connectomist executable.

    Returns
    -------
    outdir: str
        path to Connectomist's output directory.
    """
    # Get morphologist result files and check existance
    apcfile = os.path.join(morphologist_dir, subjectid, "t1mri",
                           "default_acquisition", "{0}.APC".format(subjectid))
    t1file = os.path.join(morphologist_dir, subjectid, "t1mri",
                          "default_acquisition",
                          "{0}.nii.gz".format(subjectid))
    for fpath in (apcfile, t1file):
        if not os.path.isfile(fpath):
            raise ConnectomistBadFileError(fpath)

    # Dict with all parameters for connectomist
    algorithm = "DWI-To-Anatomy-Matching"
    parameters_dict = {
        'dwToT1RegistrationParameter': {
            'applySmoothing': 1,
            'floatingLowerThreshold': 0.0,
            'initialParametersRotationX': 0,
            'initialParametersRotationY': 0,
            'initialParametersRotationZ': 0,
            'initialParametersScalingX': 1.0,
            'initialParametersScalingY': 1.0,
            'initialParametersScalingZ': 1.0,
            'initialParametersShearingXY': 0.0,
            'initialParametersShearingXZ': 0.0,
            'initialParametersShearingYZ': 0.0,
            'initialParametersTranslationX': 0,
            'initialParametersTranslationY': 0,
            'initialParametersTranslationZ': 0,
            'initializeCoefficientsUsingCenterOfGravity': True,
            'levelCount': 32,
            'maximumIterationCount': 1000,
            'maximumTestGradient': 1000.0,
            'maximumTolerance': 0.01,
            'optimizerName': 0,
            'optimizerParametersRotationX': 5,
            'optimizerParametersRotationY': 5,
            'optimizerParametersRotationZ': 5,
            'optimizerParametersScalingX': 0.05,
            'optimizerParametersScalingY': 0.05,
            'optimizerParametersScalingZ': 0.05,
            'optimizerParametersShearingXY': 0.05,
            'optimizerParametersShearingXZ': 0.05,
            'optimizerParametersShearingYZ': 0.05,
            'optimizerParametersTranslationX': 30,
            'optimizerParametersTranslationY': 30,
            'optimizerParametersTranslationZ': 30,
            'referenceLowerThreshold': 0.0,
            'resamplingOrder': 1,
            'similarityMeasureName': 1,
            'stepSize': 0.1,
            'stoppingCriterionError': 0.01,
            'subSamplingMaximumSizes': '64',
            'transform3DType': 0
        },
        '_subjectName': subjectid,
        'anteriorPosteriorAdditionSliceCount': 0,
        'correctedDwiDirectory': corrected_dwi_dir,
        'fileNameACP': apcfile,
        'fileNameDwToT1Transformation': '',
        'fileNameT1': t1file,
        'generateDwToT1Transformation': 1,
        'headFootAdditionSliceCount': 0,
        'importDwToT1Transformation': 0,
        'leftRightAdditionSliceCount': 0,
        'outputWorkDirectory': outdir,
        'roughMaskDirectory': rough_mask_dir,
        't1AnteriorYCropping': 0,
        't1FootZCropping': 0,
        't1HeadZCropping': 0,
        't1LeftXCropping': 0,
        't1PosteriorYCropping': 0,
        't1RightXCropping': 0
    }

    # Call with Connectomist
    connprocess = ConnectomistWrapper(path_connectomist)
    parameter_file = ConnectomistWrapper.create_parameter_file(
        algorithm, parameters_dict, outdir)
    connprocess(algorithm, parameter_file, outdir, nb_tries=nb_tries)

    return outdir
def export_eddy_motion_results_to_nifti(eddy_motion_dir,
                                        outdir=None,
                                        filename="dwi",
                                        nb_tries=10):
    """
    After Connectomist has done Eddy current and motion correction, convert
    the result to Nifti with bval/bvec files (bvec with corrrected directions).

    Parameters
    ----------
    eddy_motion_dir: str
        path to the Connectomist "Eddy current and motion" directory.
    outdir: str
        path to directory where to output:
            <outdir>/<filename>.nii.gz
            <outdir>/<filename>.bval
            <outdir>/<filename>.bvec
        By default <outdir> is <eddy_motion_dir>.
    filename: str
        to change output filenames, by default "dwi".
    nb_tries: int
        number of times to try the conversion. It often fails
        when using parallel processing.

    Returns
    -------
    dwi, bval, bvec: str
        the diffusion nifti image with associated bval and bvec files.
    """
    # Step 0 - Set outdir path and check directory existence
    if outdir is None:
        outdir = eddy_motion_dir
    else:
        if not os.path.isdir(outdir):  # If outdir does not exist, create it
            os.mkdir(outdir)

    # Step 1 - Concatenate preprocessed T2 and preprocessed DW volumes
    # Set input and output paths (Gis files) without extension (.ima)
    t2 = os.path.join(eddy_motion_dir, "t2_wo_eddy_current_and_motion.ima")
    dw = os.path.join(eddy_motion_dir, "dw_wo_eddy_current_and_motion.ima")
    t2_dw = os.path.join(eddy_motion_dir,
                         "t2_dw_wo_eddy_current_and_motion.ima")

    # Check existence of input files
    for path in (t2, dw):
        if not os.path.isfile(path):
            raise ConnectomistBadFileError(path)

    # Apply concatenation: result is a Gis file
    ptk_concatenate_volumes([t2, dw], t2_dw, nb_tries=nb_tries)

    # Step 2 - Convert to Nifti
    dwi = ptk_gis_to_nifti(t2_dw,
                           os.path.join(outdir, "%s.nii.gz" % filename),
                           nb_tries=nb_tries)

    # Step 3 - Create .bval and .bvec (with corrected directions)
    # The new directions of gradients (modified by the Eddy current and motion
    # correction) are found in the .ima.minf (Gis format) file associated to
    # diffusion weighted data.
    try:
        # The .ima.minf is a text file that defines a python dict
        path_minf = dw + ".minf"
        exec_dict = dict()  # To store variables created by execfile() call.
        execfile(path_minf, exec_dict)

        # Verify dict structure by checking 2 keys.
        if "bvalues" not in exec_dict["attributes"]:
            raise Exception
        if "diffusion_gradient_orientations" not in exec_dict["attributes"]:
            raise Exception
    except:
        raise ConnectomistBadFileError(path_minf)

    # Get bvalues and create .bval file
    bvalues = np.array(exec_dict["attributes"]["bvalues"], dtype=np.int)

    # Add 0 in bvalues for b=0 associated to T2
    bvalues = np.concatenate(([0], bvalues))

    # Create "dwi.bval"
    bval = os.path.join(outdir, "%s.bval" % filename)
    np.savetxt(bval, bvalues, newline=" ", fmt="%d")

    # Get gradient directions to create .bvec file
    directions = np.array(
        exec_dict["attributes"]["diffusion_gradient_orientations"])

    # Normalize vectors
    magnitudes = np.linalg.norm(directions, axis=1)
    for i, vector in enumerate(directions):
        directions[i, :] = directions[i, :] / magnitudes[i]

    # Add null vector for direction corresponding to bvalue=0 volume
    directions = np.concatenate(([[0, 0, 0]], directions))

    # Create "dwi.bvec"
    bvec = os.path.join(outdir, "%s.bvec" % filename)
    np.savetxt(bvec, directions.T, fmt="%.10f")

    return dwi, bval, bvec
Пример #9
0
def gather_and_format_input_files(outdir,
                                  dwi,
                                  bval,
                                  bvec,
                                  b0_magnitude=None,
                                  b0_phase=None):
    """
    Gather all files needed to start the preprocessing in the right format
    (Gis format for images and B0 maps).

    Parameters
    ----------
    outdir: str
        path to directory where to gather all files.
    dwi: str
        path to input Nifti file to be preprocessed.
    bval: str
        path to .bval file associated to Nifti.
    bvec: str
        path to .bvec file associated to Nifti.
    b0_magnitude: str (optional, default None)
        path to B0 magnitude map, may also contain phase.
        Required only if you want to make fieldmap-based
        correction of susceptibility distortions.
    b0_phase: str (optional, default None)
        not required if phase is already contained in
        b0_magnitude or if you don't want to make fieldmap-based
        correction of susceptibility distortions.

    Returns
    -------
    raw_dwi_dir:
        Connectomist's import data directory with file in Gis format.
    """
    # Check that files exist
    files = [dwi, bval, bvec]
    if b0_magnitude is not None:
        files.append(b0_magnitude)
    if b0_phase is not None:
        files.append(b0_phase)
    for path in files:
        if not os.path.isfile(path):
            raise ConnectomistBadFileError(path)

    # Create the directory if not existing
    if not os.path.isdir(outdir):
        os.mkdir(outdir)

    # If there is only one b0 map file and if this file contains 2 volumes,
    # split it in 2 files: magnitude and phase, assuming the first one is
    # magnitude
    if b0_magnitude and not b0_phase:
        b0_maps = nibabel.load(b0_magnitude)
        if b0_maps.shape[-1] == 2:
            voxels = b0_maps.get_data()
            header = b0_maps.get_header()
            affine = b0_maps.get_affine()
            magnitude = nibabel.Nifti1Image(voxels[..., 0], affine, header)
            phase = nibabel.Nifti1Image(voxels[..., 1], affine, header)
            b0_magnitude = os.path.join(outdir, "b0_magnitude.nii.gz")
            b0_phase = os.path.join(outdir, "b0_phase.nii.gz")
            magnitude.to_filename(b0_magnitude)
            phase.to_filename(b0_phase)

    # Convert Nifti to Gis
    dwi = ptk_nifti_to_gis(dwi, os.path.join(outdir, "dwi.ima"))

    # Copy bval and bvec files, with homogeneous names
    bval_copy = os.path.join(outdir, "dwi.bval")
    bvec_copy = os.path.join(outdir, "dwi.bvec")
    shutil.copyfile(bval, bval_copy)
    shutil.copyfile(bvec, bvec_copy)

    # Convert and rename B0 map(s) if they are given
    if b0_magnitude is not None:
        b0_magnitude = ptk_nifti_to_gis(
            b0_magnitude, os.path.join(outdir, "b0_magnitude.ima"))

    if b0_phase is not None:
        b0_phase = ptk_nifti_to_gis(b0_phase,
                                    os.path.join(outdir, "b0_phase.ima"))

    return dwi, bval_copy, bvec_copy, b0_magnitude, b0_phase
Пример #10
0
def dwi_data_import_and_qspace_sampling(
    outdir,
    dwi,
    bval,
    bvec,
    manufacturer,
    invertX=True,
    invertY=False,
    invertZ=False,
    subject_id=None,
    b0_magnitude=None,
    b0_phase=None,
    nb_tries=10,
    path_connectomist=(
        "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """
    Wrapper to Connectomist's "DWI & Q-space" tab.

    Parameters
    ----------
    outdir: str
        path to Connectomist's output directory.
    dwi: str
        path to Nifti diffusion-weighted data.
    bvec: str
        path to .bval file associated to the Nifti.
    bval: str
        path to .bvec file associated to the Nifti.
    manufacturer: str
        name of the manufacturer (e.g. "Siemens", "GE", "Philips" or "Bruker").
    invertX: bool (optional, default True)
        if True invert x-axis of diffusion model.
    invertY, invertZ: bool (optional, default False)
        if True invert y or z-axis of diffusion model.
    b0_magnitude: str (optional, default None)
        path to the magnitude fieldmap (if fieldmap-based correction of
        susceptibility distortions is to be used).
    b0_phase: str (optional, default None)
        path to phase fieldmap (if fieldmap-based correction of susceptibility
        distortions is to be used).
    nb_tries: int (optional, default 10)
        nb of times to try an algorithm if it fails.
        It often crashes when running in parallel. The reason
        why it crashes is unknown.
    path_connectomist: str (optional)
        path to the Connectomist executable.

    Returns
    -------
    outdir: str
        path to Connectomist's output directory.
    """
    # Create the Connectomist's import data directory
    (dwi, bval, bvec, b0_magnitude,
     b0_phase) = gather_and_format_input_files(outdir, dwi, bval, bvec,
                                               b0_magnitude, b0_phase)

    # Dict with all parameters for connectomist
    algorithm = "DWI-Data-Import-And-QSpace-Sampling"
    parameters_dict = {
        # Parameters are ordered as they appear in connectomist's GUI

        # ---------------------------------------------------------------------
        # Field: "Diffusion weighted-images"
        "fileNameDwi": dwi,  # "DW data"
        "sliceAxis": 2,  # "Slice axis", default "Z-axis"
        "phaseAxis": 1,  # "Phase axis", default "Y-axis"
        "manufacturer": None,

        # Subfield: "Advanced parameters"
        "flipAlongX": 0,  # "Flip data along x"
        "flipAlongY": 0,
        "flipAlongZ": 0,
        "numberOfDiscarded": 0,  # "#discarded images at beginning"
        "numberOfT2": None,  # "#T2"
        "numberOfRepetitions": 1,  # "#repetitions"
        # ---------------------------------------------------------------------
        # Field: "Rotation of field of view", default is identity matrix
        "qSpaceTransform_xx": 1.0,
        "qSpaceTransform_xy": 0.0,
        "qSpaceTransform_xz": 0.0,
        "qSpaceTransform_yx": 0.0,
        "qSpaceTransform_yy": 1.0,
        "qSpaceTransform_yz": 0.0,
        "qSpaceTransform_zx": 0.0,
        "qSpaceTransform_zy": 0.0,
        "qSpaceTransform_zz": 1.0,
        # ---------------------------------------------------------------------
        # Field: "Q-space sampling"
        "qSpaceSamplingType": 4,  # default "spherical single-shell custom"
        "qSpaceChoice5BValue": 1300,
        "qSpaceChoice5OrientationFileNames": bvec,

        # Apparently Connectomist uses 2 as True, and 0 as False.
        "invertXAxis": 2 if invertX else 0,
        "invertYAxis": 2 if invertY else 0,
        "invertZAxis": 2 if invertZ else 0,

        # In this field but not used/handled parameters
        "qSpaceChoice1MaximumBValue": 1000,  # case Cartesian
        "qSpaceChoice2BValue": 1000,
        "qSpaceChoice3BValue": 1000,
        "qSpaceChoice4BValue": 1000,
        "qSpaceChoice6BValues": "",
        "qSpaceChoice7BValues": "",
        "qSpaceChoice8BValues": "",
        "qSpaceChoice9BValues": "",
        "qSpaceChoice10BValues": "",
        "qSpaceChoice11BValues": "",
        "qSpaceChoice12BValues": "",
        "qSpaceChoice13BValues": "",
        "qSpaceChoice1NumberOfSteps": 11,
        "qSpaceChoice2NumberOfOrientations": 6,
        "qSpaceChoice3NumberOfOrientations": 6,
        "qSpaceChoice4NumberOfOrientations": 6,
        "qSpaceChoice6NumberOfOrientations": 6,
        "qSpaceChoice7NumberOfOrientations": 6,
        "qSpaceChoice8NumberOfOrientations": 6,
        "qSpaceChoice9OrientationFileNames": "",
        "qSpaceChoice10NumberOfOrientations": "",
        "qSpaceChoice11NumberOfOrientations": "",
        "qSpaceChoice12NumberOfOrientations": "",
        "qSpaceChoice13OrientationFileNames": "",
        # ---------------------------------------------------------------------
        # Field: "Diffusion time (in ms)"
        "diffusionTime": 1.0,
        # ---------------------------------------------------------------------
        # Field: "Work directory"
        "outputWorkDirectory": outdir,
        # ---------------------------------------------------------------------
        # unknown parameter
        "_subjectName": subject_id if subject_id else "",
    }

    # Map the manufacturer name with Connectomist convention
    if manufacturer not in MANUFACTURERS:
        raise ConnectomistBadManufacturerNameError(manufacturer)
    parameters_dict["manufacturer"] = MANUFACTURERS[manufacturer]

    # Read .bval file to infer nb of T2, nb of shells...
    # Check the at least one bval is not null
    try:
        bvalues = np.loadtxt(bval)
        if set(bvalues) == {0}:  # If only 0s raise Exception
            raise Exception
    except:
        raise ConnectomistBadFileError(bval)
    nb_t2 = np.sum(bvalues == 0)  # nb of volumes where bvalue=0
    bvals_set = set(bvalues) - {0}  # set of non-zero bvalues
    nb_shells = len(bvals_set)

    # Update Connectomist step description
    parameters_dict["numberOfT2"] = nb_t2
    if nb_shells == 1:
        # Spherical single-shell custom
        parameters_dict["qSpaceSamplingType"] = 4
    else:
        raise ConnectomistError("Multiple shell models not handled. "
                                "Path to .bval file: %s" % bval)

    # Check validity of .bvec file.
    # If bvec file does not exist or filled with 0s, raise Error
    if (not os.path.isfile(bvec)) or np.loadtxt(bvec).max() == 0:
        raise ConnectomistBadFileError(bvec)

    # Call with Connectomist
    connprocess = ConnectomistWrapper(path_connectomist)
    parameter_file = ConnectomistWrapper.create_parameter_file(
        algorithm, parameters_dict, outdir)
    connprocess(algorithm, parameter_file, outdir, nb_tries=nb_tries)

    # When there are multiple t2 (nodif) volumes, Connectomist merges them
    # rewrite bvec, bval file accordingly (remove extra T2 values)
    if nb_t2 > 1:
        dw_indexes = np.where(bvalues != 0)[0]
        new_bvalues = np.concatenate(([0], bvalues[dw_indexes]))
        np.savetxt(bval, new_bvalues)

        bvecs = np.loadtxt(bvec)
        new_bvecs = np.concatenate(([[0], [0], [0]], bvecs[:, dw_indexes]),
                                   axis=1)
        np.savetxt(bvec, new_bvecs)

    return outdir
Пример #11
0
def tractography_mask(
    outdir,
    subjectid,
    morphologist_dir,
    add_cerebelum=False,
    add_commissures=True,
    nb_tries=10,
    path_connectomist=(
        "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """ Tractography mask computation.

    Parameters
    ----------
    outdir: str
        path to Connectomist output work directory.
    subjectid: str
        the subject code in study.
    morphologist_dir: str
        path to Morphologist directory.
    add_cerebelum: bool (optional, default False)
        if True add the cerebelum to the tractography mask.
    add_commissures: bool (optional, default False)
        if True add the commissures to the tractography mask.
    nb_tries: int (optional, default 10)
        nb of times to try an algorithm if it fails.
        It often crashes when running in parallel. The reason
        why it crashes is unknown.
    path_connectomist: str (optional)
        path to the Connectomist executable.

    Returns
    -------
    outdir: str
        path to Connectomist's output directory.
    """
    # Get morphologist result files and check existance
    apcfile = os.path.join(morphologist_dir, subjectid, "t1mri",
                           "default_acquisition", "{0}.APC".format(subjectid))
    histofile = os.path.join(morphologist_dir, subjectid, "t1mri",
                             "default_acquisition", "default_analysis",
                             "nobias_{0}.han".format(subjectid))
    t1file = os.path.join(morphologist_dir, subjectid, "t1mri",
                          "default_acquisition", "default_analysis",
                          "nobias_{0}.nii.gz".format(subjectid))
    voronoifile = os.path.join(morphologist_dir, subjectid, "t1mri",
                               "default_acquisition", "default_analysis",
                               "segmentation",
                               "voronoi_{0}.nii.gz".format(subjectid))
    for fpath in (apcfile, histofile, t1file, voronoifile):
        if not os.path.isfile(fpath):
            raise ConnectomistBadFileError(fpath)

    # Dict with all parameters for connectomist
    algorithm = "DWI-Tractography-Mask"
    parameters_dict = {
        '_subjectName': subjectid,
        'addCerebellum': bool_map[add_cerebelum],
        'addCommissures': bool_map[add_commissures],
        'addROIMask': 0,
        'fileNameCommissureCoordinates': apcfile,
        'fileNameHistogramAnalysis': histofile,
        'fileNameROIMaskToAdd': '',
        'fileNameROIMaskToRemove': '',
        'fileNameUnbiasedT1': t1file,
        'fileNameVoronoiMask': voronoifile,
        'outputWorkDirectory': outdir,
        'removeROIMask': 0,
        'removeTemporaryFiles': 2
    }

    # Call with Connectomist
    connprocess = ConnectomistWrapper(path_connectomist)
    parameter_file = ConnectomistWrapper.create_parameter_file(
        algorithm, parameters_dict, outdir)
    connprocess(algorithm, parameter_file, outdir, nb_tries=nb_tries)

    return outdir
Пример #12
0
def dwi_local_modeling(
    outdir,
    registered_dwi_dir,
    subjectid,
    model="aqbi",
    order=4,
    aqbi_laplacebeltrami_sharpefactor=0.0,
    regularization_lccurvefactor=0.006,
    dti_estimator="linear",
    constrained_sd=False,
    sd_kernel_type="symmetric_tensor",
    sd_kernel_lower_fa=0.65,
    sd_kernel_upper_fa=0.85,
    sd_kernel_voxel_count=300,
    nb_tries=10,
    path_connectomist=(
        "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """ Diffusion model estimation.

    Parameters
    ----------
    outdir: str
        path to Connectomist output work directory.
    registered_dwi_dir: str
        path to Connectomist registeres DWI directory.
    subjectid: str
        the subject code in study.
    model: str (optional, default 'aqbi')
        the name of the model to be estimated: 'dot', 'sd', 'sdt', 'aqbi',
        'sa-qbi', 'dti'.
    order: int (optional, default 4)
        the order of the desired model which is directly related to the
        nulber of maxima that can be modeled considering the data SNR. For
        'dti' model this parameter has no effect since it is by definition a
        second order model
    aqbi_laplacebeltrami_sharpefactor: float (optional default 0.0)
        for 'aqbi' and 'sa-aqbi' sharpening factor.
    regularization_lccurvefactor: float (optional default 0.006)
        for 'sdt', 'aqbi' and 'sa-aqbi' regularization factor.
    dti_estimator: str (optional default 'linear')
        the secend order tensor fitting method: 'linear' or 'positive'.
        The seconf method generates positive definite tensors.
    constrained_sd: bool (optiona, default False)
        If True us constrained spherical deconvolution.
    sd_kernel_type: str (optional, default 'symmetric_tensor')
        the spherical deconvolution kernel type: 'symmetric_tensor' or
        'normal'.
    sd_kernel_lower_fa: float (optional, default 0.65)
        lower fractional anisotrpy threshold.
    sd_kernel_upper_fa: float (optional, default 0.85)
        upper fractional anisotrpy threshold.
    sd_kernel_voxel_count: int (optional, default 300)
        kernel size in voxels.
    nb_tries: int (optional, default 10)
        nb of times to try an algorithm if it fails.
        It often crashes when running in parallel. The reason
        why it crashes is unknown.
    path_connectomist: str (optional)
        path to the Connectomist executable.

    Returns
    -------
    outdir: str
        path to Connectomist's output directory.
    """
    # Get Connectomist registration result files and check existance
    dwifile = os.path.join(registered_dwi_dir, "dw_talairach.ima")
    maskfile = os.path.join(registered_dwi_dir, "mask_talairach.ima")
    t1file = os.path.join(registered_dwi_dir, "t1.ima")
    t2file = os.path.join(registered_dwi_dir, "t2_talairach.ima")
    dwtot1file = os.path.join(registered_dwi_dir, "talairach_to_t1.trm")
    for fpath in (dwifile, maskfile, t1file, t2file, dwtot1file):
        if not os.path.isfile(fpath):
            raise ConnectomistBadFileError(fpath)

    # Check input parameters
    if model not in odf_model_map:
        raise ConnectomistError("'{0}' model not supported.".format(model))
    if dti_estimator not in dti_estimator_map:
        raise ConnectomistError(
            "'{0}' dti estimator not supported.".format(dti_estimator))
    if not isinstance(constrained_sd, bool):
        raise ConnectomistError("'constrained_sd' is not a boolean.")
    constrained_sd = int(constrained_sd)
    if sd_kernel_type not in sd_kernel_map:
        raise ConnectomistError(
            "'{0}' kernel not supported.".format(sd_kernel_type))

    # Dict with all parameters for connectomist
    algorithm = "DWI-Local-Modeling"
    parameters_dict = {
        '_subjectName': subjectid,
        'odfType': odf_model_map[model],
        'viewType': odf_model_map[model],
        'computeOdfVolume': 0,
        'rgbScale': 1.0,
        'outputOrientationCount': 500,
        'outputWorkDirectory': outdir,
        'fileNameDw': dwifile,
        'fileNameMask': maskfile,
        'fileNameT1': t1file,
        'fileNameT2': t2file,
        'fileNameTransformationDwToT1': dwtot1file
    }
    parameters_dict.update({
        'aqbiLaplaceBeltramiSharpeningFactor':
        (aqbi_laplacebeltrami_sharpefactor),
        'aqbiMaximumSHOrder':
        order,
        'aqbiRegularizationLcurveFactor':
        regularization_lccurvefactor
    })
    parameters_dict.update({
        'dotEffectiveDiffusionTime': 25.0,
        'dotMaximumSHOrder': order,
        'dotOdfComputation': 2,
        'dotR0': 12.0
    })
    parameters_dict.update({
        'dsiFilteringDataBeforeFFT': 2,
        'dsiMarginalOdf': 2,
        'dsiMaximumR0': 15.0,
        'dsiMinimumR0': 1.0
    })
    parameters_dict.update(
        {'dtiEstimatorType': dti_estimator_map[dti_estimator]})
    parameters_dict.update({
        'qbiEquatorPointCount': 50,
        'qbiPhiFunctionAngle': 0.0,
        'qbiPhiFunctionMaximumAngle': 0.0,
        'qbiPhiFunctionType': 0
    })
    parameters_dict.update({
        'saAqbiLaplaceBeltramiSharpeningFactor':
        (aqbi_laplacebeltrami_sharpefactor),
        'saAqbiMaximumSHOrder':
        order,
        'saAqbiRegularizationLcurveFactor':
        regularization_lccurvefactor
    })
    parameters_dict.update({
        'sdFilterCoefficients':
        ('1 1 1 0.5 0.1 0.02 0.002 0.0005 0.0001 0.00010.00001 0.00001 '
         '0.00001 0.00001 0.00001 0.00001 0.00001'),
        'sdKernelLowerFAThreshold':
        sd_kernel_lower_fa,
        'sdKernelType':
        sd_kernel_map[sd_kernel_type],
        'sdKernelUpperFAThreshold':
        sd_kernel_upper_fa,
        'sdKernelVoxelCount':
        sd_kernel_voxel_count,
        'sdMaximumSHOrder':
        order,
        'sdUseCSD':
        constrained_sd
    })
    parameters_dict.update({
        'sdtKernelLowerFAThreshold': sd_kernel_lower_fa,
        'sdtKernelType': sd_kernel_map[sd_kernel_type],
        'sdtKernelUpperFAThreshold': sd_kernel_upper_fa,
        'sdtKernelVoxelCount': sd_kernel_voxel_count,
        'sdtMaximumSHOrder': order,
        'sdtRegularizationLcurveFactor': regularization_lccurvefactor,
        'sdtUseCSD': constrained_sd
    })

    # Call with Connectomist
    connprocess = ConnectomistWrapper(path_connectomist)
    parameter_file = ConnectomistWrapper.create_parameter_file(
        algorithm, parameters_dict, outdir)
    connprocess(algorithm, parameter_file, outdir, nb_tries=nb_tries)

    return outdir
Пример #13
0
def dwi_susceptibility_artifact_correction(
        outdir,
        raw_dwi_dir,
        rough_mask_dir,
        outliers_dir,
        delta_TE,
        partial_fourier_factor,
        parallel_acceleration_factor,
        negative_sign=False,
        echo_spacing=None,
        EPI_factor=None,
        b0_field=3.0,
        water_fat_shift=4.68,
        nb_tries=10,
        path_connectomist=(
            "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """
    Wrapper to Connectomist's "Susceptibility" tab.

    Parameters
    ----------
    outdir: str
        path to Connectomist output work directory.
    raw_dwi_dir: str
        path to Connectomist Raw DWI folder.
    rough_mask_dir: str
        path to Connectomist Rough Mask folder.
    outliers_dir: str
        path to Connectomist Outliers folder.
    delta_TE: float
        difference in seconds between the 2 echoes
        in B0 magnitude map acquisition.
    partial_fourier_factor: float (]0;1])
        percentage of k-space plane acquired.
    parallel_acceleration_factor: int
        nb of parallel acquisition in k-space plane.
    negative_sign: bool
        if True invert direction of unwarping in
        susceptibility-distortion correction.
    echo_spacing: float
        not for Philips, acquisition time in ms between
        2 centers of 2 consecutively acquired lines in k-space.
    EPI_factor: int
        nb of echoes after one excitation (90 degrees),
        i.e. echo train length.
    b0_field: float
        Philips only, B0 field intensity, by default 3.0.
    water_fat_shift: float
        Philips only, default 4.68 pixels.

    Returns
    -------
    outdir: str
        path to Connectomist's output directory.
    """
    # Get the b0 amplitude and phase image
    b0_magnitude = os.path.join(raw_dwi_dir, "b0_magnitude.ima")
    b0_phase = os.path.join(raw_dwi_dir, "b0_phase.ima")

    # Get the manufacturer from Connectomist's parameter file
    try:
        parameter_file = os.path.join(raw_dwi_dir, "acquisition_parameters.py")
        exec_dict = dict()  # To store variables created by execfile() call.
        execfile(parameter_file, exec_dict)
        manufacturer = exec_dict["acquisitionParameters"][
            "manufacturer"].split(" ")[0]
    except:
        raise ConnectomistBadFileError(parameter_file)
    if manufacturer not in MANUFACTURERS:
        raise ConnectomistBadManufacturerNameError(manufacturer)

    # Dict with all parameters for connectomist
    algorithm = "DWI-Susceptibility-Artifact-Correction"
    parameters_dict = {
        # ---------------------------------------------------------------------
        # Paths parameters
        'rawDwiDirectory':                raw_dwi_dir,
        'roughMaskDirectory':          rough_mask_dir,
        'outlierFilteredDwiDirectory':   outliers_dir,
        'outputWorkDirectory':                 outdir,

        # ---------------------------------------------------------------------
        # Fieldmap correction only
        'correctionStrategy':            0,
        'importDwToB0Transformation':    0,
        'generateDwToB0Transformation':  1,
        'fileNameDwToB0Transformation': '',

        # ---------------------------------------------------------------------
        # Bruker parameters
        'brukerDeltaTE':                      2.46,
        'brukerEchoSpacing':                  0.75,
        'brukerPhaseNegativeSign':               0,
        'brukerPartialFourierFactor':          1.0,
        'brukerParallelAccelerationFactor':      1,
        'brukerFileNameFirstEchoB0Magnitude':   '',
        'brukerFileNameB0PhaseDifference':      '',

        # ---------------------------------------------------------------------
        # GE parameters
        'geDeltaTE':                                         2.46,
        'geEchoSpacing':                                     0.75,
        'gePhaseNegativeSign':                                  0,
        'gePartialFourierFactor':                             1.0,
        'geParallelAccelerationFactor':                         1,
        'geFileNameDoubleEchoB0MagnitudePhaseRealImaginary':   '',

        # ---------------------------------------------------------------------
        # Philips parameters
        'philipsDeltaTE':                      2.46,
        'philipsEchoSpacing':                  0.75,  # Not requested in GUI;
        'philipsPhaseNegativeSign':               0,
        'philipsPartialFourierFactor':          1.0,
        'philipsParallelAccelerationFactor':      1,
        'philipsFileNameFirstEchoB0Magnitude':   '',
        'philipsFileNameB0PhaseDifference':      '',
        'philipsEPIFactor':                     128,
        'philipsStaticB0Field':                 3.0,
        'philipsWaterFatShiftPerPixel':         0.0,

        # ---------------------------------------------------------------------
        # Siemens parameters
        'siemensDeltaTE':                       2.46,
        'siemensEchoSpacing':                   0.75,
        'siemensPhaseNegativeSign':                2,
        'siemensPartialFourierFactor':           1.0,
        'siemensParallelAccelerationFactor':       1,
        'siemensFileNameDoubleEchoB0Magnitude':   "",
        'siemensFileNameB0PhaseDifference':       "",

        # ---------------------------------------------------------------------
        # Parameters not used/handled by the code
        '_subjectName': '',
        'DwToB0RegistrationParameter': {
            'applySmoothing':                                1,
            'floatingLowerThreshold':                      0.0,
            'initialParametersRotationX':                    0,
            'initialParametersRotationY':                    0,
            'initialParametersRotationZ':                    0,
            'initialParametersScalingX':                   1.0,
            'initialParametersScalingY':                   1.0,
            'initialParametersScalingZ':                   1.0,
            'initialParametersShearingXY':                 0.0,
            'initialParametersShearingXZ':                 0.0,
            'initialParametersShearingYZ':                 0.0,
            'initialParametersTranslationX':                 0,
            'initialParametersTranslationY':                 0,
            'initialParametersTranslationZ':                 0,
            'initializeCoefficientsUsingCenterOfGravity': True,
            'levelCount':                                   32,
            'maximumIterationCount':                      1000,
            'maximumTestGradient':                      1000.0,
            'maximumTolerance':                           0.01,
            'optimizerName':                                 0,
            'optimizerParametersRotationX':                 10,
            'optimizerParametersRotationY':                 10,
            'optimizerParametersRotationZ':                 10,
            'optimizerParametersScalingX':                0.05,
            'optimizerParametersScalingY':                0.05,
            'optimizerParametersScalingZ':                0.05,
            'optimizerParametersShearingXY':              0.05,
            'optimizerParametersShearingXZ':              0.05,
            'optimizerParametersShearingYZ':              0.05,
            'optimizerParametersTranslationX':              10,
            'optimizerParametersTranslationY':              10,
            'optimizerParametersTranslationZ':              10,
            'referenceLowerThreshold':                     0.0,
            'resamplingOrder':                               1,
            'similarityMeasureName':                         1,
            'stepSize':                                    0.1,
            'stoppingCriterionError':                     0.01,
            'subSamplingMaximumSizes':                    '56',
            'transform3DType':                               0
        },
    }

    # Maps required parameters in Connectomist, for each manufacturer, to the
    # arguments of the function.
    args_map = {
        "Bruker": {
            "brukerDeltaTE":                      delta_TE,
            "brukerPartialFourierFactor":         partial_fourier_factor,
            "brukerParallelAccelerationFactor":   parallel_acceleration_factor,
            "brukerFileNameFirstEchoB0Magnitude": b0_magnitude,
            "brukerFileNameB0PhaseDifference":    b0_phase,
            "brukerPhaseNegativeSign":            2 if negative_sign else 0,
            'brukerEchoSpacing':                  echo_spacing
        },
        "GE": {
            "geDeltaTE":                          delta_TE,
            "gePartialFourierFactor":             partial_fourier_factor,
            "geParallelAccelerationFactor":       parallel_acceleration_factor,
            "geFileNameDoubleEchoB0MagnitudePhaseRealImaginary": b0_magnitude,
            "gePhaseNegativeSign":                2 if negative_sign else 0,
            "geEchoSpacing":                      echo_spacing

        },
        "Philips": {
            "philipsDeltaTE":                     delta_TE,
            "philipsPartialFourierFactor":        partial_fourier_factor,
            "philipsParallelAccelerationFactor":  parallel_acceleration_factor,
            "philipsFileNameFirstEchoB0Magnitude": b0_magnitude,
            "philipsFileNameB0PhaseDifference":   b0_phase,
            "philipsPhaseNegativeSign":           2 if negative_sign else 0,
            "philipsEPIFactor":                   EPI_factor,
            "philipsStaticB0Field":               b0_field,
            "philipsWaterFatShiftPerPixel":       water_fat_shift
        },
        "Siemens": {
            "siemensDeltaTE":                      delta_TE,
            "siemensPartialFourierFactor":         partial_fourier_factor,
            "siemensParallelAccelerationFactor":  parallel_acceleration_factor,
            "siemensFileNameDoubleEchoB0Magnitude": b0_magnitude,
            "siemensFileNameB0PhaseDifference":    b0_phase,
            "siemensPhaseNegativeSign":            2 if negative_sign else 0,
            "siemensEchoSpacing":                  echo_spacing
        }
    }

    # Check that all needed parameters have been passed: a missing parameter
    # is a parameter with a None value
    required_parameters = set(args_map[manufacturer])
    missing_parameters = [p for p in required_parameters
                          if args_map[manufacturer][p] is None]
    if len(missing_parameters) > 0:
        raise ConnectomistMissingParametersError(algorithm, missing_parameters)

    # Set given parameters
    for p in required_parameters:
        parameters_dict[p] = args_map[manufacturer][p]

    # Call with Connectomist
    connprocess = ConnectomistWrapper(path_connectomist)
    parameter_file = ConnectomistWrapper.create_parameter_file(
        algorithm, parameters_dict, outdir)
    connprocess(algorithm, parameter_file, outdir, nb_tries=nb_tries)

    return outdir