Esempio n. 1
0
def dwi_outlier_detection(
        outdir,
        raw_dwi_dir,
        rough_mask_dir,
        nb_tries=10,
        path_connectomist=(
            "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """
    Wrapper to Connectomist's "Outliers" 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.
    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.

    <unit>
        <output name="outliers_dir"  type="Directory" />

        <input name="outdir"         type="Directory" />
        <input name="raw_dwi_dir"    type="Directory" />
        <input name="rough_mask_dir" type="Directory" />
    </unit>
    """
    # Dict with all parameters for connectomist
    algorithm = "DWI-Outlier-Detection"
    parameters_dict = {'rawDwiDirectory':        raw_dwi_dir,
                       'roughMaskDirectory':  rough_mask_dir,
                       'outputWorkDirectory':         outdir,
                       '_subjectName':                    '',
                       'discardedOrientationList':        '',
                       'outlierFactor':                  3.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
Esempio n. 2
0
def dwi_rough_mask_extraction(
        outdir,
        raw_dwi_dir,
        nb_tries=10,
        path_connectomist=(
            "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """
    Wrapper to Connectomist's "Rough mask" tab.

    Parameters
    ----------
    outdir:  str
        path to Connectomist output work directory.
    raw_dwi_dir: str
        path to Connectomist Raw DWI folder.
    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.
    """
    # Dict with all parameters for connectomist
    algorithm = "DWI-Rough-Mask-Extraction"
    parameters_dict = {
        # ---------------------------------------------------------------------
        # Used parameters
        'outputWorkDirectory':      outdir,
        'rawDwiDirectory':     raw_dwi_dir,
        # ---------------------------------------------------------------------
        # Parameters not used/handled by the code
        '_subjectName': '',
        'anatomy': '',
        '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
        },
        'maskClosingRadius':        0.0,
        'maskDilationRadius':       4.0,
        'morphologistBrainMask':     '',
        'noiseThresholdPercentage': 2.0,
        'strategyRoughMaskFromT1':    0,
        'strategyRoughMaskFromT2':    1
    }

    # 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
Esempio n. 3
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.

    <unit>
        <output name="susceptibility_dir"          type="Directory" />

        <input name="outdir"                       type="Directory" />
        <input name="raw_dwi_dir"                  type="Directory" />
        <input name="rough_mask_dir"               type="Directory" />
        <input name="outliers_dir"                 type="Directory" />
        <input name="delta_TE"                     type="Float"     />
        <input name="partial_fourier_factor"       type="Float"     />
        <input name="parallel_acceleration_factor" type="Float"     />
        <input name="negative_sign"                type="Bool"      />
        <input name="echo_spacing"                 type="Float"     />
        <input name="EPI_factor"                   type="Int"       />
        <input name="b0_field"                     type="Float"     />
        <input name="water_fat_shift"              type="Float"     />
    </unit>
    """
    # 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
Esempio n. 4
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
Esempio n. 5
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
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.

    <unit>
        <output name="raw_dwi_dir" type="Directory" description="Path to
            Connectomist output directory."/>

        <input name="outdir"       type="Directory" />
        <input name="dwi"          type="File"      />
        <input name="bval"         type="File"      />
        <input name="bvec"         type="File"      />
        <input name="manufacturer" type="Str"  description="'Siemens', 'GE', 'Philips' or 'Bruker'" />
        <input name="invertX"      type="Bool" description="If True invert x-axis of diffusion model."/>
        <input name="invertY"      type="Bool" description="Same as invertX but for y-axis."/>
        <input name="invertZ"      type="Bool" description="Same as invertX but for z-axis."/>
        <input name="subject_id"   type="Str"       />
        <input name="b0_magnitude" type="File"      />
        <input name="b0_phase"     type="File"      />
    </unit>
    """
    # 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
def dwi_eddy_current_and_motion_correction(
        outdir,
        raw_dwi_dir,
        rough_mask_dir,
        corrected_dir,
        nb_tries=10,
        path_connectomist=(
            "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """
    Wrapper to Connectomist's "Eddy current & motion" tab.

    Parameters
    ----------
    outdir: str
        path to Connectomist output work directory.
    raw_dwi_dir: str
        path to Connectomist Raw DWI directory.
    rough_mask_dir: str
        path to Connectomist Rough Mask directory.
    corrected_dir: str
        path to Connectomist Susceptibility or Outlier directory.
        Depending whether you make Eddy Current correction before
        or after susceptibility correction.
    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.

    <unit>
        <output name="eddy_motion_dir" type="Directory" />

        <input name="outdir" type="Directory" description="Path to
            Connectomist output work directory."/>
        <input name="raw_dwi_dir" type="Directory" description="Path to
            Connectomist Raw DWI directory."/>
        <input name="rough_mask_dir" type="Directory" description="Path
            to Connectomist Rough Mask directory."/>
        <input name="corrected_dir" type="Directory" description="
            Connectomist Susceptibility or Outlier directory."/>
    </unit>
    """
    # Dict with all parameters for connectomist
    algorithm = "DWI-Eddy-Current-And-Motion-Correction"
    parameters_dict = {
        # ---------------------------------------------------------------------
        # Used parameters
        "rawDwiDirectory":          raw_dwi_dir,
        "roughMaskDirectory":    rough_mask_dir,
        "correctedDwiDirectory":  corrected_dir,
        "outputWorkDirectory":           outdir,
        "eddyCurrentCorrection":              2,
        "motionCorrection":                   1,
        # ---------------------------------------------------------------------
        # Parameters not used/handled by the code
        "_subjectName": "",
        "fileNameMotionTransform": "",
        "eddyCurrentCorrectionOptions": {
            "optimizerParametersTranslationY":  2,
            "optimizerParametersTranslationX":  2,
            "optimizerParametersTranslationZ":  2,
            "maximumTestGradient":         1000.0,
            "subSamplingMaximumSizes":       "64",
            "optimizerName":                    0,
            "optimizerParametersShearingYZ": 0.01,
            "initialParametersTranslationZ":    0,
            "optimizerParametersShearingXZ": 0.01,
            "initialParametersRotationX":       0,
            "initialParametersRotationY":       0,
            "initialParametersRotationZ":       0,
            "maximumIterationCount":         1000,
            "registrationResamplingOrder":      1,
            "optimizerParametersShearingXY": 0.01,
            "optimizerParametersRotationX":     2,
            "optimizerParametersRotationZ":     2,
            "optimizerParametersScalingZ":   0.01,
            "optimizerParametersScalingY":   0.01,
            "backgroundResamplingLevel":        0,
            "initialParametersShearingXZ":    0.0,
            "initialParametersShearingXY":    0.0,
            "outputResamplingOrder":            3,
            "optimizerParametersScalingX":   0.01,
            "lowerThreshold":                 0.0,
            "stoppingCriterionError":        0.01,
            "maximumTolerance":              0.01,
            "levelCount":                      32,
            "initialParametersTranslationX":    0,
            "initialParametersTranslationY":    0,
            "optimizerParametersRotationY":     2,
            "stepSize":                       0.1,
            "initialParametersShearingYZ":    0.0,
            "similarityMeasureName":            1,
            "applySmoothing":                   1,
            "initialParametersScalingX":      1.0,
            "initialParametersScalingY":      1.0,
            "initialParametersScalingZ":      1.0
        },
        "motionCorrectionOptions": {
            "subSamplingMaximumSizes":       "64",
            "optimizerParametersTranslationX":  2,
            "stoppingCriterionError":        0.01,
            "stepSize":                       0.1,
            "optimizerParametersTranslationY":  2,
            "optimizerName":                    0,
            "optimizerParametersTranslationZ":  2,
            "maximumTestGradient":         1000.0,
            "initialParametersRotationX":       0,
            "initialParametersRotationY":       0,
            "initialParametersRotationZ":       0,
            "maximumIterationCount":         1000,
            "applySmoothing":                   1,
            "optimizerParametersRotationX":     2,
            "optimizerParametersRotationZ":     2,
            "backgroundResamplingLevel":        0,
            "outputResamplingOrder":            3,
            "lowerThreshold":                 0.0,
            "maximumTolerance":              0.01,
            "initialParametersTranslationZ":    0,
            "levelCount":                      32,
            "initialParametersTranslationX":    0,
            "initialParametersTranslationY":    0,
            "registrationResamplingOrder":      1,
            "similarityMeasureName":            1,
            "optimizerParametersRotationY":     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
def dwi_eddy_current_and_motion_correction(
    outdir,
    raw_dwi_dir,
    rough_mask_dir,
    corrected_dir,
    nb_tries=10,
    path_connectomist=(
        "/i2bm/local/Ubuntu-14.04-x86_64/ptk/bin/connectomist")):
    """
    Wrapper to Connectomist's "Eddy current & motion" tab.

    Parameters
    ----------
    outdir: str
        path to Connectomist output work directory.
    raw_dwi_dir: str
        path to Connectomist Raw DWI directory.
    rough_mask_dir: str
        path to Connectomist Rough Mask directory.
    corrected_dir: str
        path to Connectomist Susceptibility or Outlier directory.
        Depending whether you make Eddy Current correction before
        or after susceptibility correction.
    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.
    """
    # Dict with all parameters for connectomist
    algorithm = "DWI-Eddy-Current-And-Motion-Correction"
    parameters_dict = {
        # ---------------------------------------------------------------------
        # Used parameters
        "rawDwiDirectory": raw_dwi_dir,
        "roughMaskDirectory": rough_mask_dir,
        "correctedDwiDirectory": corrected_dir,
        "outputWorkDirectory": outdir,
        "eddyCurrentCorrection": 2,
        "motionCorrection": 1,
        # ---------------------------------------------------------------------
        # Parameters not used/handled by the code
        "_subjectName": "",
        "fileNameMotionTransform": "",
        "eddyCurrentCorrectionOptions": {
            "optimizerParametersTranslationY": 2,
            "optimizerParametersTranslationX": 2,
            "optimizerParametersTranslationZ": 2,
            "maximumTestGradient": 1000.0,
            "subSamplingMaximumSizes": "64",
            "optimizerName": 0,
            "optimizerParametersShearingYZ": 0.01,
            "initialParametersTranslationZ": 0,
            "optimizerParametersShearingXZ": 0.01,
            "initialParametersRotationX": 0,
            "initialParametersRotationY": 0,
            "initialParametersRotationZ": 0,
            "maximumIterationCount": 1000,
            "registrationResamplingOrder": 1,
            "optimizerParametersShearingXY": 0.01,
            "optimizerParametersRotationX": 2,
            "optimizerParametersRotationZ": 2,
            "optimizerParametersScalingZ": 0.01,
            "optimizerParametersScalingY": 0.01,
            "backgroundResamplingLevel": 0,
            "initialParametersShearingXZ": 0.0,
            "initialParametersShearingXY": 0.0,
            "outputResamplingOrder": 3,
            "optimizerParametersScalingX": 0.01,
            "lowerThreshold": 0.0,
            "stoppingCriterionError": 0.01,
            "maximumTolerance": 0.01,
            "levelCount": 32,
            "initialParametersTranslationX": 0,
            "initialParametersTranslationY": 0,
            "optimizerParametersRotationY": 2,
            "stepSize": 0.1,
            "initialParametersShearingYZ": 0.0,
            "similarityMeasureName": 1,
            "applySmoothing": 1,
            "initialParametersScalingX": 1.0,
            "initialParametersScalingY": 1.0,
            "initialParametersScalingZ": 1.0
        },
        "motionCorrectionOptions": {
            "subSamplingMaximumSizes": "64",
            "optimizerParametersTranslationX": 2,
            "stoppingCriterionError": 0.01,
            "stepSize": 0.1,
            "optimizerParametersTranslationY": 2,
            "optimizerName": 0,
            "optimizerParametersTranslationZ": 2,
            "maximumTestGradient": 1000.0,
            "initialParametersRotationX": 0,
            "initialParametersRotationY": 0,
            "initialParametersRotationZ": 0,
            "maximumIterationCount": 1000,
            "applySmoothing": 1,
            "optimizerParametersRotationX": 2,
            "optimizerParametersRotationZ": 2,
            "backgroundResamplingLevel": 0,
            "outputResamplingOrder": 3,
            "lowerThreshold": 0.0,
            "maximumTolerance": 0.01,
            "initialParametersTranslationZ": 0,
            "levelCount": 32,
            "initialParametersTranslationX": 0,
            "initialParametersTranslationY": 0,
            "registrationResamplingOrder": 1,
            "similarityMeasureName": 1,
            "optimizerParametersRotationY": 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
Esempio n. 9
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
Esempio n. 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
Esempio n. 11
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
Esempio n. 12
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
Esempio n. 13
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
Esempio n. 14
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
Esempio n. 15
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
Esempio n. 16
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