Esempio n. 1
0
def adni3_image(subject_id, timepoint, visit_str, mprage_meta_subj, mayo_mri_qc_subj):

    from clinica.iotools.converters.adni_to_bids.adni_utils import replace_sequence_chars
    from clinica.utils.stream import cprint

    filtered_scan = mprage_meta_subj[(mprage_meta_subj['Orig/Proc'] == 'Original')
                                     & (mprage_meta_subj.Visit == visit_str)
                                     & mprage_meta_subj.Sequence.map(
        lambda x: (x.lower().find('accel') > -1) & ~(x.lower().endswith('_ND')))]

    if filtered_scan.shape[0] < 1:
        # TODO - LOG THIS
        cprint('NO MPRAGE Meta for ADNI3: ' + subject_id + ' for visit ' + timepoint + ' - ' + visit_str)
        return None

    scan = select_scan_qc_adni2(filtered_scan, mayo_mri_qc_subj, preferred_field_strength=3.0)
    sequence = replace_sequence_chars(scan.Sequence)

    return {'Subject_ID': subject_id,
            'VISCODE': timepoint,
            'Visit': visit_str,
            'Sequence': sequence,
            'Scan_Date': scan.ScanDate,
            'Study_ID': str(scan.StudyID),
            'Series_ID': str(scan.SeriesID),
            'Image_ID': str(scan.ImageUID),
            'Field_Strength': scan.MagStrength,
            'Original': True}
def atlas_statistics(file_list, atlas_list):
    """
    For each atlas name provided it ƒcalculates for the input image the mean for each region in the atlas and saves it to a TSV file.
    :param in_image: A Nifti image
    :param in_atlas_list: List of names of atlas to be applied
    :return: List of paths to tsv files
    """
    from os import getcwd
    from os.path import abspath, join
    from nipype.utils.filemanip import split_filename
    from clinica.utils.atlas import AtlasAbstract
    from clinica.utils.statistics import statistics_on_atlas
    from clinica.utils.stream import cprint

    orig_dir, base, ext = split_filename(file_list)
    atlas_classes = AtlasAbstract.__subclasses__()
    atlas_statistics_list = []
    for atlas in atlas_list:
        for atlas_class in atlas_classes:
            if atlas_class.get_name_atlas() == atlas:
                #out_atlas_statistics = abspath(join(getcwd(), base + '_space-' + atlas + '_map-graymatter_statistics.tsv'))
                out_atlas_statistics = abspath(
                    join('./' + base + '_space-' + atlas +
                         '_map-graymatter_statistics.tsv'))
                cprint(out_atlas_statistics)
                statistics_on_atlas(file_list, atlas_class(),
                                    out_atlas_statistics)
                atlas_statistics_list.append(out_atlas_statistics)

                break

    return atlas_statistics_list
Esempio n. 3
0
    def run_command(self, args):
        """
        """
        import os
        import datetime
        from colorama import Fore
        from tempfile import mkdtemp
        from .dwi_dti_pipeline import DwiDti
        from clinica.utils.stream import cprint

        pipeline = DwiDti(
            caps_directory=self.absolute_path(args.caps_directory),
            tsv_file=self.absolute_path(args.subjects_sessions_tsv))

        if args.working_directory is None:
            args.working_directory = mkdtemp()
        pipeline.base_dir = self.absolute_path(args.working_directory)

        if args.n_procs:
            pipeline.run(plugin='MultiProc',
                         plugin_args={'n_procs': args.n_procs})
        else:
            pipeline.run()

        now = datetime.datetime.now().strftime('%H:%M:%S')
        cprint(
            '%s[%s]%s The %s pipeline has completed. You can now delete the working directory (%s).'
            % (Fore.GREEN, now, Fore.RESET, self._name,
               os.path.join(os.path.abspath(args.working_directory),
                            pipeline.__class__.__name__)))
Esempio n. 4
0
def check_fsl(version_requirements=None):
    """Check FSL software."""
    import nipype.interfaces.fsl as fsl
    from colorama import Fore

    from clinica.utils.exceptions import ClinicaMissingDependencyError
    from clinica.utils.stream import cprint

    check_environment_variable("FSLDIR", "FSL")

    try:
        if fsl.Info.version().split(".") < ["5", "0", "5"]:
            raise ClinicaMissingDependencyError(
                f"{Fore.RED}FSL version must be greater than 5.0.5{Fore.RESET}"
            )
    except Exception as e:
        cprint(str(e))

    list_binaries = ["bet", "flirt", "fast", "first"]
    for binary in list_binaries:
        if not is_binary_present(binary):
            raise ClinicaMissingDependencyError(
                f"{Fore.RED}\n[Error] Clinica could not find FSL software: "
                f"the {binary} command is not present in your PATH environment.{Fore.RESET}"
            )
def delta_echo_time_from_bids_fmap(fmap_json):
    """
    Extract BIDS metadata (EchoTime1, etc.) from a fmap .json file.

    Args:
        fmap_json: Path to a BIDS compliant .json file

    Returns:

    """
    import json
    import os

    from clinica.utils.stream import cprint

    if not os.path.exists(fmap_json):
        raise IOError('fmap .json file (%s) does not exist.' % fmap_json)

    with open(fmap_json) as data_frame:
        data = json.load(data_frame)

    echo_time_1 = data['EchoTime1']
    echo_time_2 = data['EchoTime2']
    delta_echo_time = echo_time_2 - echo_time_1

    cprint(
        dwi_container_from_filename(fmap_json) + " (FMap JSON): EchoTime1=" +
        str(echo_time_1) + ", EchoTime2=" + str(echo_time_2) + " (Delta = " +
        str(delta_echo_time) + ", fname=" + fmap_json + ")")

    return delta_echo_time
Esempio n. 6
0
def check_qc(scan, subject_id, visit_str, mri_quality_subj):
    """Checks if a scan has passed check quality, if it was performed

    Args:
        scan: DataFrame row containing scan information
        subject_id: string containing subject ID
        visit_str: string of visit name
        mri_quality_subj: DatFrame of MR image quality of images corresponding to the subject

    Returns:
        boolean, True if image passed QC or if there is not available QC, False elsewhere

    """
    from clinica.utils.stream import cprint

    # Check if QC exists for image series
    qc = mri_quality_subj[mri_quality_subj.LONIUID == 'S' + str(scan.SeriesID)]

    # If QC exists and failed we keep the other scan (in case 2 scans were performed)
    if not qc.empty and qc.iloc[0].PASS != 1:

        cprint('QC found but NOT passed')
        cprint('Subject ' + subject_id + ' for visit ' + visit_str +
               ' - Series: ' + str(scan.SeriesID) + ' - Study: ' +
               str(scan.StudyID))
        return False
    return True
Esempio n. 7
0
    def build_input_node(self):
        """Build and connect an input node to the pipeline."""
        import os

        from clinica.utils.filemanip import save_participants_sessions
        from clinica.utils.stream import cprint
        from clinica.utils.ux import print_images_to_process

        if self.parameters["longitudinal"]:
            self.build_input_node_longitudinal()
        else:
            self.build_input_node_cross_sectional()

        # Save subjects to process in <WD>/<Pipeline.name>/participants.tsv
        folder_participants_tsv = os.path.join(self.base_dir, self.name)
        save_participants_sessions(
            self.subjects, self.sessions, folder_participants_tsv
        )

        if len(self.subjects):
            print_images_to_process(self.subjects, self.sessions)
            cprint(
                "List available in %s"
                % os.path.join(folder_participants_tsv, "participants.tsv")
            )
            cprint("The pipeline will last approximately a few hours per image.")
Esempio n. 8
0
def check_freesurfer():
    """
    Check FreeSurfer software.

    This function checks if FreeSurfer is present (FREESURFER_HOME & binaries).
    """
    import os
    from clinica.utils.stream import cprint

    try:
        freesurfer_home = os.environ.get('FREESURFER_HOME', '')
        if not freesurfer_home:
            raise RuntimeError('FREESURFER_HOME variable is not set')
    except Exception as e:
        cprint(str(e))

    list_binaries = ['mri_convert', 'recon-all']
    for binary in list_binaries:
        if not is_binary_present(binary):
            raise RuntimeError(
                '%s from FreeSurfer Software is not present in your PATH '
                'environment: did you source ${FREESURFER_HOME}/'
                'SetUpFreeSurfer.sh ?' % binary)

    cprint('FreeSurfer has been detected')
Esempio n. 9
0
def write_tsv_files(subjects_dir, image_id):
    """
    Generate statistics TSV files in `subjects_dir`/regional_measures folder for `image_id`.

    Notes:
        We do not need to check the line "finished without error" in scripts/recon-all.log.
        If an error occurs, it will be detected by Nipype and the next nodes (including
        write_tsv_files will not be called).
    """
    import os

    from clinica.utils.freesurfer import generate_regional_measures
    from clinica.utils.stream import cprint

    if os.path.isfile(
            os.path.join(subjects_dir, image_id, "mri", "aparc+aseg.mgz")):
        generate_regional_measures(subjects_dir, image_id)
    else:
        cprint(
            msg=
            (f"{image_id.replace('_', ' | ')} does not contain "
             f"mri/aseg+aparc.mgz file. Creation of regional_measures/ folder will be skipped."
             ),
            lvl="warning",
        )
    return image_id
Esempio n. 10
0
def save_part_sess_long_ids_to_tsv(participant_ids,
                                   session_ids,
                                   long_ids,
                                   out_folder,
                                   file_name=None):
    """Save participant, session and longitudinal IDs to TSV file.

    TODO: Find a way to merge with utils/save_participants_sessions.py::read_participant_tsv into one util
    """
    import os

    import pandas

    from clinica.utils.stream import cprint

    os.makedirs(out_folder, exist_ok=True)

    if file_name:
        tsv_file = os.path.join(out_folder, file_name)
    else:
        tsv_file = os.path.join(out_folder, "participants.tsv")

    try:
        data = pandas.DataFrame({
            "participant_id": participant_ids,
            "session_id": session_ids,
            "long_id": long_ids,
        })
        data.to_csv(tsv_file, sep="\t", index=False, encoding="utf-8")
    except Exception as e:
        cprint(f"Impossible to save {tsv_file} with pandas")
        raise e
Esempio n. 11
0
 def print_images_to_process(list_participant_id, list_session_id,
                             list_longitudinal_id):
     cprint('The pipeline will be run on the following %s image(s):' %
            len(list_participant_id))
     for (p_id, s_id, l_id) in zip(list_participant_id, list_session_id,
                                   list_longitudinal_id):
         cprint("\t%s | %s | %s" % (p_id, s_id, l_id))
Esempio n. 12
0
def find_image_path(images, source_dir, modality, prefix, id_field):
    """
    For each image, the path to an existing image file or folder is created from image metadata.

    Args:
        images: List of images metadata
        source_dir: path to the ADNI directory
        modality: Imaging modality
        prefix: Prefix to prepend to image identifier to create name of folder containing the image
        id_field: Name of the field in images metadata dataframe containing the image identifier to use

    Returns: Dataframe containing metadata and existing paths
    """
    from pathlib import Path

    import pandas as pd

    from clinica.utils.stream import cprint

    is_dicom = []
    image_folders = []

    for _, image in images.iterrows():
        # Base directory where to look for image files.
        seq_path = Path(source_dir) / str(image["Subject_ID"])

        # Generator finding files containing the image ID.
        find_file = filter(
            lambda p: p.is_file(),
            seq_path.rglob(f"*_I{image['Image_ID']}.*"),
        )

        try:
            # Grab the first file from the generator.
            next_file: Path = next(find_file)

            # Whether the image data are DICOM or not.
            dicom = "dcm" in next_file.suffix

            # Compute the image path (DICOM folder or NIfTI path).
            image_path = str(next_file.parent if dicom else next_file)
        except StopIteration:
            # In case no file is found.
            image_path = ""
            dicom = True

        is_dicom.append(dicom)
        image_folders.append(image_path)
        if image_path == "":
            cprint(
                msg=
                (f"No {modality} image path found for subject {image.Subject_ID} in visit {image.VISCODE} "
                 f"with image ID {image.Image_ID}"),
                lvl="info",
            )

    images.loc[:, "Is_Dicom"] = pd.Series(is_dicom, index=images.index)
    images.loc[:, "Path"] = pd.Series(image_folders, index=images.index)

    return images
def write_tsv_files(subjects_dir, subject_id):
    """Generate statistics TSV files in `subjects_dir`/regional_measures folder for `subject_id`.

    Notes:
        We do not need to check the line "finished without error" in scripts/recon-all.log.
        If an error occurs, it will be detected by Nipype and the next nodes (i.e.
        write_tsv_files will not be called).
    """
    import os

    from clinica.utils.freesurfer import (
        extract_image_id_from_longitudinal_segmentation,
        generate_regional_measures,
    )
    from clinica.utils.stream import cprint

    image_id = extract_image_id_from_longitudinal_segmentation(subject_id)
    str_image_id = (image_id.participant_id + "_" + image_id.session_id + "_" +
                    image_id.long_id)
    if os.path.isfile(
            os.path.join(subjects_dir, subject_id, "mri", "aparc+aseg.mgz")):
        generate_regional_measures(subjects_dir, subject_id)
    else:
        cprint(
            msg=
            (f"{str_image_id.replace('_', ' | ')} does not contain mri/aseg+aparc.mgz file. "
             "Creation of regional_measures/ folder will be skipped."),
            lvl="warning",
        )
    return subject_id
Esempio n. 14
0
    def run_command(self, args):
        """
        """
        from tempfile import mkdtemp
        from clinica.utils.stream import cprint
        from clinica.pipelines.machine_learning_spatial_svm.spatial_svm_pipeline import SpatialSVM

        pipeline = SpatialSVM(
            caps_directory=self.absolute_path(args.caps_directory),
            tsv_file=self.absolute_path(args.subjects_sessions_tsv))

        pipeline.parameters = {
            'group_id': args.group_id,
            'fwhm': args.full_width_half_maximum,
            'image_type': args.image_type,
            'pet_type': args.pet_tracer,
            'no_pvc': args.no_pvc
        }
        if args.working_directory is None:
            args.working_directory = mkdtemp()
        pipeline.base_dir = self.absolute_path(args.working_directory)
        if args.n_procs:
            pipeline.run(plugin='MultiProc',
                         plugin_args={'n_procs': args.n_procs})
        else:
            pipeline.run()

        cprint(
            "The " + self._name +
            " pipeline has completed. You can now delete the working directory ("
            + args.working_directory + ").")
Esempio n. 15
0
    def run_command(self, args):
        """
        """
        from tempfile import mkdtemp
        from clinica.utils.stream import cprint
        from clinica.pipelines.t1_volume_parcellation.t1_volume_parcellation_pipeline import T1VolumeParcellation

        pipeline = T1VolumeParcellation(
            caps_directory=self.absolute_path(args.caps_directory),
            tsv_file=self.absolute_path(args.subjects_sessions_tsv))
        assert args.modulation in ['on', 'off']
        pipeline.parameters = {
            'group_id': args.group_id,
            'atlases': args.atlases,
            'wd': self.absolute_path(args.working_directory),
            'n_procs': args.n_procs,
            'modulate': args.modulation
        }

        if args.working_directory is None:
            args.working_directory = mkdtemp()
        pipeline.base_dir = self.absolute_path(args.working_directory)

        if args.n_procs:
            pipeline.run(plugin='MultiProc',
                         plugin_args={'n_procs': args.n_procs})
        else:
            pipeline.run()

        cprint(
            "The " + self._name +
            " pipeline has completed. You can now delete the working directory ("
            + args.working_directory + ").")
Esempio n. 16
0
def write_tsv_files(subjects_dir, subject_id):
    """
    Generate statistics TSV files in `subjects_dir`/regional_measures folder for `subject_id`.

    Notes:
        We do not need to check the line "finished without error" in scripts/recon-all.log.
        If an error occurs, it will be detected by Nipype and the next nodes (i.e.
        write_tsv_files will not be called).
    """
    import os
    import datetime
    from colorama import Fore
    from clinica.utils.stream import cprint
    from clinica.utils.freesurfer import generate_regional_measures, extract_image_id_from_longitudinal_segmentation

    image_id = extract_image_id_from_longitudinal_segmentation(subject_id)
    str_image_id = image_id.participant_id + '_' + image_id.session_id + '_' + image_id.long_id
    if os.path.isfile(
            os.path.join(subjects_dir, subject_id, 'mri', 'aparc+aseg.mgz')):
        generate_regional_measures(subjects_dir, subject_id)
    else:
        now = datetime.datetime.now().strftime('%H:%M:%S')
        cprint(
            '%s[%s] %s does not contain mri/aseg+aparc.mgz file. '
            'Creation of regional_measures/ folder will be skipped.%s' %
            (Fore.YELLOW, now, str_image_id.replace('_', ' | '), Fore.RESET))
    return subject_id
Esempio n. 17
0
def get_file_from_server(remote_file, cache_path=None):
    """Download file from server.

    Args:
        remote_file (str): RemoteFileStructure defined in clinica.utils.inputs
        cache_path (str): (default: ~/.cache/clinica/data)

    Returns:
        Path to downloaded file.
    """
    import os
    from pathlib import Path

    from clinica.utils.stream import cprint

    home = str(Path.home())
    if cache_path:
        cache_clinica = os.path.join(home, ".cache", cache_path)
    else:
        cache_clinica = os.path.join(home, ".cache", "clinica", "data")

    os.makedirs(cache_clinica, exist_ok=True)

    local_file = os.path.join(cache_clinica, remote_file.filename)

    if not (os.path.exists(local_file)):
        try:
            local_file = fetch_file(remote_file, cache_clinica)
        except IOError as err:
            cprint(
                f"Unable to download {remote_file.filename} from {remote_file.url}: {err}"
            )

    return local_file
Esempio n. 18
0
def init_input_node(pet_nii):
    import datetime

    import nibabel as nib
    from colorama import Fore

    from clinica.utils.filemanip import get_subject_id
    from clinica.utils.stream import cprint
    from clinica.utils.ux import print_begin_image

    # Extract image ID
    image_id = get_subject_id(pet_nii)

    # Check that the PET file is a 3D volume
    img = nib.load(pet_nii)
    if len(img.shape) == 4:
        now = datetime.datetime.now().strftime("%H:%M:%S")
        error_msg = (
            f"{Fore.RED}[{now}] Error: Clinica does not handle 4D volumes "
            f"for {image_id.replace('_', ' | ')}{Fore.RESET}")
        cprint(error_msg)
        raise NotImplementedError(error_msg)

    # Print begin message
    print_begin_image(image_id)

    return pet_nii
Esempio n. 19
0
    def run_command(self, args):
        """
        Run the DWIPreprocessingUsingT1 Pipeline from command line.
        """
        from tempfile import mkdtemp
        from clinica.utils.stream import cprint
        from .dwi_preprocessing_using_t1_pipeline import DwiPreprocessingUsingT1

        pipeline = DwiPreprocessingUsingT1(
            bids_directory=self.absolute_path(args.bids_directory),
            caps_directory=self.absolute_path(args.caps_directory),
            tsv_file=self.absolute_path(args.subjects_sessions_tsv),
            low_bval=args.low_bval)

        if args.working_directory is None:
            args.working_directory = mkdtemp()
        pipeline.base_dir = self.absolute_path(args.working_directory)

        if args.n_procs:
            pipeline.run(plugin='MultiProc',
                         plugin_args={'n_procs': args.n_procs})
        else:
            pipeline.run()

        cprint(
            "The " + self._name +
            " pipeline has completed. You can now delete the working directory ("
            + args.working_directory + ").")
    def run_command(self, args):
        """
        """
        from tempfile import mkdtemp
        from clinica.utils.stream import cprint
        from clinica.pipelines.t1_volume_existing_dartel.t1_volume_existing_dartel_pipeline import T1VolumeExistingDartel

        pipeline = T1VolumeExistingDartel(
            bids_directory=self.absolute_path(args.bids_directory),
            caps_directory=self.absolute_path(args.caps_directory),
            tsv_file=self.absolute_path(args.subjects_sessions_tsv),
            group_id=args.group_id)

        pipeline.parameters.update({'tissues': args.tissues})

        if args.working_directory is None:
            args.working_directory = mkdtemp()
        pipeline.base_dir = self.absolute_path(args.working_directory)

        if args.n_procs:
            pipeline.run(plugin='MultiProc',
                         plugin_args={'n_procs': args.n_procs})
        else:
            pipeline.run()

        cprint(
            "The " + self._name +
            " pipeline has completed. You can now delete the working directory ("
            + args.working_directory + ").")
Esempio n. 21
0
    def run(self, plugin=None, plugin_args=None, update_hash=False, bypass_check=False):
        """Executes the Pipeline.

        It overwrites the default Workflow method to check if the
        Pipeline is built before running it. If not, it builds it and then
        run it.
        It also checks whether there is enough space left on the disks, and if
        the number of threads to run in parallel is consistent with what is
        possible on the CPU.

        Args:
            Similar to those of Workflow.run.

        Returns:
            An execution graph (see Workflow.run).
        """
        import shutil

        from colorama import Fore
        from networkx import Graph, NetworkXError

        from clinica.utils.stream import cprint
        from clinica.utils.ux import print_failed_images

        if not self.is_built:
            self.build()
        self.check_not_cross_sectional()
        if not bypass_check:
            self.check_size()
            plugin_args = self.update_parallelize_info(plugin_args)
            plugin = "MultiProc"
        exec_graph = []
        try:
            exec_graph = Workflow.run(self, plugin, plugin_args, update_hash)
            if not self.base_dir_was_specified:
                shutil.rmtree(self.base_dir)

        except RuntimeError as e:
            # Check that it is a Nipype error
            if "Workflow did not execute cleanly. Check log for details" in str(e):
                input_ids = [
                    p_id + "_" + s_id
                    for p_id, s_id in zip(self.subjects, self.sessions)
                ]
                output_ids = self.get_processed_images(
                    caps_directory=self.caps_directory,
                    subjects=self.subjects,
                    sessions=self.sessions,
                )
                missing_ids = list(set(input_ids) - set(output_ids))
                print_failed_images(self.name, missing_ids)
            else:
                raise e
        except NetworkXError:
            cprint(
                f"{Fore.BLUE}Either all the images were already run by the pipeline "
                f"or no image was found to run the pipeline.\n{Fore.RESET}"
            )
            exec_graph = Graph()
        return exec_graph
Esempio n. 22
0
def use_spm_standalone():
    """Use SPM Standalone with MATLAB Common Runtime."""
    import os
    import platform

    from nipype.interfaces import spm

    from clinica.utils.stream import cprint

    # This section of code determines whether to use SPM standalone or not
    if all(elem in os.environ.keys()
           for elem in ["SPMSTANDALONE_HOME", "MCR_HOME"]):
        spm_standalone_home = os.getenv("SPMSTANDALONE_HOME")
        mcr_home = os.getenv("MCR_HOME")
        if os.path.exists(spm_standalone_home) and os.path.exists(mcr_home):
            cprint(
                "SPM standalone has been found and will be used in this pipeline"
            )
            if platform.system().lower().startswith("darwin"):
                matlab_cmd = (
                    f"cd {spm_standalone_home} && ./run_spm12.sh {mcr_home} script"
                )
            elif platform.system().lower().startswith("linux"):
                matlab_cmd = f"{os.path.join(spm_standalone_home, 'run_spm12.sh')} {mcr_home} script"
            else:
                raise SystemError("Clinica only support macOS and Linux")
            spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True)
            cprint(f"Using SPM standalone version {spm.SPMCommand().version}")
        else:
            raise FileNotFoundError(
                "$SPMSTANDALONE_HOME and $MCR_HOME are defined, but linked to non existent folder "
            )
def parameters_from_dwi_metadata(dwi_json):
    """
    Extract BIDS metadata (EffectiveEchoSpacing, etc.) from a DWI .json file.

    Args:
        dwi_json: Path to a BIDS compliant .json file

    Returns:

    """
    import json
    import os

    from clinica.utils.stream import cprint

    if not os.path.exists(dwi_json):
        raise IOError('DWI .json file (%s) does not exist.' % dwi_json)

    with open(dwi_json) as data_frame:
        data = json.load(data_frame)

    effective_echo_spacing = data['EffectiveEchoSpacing']
    phase_encoding_direction = data['PhaseEncodingDirection']

    cprint(
        dwi_container_from_filename(dwi_json) +
        " (DWI JSON): EffectiveEchoSpacing=" + str(effective_echo_spacing) +
        ", PhaseEncodingDirection=" + str(phase_encoding_direction) +
        " (fname = " + dwi_json + ")")

    return [effective_echo_spacing, phase_encoding_direction]
Esempio n. 24
0
def move_subjects_dir_to_source_dir(subjects_dir, source_dir, subject_id):
    """
    Move content of `subjects_dir`/`subject_id` to `source_dir`.

    This function will move content of `subject_id` if recon-all has run in $(TMP). This happens when only
    one time point is used. Content of $(TMP)/`subject_id` is copied to `source_dir` before the deletion of $(TMP).

    Args:
        subjects_dir: $(TMP), if segmentation was performed on 1 time point,
            <base_dir>/<Pipeline.Name>/ReconAll/`subject_id` otherwise
        source_dir: <base_dir>/<Pipeline.Name>/ReconAll folder
        subject_id: Subject ID (e.g. "sub-CLNC01_ses-M00" or "sub-CLNC01_ses-M00M18")

    Returns:
        subject_id for node connection with Nipype
    """
    import os
    import shutil
    import datetime
    from colorama import Fore
    from clinica.utils.stream import cprint

    if source_dir not in subjects_dir:
        shutil.copytree(src=os.path.join(subjects_dir, subject_id),
                        dst=os.path.join(source_dir, subject_id, subject_id),
                        symlinks=True)
        shutil.rmtree(subjects_dir)
        now = datetime.datetime.now().strftime('%H:%M:%S')
        cprint(
            '%s[%s] Segmentation of %s has moved to working directory and $SUBJECTS_DIR folder (%s) was deleted%s'
            % (Fore.YELLOW, now, subject_id.replace(
                '_', ' | '), subjects_dir, Fore.RESET))

    return subject_id
Esempio n. 25
0
def save_participants_sessions(participant_ids,
                               session_ids,
                               out_folder,
                               out_file=None):
    """
    Save <participant_ids> <session_ids> in <out_folder>/<out_file> TSV file.
    """
    import os
    import errno
    import pandas
    from clinica.utils.stream import cprint

    assert (len(participant_ids) == len(session_ids))

    try:
        os.makedirs(out_folder)
    except OSError as e:
        if e.errno != errno.EEXIST:  # EEXIST: folder already exists
            raise e

    if out_file:
        tsv_file = os.path.join(out_folder, out_file)
    else:
        tsv_file = os.path.join(out_folder, 'participants.tsv')

    try:
        data = pandas.DataFrame({
            'participant_id': participant_ids,
            'session_id': session_ids,
        })
        data.to_csv(tsv_file, sep='\t', index=False, encoding='utf-8')
    except Exception as e:
        cprint("Impossible to save %s with pandas" % out_file)
        raise e
Esempio n. 26
0
    def run_command(self, args):
        from clinica.iotools.converters.adni_to_bids.adni_to_bids import AdniToBids
        from os.path import exists, join
        from clinica.utils.stream import cprint
        from colorama import Fore
        from time import sleep

        adni_to_bids = AdniToBids()

        # Check dcm2nii and dcm2niix dependencies
        adni_to_bids.check_adni_dependencies()

        if 'fMRI' in args.modalities and not exists(join(args.clinical_data_directory, 'IDA_MR_Metadata_Listing.csv')):
            cprint(Fore.RED + '[Warning] We could not detect file IDA_MR_Metadata_Listing.csv in your clinical data folder.'
                   + ' Therefore, fMRI conversion is disabled.' + Fore.GREEN
                   + '\nADNI conversion will start in a few seconds...' + Fore.RESET)
            # Enough time for the user to read the message
            sleep(7)
            args.modalities.remove('fMRI')

        if not args.clinical_data_only:
            adni_to_bids.convert_images(self.absolute_path(args.dataset_directory),
                                        self.absolute_path(args.clinical_data_directory),
                                        self.absolute_path(args.bids_directory),
                                        args.subjects_list,
                                        args.modalities)

        adni_to_bids.convert_clinical_data(self.absolute_path(args.clinical_data_directory),
                                           self.absolute_path(args.bids_directory))
Esempio n. 27
0
def save_participants_sessions(participant_ids,
                               session_ids,
                               out_folder,
                               out_file=None):
    """Save <participant_ids> <session_ids> in <out_folder>/<out_file> TSV file."""
    import os

    import pandas

    from clinica.utils.stream import cprint

    assert len(participant_ids) == len(session_ids)

    os.makedirs(out_folder, exist_ok=True)

    if out_file:
        tsv_file = os.path.join(out_folder, out_file)
    else:
        tsv_file = os.path.join(out_folder, "participants.tsv")

    try:
        data = pandas.DataFrame({
            "participant_id": participant_ids,
            "session_id": session_ids,
        })
        data.to_csv(tsv_file, sep="\t", index=False, encoding="utf-8")
    except Exception as e:
        cprint(f"Impossible to save {out_file} with pandas")
        raise e
    def run_command(self, args):
        """
        Run the pipelines with defined args
        """
        import os
        import datetime
        from colorama import Fore
        from clinica.utils.stream import cprint
        from .t1_freesurfer_cross_sectional_pipeline import T1FreeSurferCrossSectional
        from tempfile import mkdtemp

        pipeline = T1FreeSurferCrossSectional(
            bids_directory=self.absolute_path(args.bids_directory),
            caps_directory=self.absolute_path(args.caps_directory),
            tsv_file=self.absolute_path(args.subjects_sessions_tsv)
        )

        pipeline.parameters = {
            'recon_all_args': args.recon_all_args or '-qcache'
        }

        if args.working_directory is None:
            args.working_directory = mkdtemp()
        pipeline.base_dir = self.absolute_path(args.working_directory)

        if args.n_procs:
            pipeline.run(plugin='MultiProc',
                         plugin_args={'n_procs': args.n_procs})
        else:
            pipeline.run()

        now = datetime.datetime.now().strftime('%H:%M:%S')
        cprint('%s[%s]%s The %s pipeline has completed. You can now delete the working directory (%s).' %
               (Fore.GREEN, now, Fore.RESET, self._name, os.path.join(os.path.abspath(args.working_directory), pipeline.__class__.__name__)))
Esempio n. 29
0
def use_spm_standalone():
    """
    Use SPM Standalone with MATLAB Common Runtime
    """
    import os
    from colorama import Fore
    import platform
    from clinica.utils.stream import cprint
    from nipype.interfaces import spm
    # This section of code determines whether to use SPM standalone or not
    if all(elem in os.environ.keys() for elem in ['SPMSTANDALONE_HOME', 'MCR_HOME']):
        spm_standalone_home = os.getenv('SPMSTANDALONE_HOME')
        mcr_home = os.getenv('MCR_HOME')
        if os.path.exists(spm_standalone_home) and os.path.exists(mcr_home):
            cprint(Fore.GREEN + 'SPM standalone has been found and will be used in this pipeline' + Fore.RESET)
            if platform.system().lower().startswith('darwin'):
                matlab_cmd = ('cd %s && ./run_spm12.sh %s script' %
                              (spm_standalone_home, mcr_home))
            elif platform.system().lower().startswith('linux'):
                matlab_cmd = ('%s %s script' %
                              (os.path.join(spm_standalone_home, 'run_spm12.sh'), mcr_home))
            else:
                raise SystemError('Clinica only support macOS and Linux')
            spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True)
            cprint("Using SPM standalone version %s" % spm.SPMCommand().version)
        else:
            raise FileNotFoundError('$SPMSTANDALONE_HOME and $MCR_HOME are defined, but linked to non existent folder ')
Esempio n. 30
0
    def build_input_node(self):
        """Build and connect an input node to the pipeline.
        """

        from clinica.utils.stream import cprint
        import nipype.interfaces.utility as nutil
        import nipype.pipeline.engine as npe
        from clinica.lib.pycaps.caps_layout import CAPSLayout

        read_parameters_node = npe.Node(name="LoadingCLIArguments",
                                        interface=nutil.IdentityInterface(
                                            fields=self.get_input_fields(),
                                            mandatory_inputs=True))
        read_parameters_node.inputs.atlas_list = self.parameters['atlases']

        caps_layout = CAPSLayout(self.caps_directory)

        cprint('------- INPUT FILES FOR EACH SUBJECTS -------')

        subjects_regex = '|'.join(sub[4:] for sub in self.subjects)
        unique_session = set(list(self.sessions))
        sessions_regex = '|'.join(sub[4:] for sub in unique_session)
        cprint('  * grabbing all files from CAPS folder')
        caps_file = caps_layout.get(return_type='file',
                                    subject=subjects_regex,
                                    session=sessions_regex,
                                    group_id=self.parameters['group_id'],
                                    modulation=self.parameters['modulate'])
        if len(caps_file) != len(self.subjects):
            raise IOError(str(len(caps_file)) + ' file(s) grabbed, but there is ' + str(len(self.subjects)) + ' sessions')
        read_parameters_node.inputs.file_list = caps_file

        self.connect([(read_parameters_node, self.input_node, [('file_list', 'file_list')]),
                      (read_parameters_node, self.input_node, [('atlas_list', 'atlas_list')])
                      ])