<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""
EPI MRI -processing workflows.

Originally coded by <NAME>. Refactored by the CRN Developers.
"""

import os
import os.path as op

from nipype.pipeline import engine as pe
from nipype.interfaces import ants
from nipype.interfaces import c3
from nipype.interfaces import fsl
from nipype.interfaces import nipy
from nipype.interfaces import utility as niu
from niworkflows.interfaces.masks import ComputeEPIMask, BETRPT
from niworkflows.interfaces.registration import FLIRTRPT, BBRegisterRPT
from niworkflows.data import get_mni_icbm152_nlin_asym_09c

from fmriprep.interfaces import DerivativesDataSink, FormatHMCParam
from fmriprep.interfaces.utils import nii_concat
from fmriprep.utils.misc import fix_multi_T1w_source_name, _first
from fmriprep.workflows.fieldmap import sdc_unwarp
from fmriprep.workflows.sbref import _extract_wm


def normalize_motion_func(in_file, format):
    import os
    import numpy as np
    def normalize_mc_params(params, source):
        """
        Normalize a single row of motion parameters to the SPM format.
        SPM saves motion parameters as:
            x   Right-Left          (mm)
            y   Anterior-Posterior  (mm)
            z   Superior-Inferior   (mm)
            rx  Pitch               (rad)
            ry  Yaw                 (rad)
            rz  Roll                (rad)
        """
        if source.upper() == 'FSL':
            params = params[[3, 4, 5, 0, 1, 2]]
        elif source.upper() in ('AFNI', 'FSFAST'):
            params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)]
            params[3:] = params[3:] * np.pi / 180.
        elif source.upper() == 'NIPY':
            from nipy.algorithms.registration import to_matrix44, aff2euler
            matrix = to_matrix44(params)
            params = np.zeros(6)
            params[:3] = matrix[:3, 3]
            params[-1:2:-1] = aff2euler(matrix)

        return params

    mpars = np.loadtxt(in_file)  # mpars is N_t x 6
    mpars = np.apply_along_axis(func1d=normalize_mc_params,
                                axis=1, arr=mpars,
                                source=format)
    np.savetxt("motion_params.txt", mpars)
    return os.path.abspath("motion_params.txt")


# pylint: disable=R0914
def epi_hmc(metadata, name='EPI_HMC', settings=None):
    """
    Performs :abbr:`HMC (head motion correction)` over the input
    :abbr:`EPI (echo-planar imaging)` image.
    """
    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(niu.IdentityInterface(fields=['epi']), name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(
        fields=['xforms', 'epi_hmc', 'out_epi', 'epi_mask', 'epi_mean', 'movpar_file']), name='outputnode')

    normalize_motion = pe.Node(niu.Function(function=normalize_motion_func,
                                            input_names=["in_file", "format"],
                                            output_names=["out_file"]),
                               name="normalize_motion")

    if "SliceTiming" in metadata:
        realigned_output = True
        # Head motion correction (hmc)
        hmc = pe.Node(nipy.SpaceTimeRealigner(), name="spacetime_realign")
        hmc.inputs.slice_times = metadata["SliceTiming"]
        hmc.inputs.tr = metadata["RepetitionTime"]
        hmc.inputs.slice_info = 2
        try:
            import mkl
        except ImportError:
            pass
        else:
            mkl.set_num_threads(settings["nthreads"])
            hmc.interface.num_threads = settings["nthreads"]
        hmc.interface.estimated_memory_gb = settings["biggest_epi_file_size_gb"] * 3

        mean = pe.Node(fsl.MeanImage(), name="EPImean")
        inu = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='EPImeanBias')

        # Calculate EPI mask on the average after HMC
        skullstrip_epi = pe.Node(ComputeEPIMask(generate_report=True, dilation=1),
                                 name='skullstrip_epi')

        normalize_motion.inputs.format = "NIPY"

        workflow.connect([
            (inputnode, hmc, [('epi', 'in_file')]),
            (hmc, mean, [('out_file', 'in_file')]),
            (mean, outputnode, [('out_file', 'epi_mean')]),
            (mean, inu, [('out_file', 'input_image')]),
            (inu, skullstrip_epi, [('output_image', 'in_file')]),
            (skullstrip_epi, outputnode, [('mask_file', 'epi_mask')]),
            (hmc, outputnode, [('out_file', 'out_epi')]),
            (hmc, normalize_motion, [('par_file', 'in_file')]),
            (normalize_motion, outputnode, [('out_file', 'movpar_file')]),
        ])

    else:
        realigned_output = False
        # Head motion correction (hmc)
        hmc = pe.Node(fsl.MCFLIRT(
            save_mats=True, save_plots=True, mean_vol=True), name='EPI_hmc')
        hmc.interface.estimated_memory_gb = settings["biggest_epi_file_size_gb"] * 3

        hcm2itk = pe.MapNode(c3.C3dAffineTool(fsl2ras=True, itk_transform=True),
                             iterfield=['transform_file'], name='hcm2itk')

        inu = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='EPImeanBias')

        # Calculate EPI mask on the average after HMC
        skullstrip_epi = pe.Node(ComputeEPIMask(generate_report=True, dilation=1),
                                 name='skullstrip_epi')

        split = pe.Node(fsl.Split(dimension='t'), name='SplitEPI')
        split.interface.estimated_memory_gb = settings["biggest_epi_file_size_gb"] * 3

        normalize_motion.inputs.format = "FSL"

        workflow.connect([
            (inputnode, hmc, [('epi', 'in_file')]),
            (hmc, hcm2itk, [('mat_file', 'transform_file'),
                            ('mean_img', 'source_file'),
                            ('mean_img', 'reference_file')]),
            (hcm2itk, outputnode, [('itk_transform', 'xforms')]),
            (hmc, normalize_motion, [('par_file', 'in_file')]),
            (normalize_motion, outputnode, [('out_file', 'movpar_file')]),
            (hmc, inu, [('mean_img', 'input_image')]),
            (inu, skullstrip_epi, [('output_image', 'in_file')]),
            (inu, outputnode, [('output_image', 'epi_mean')]),
            (skullstrip_epi, outputnode, [('mask_file', 'epi_mask')]),
            (inputnode, split, [('epi', 'in_file')]),
            (split, outputnode, [('out_files', 'out_epi')]),
        ])

    return workflow, realigned_output<commit_msg>working AFNI two step implementation<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""
EPI MRI -processing workflows.

Originally coded by <NAME>. Refactored by the CRN Developers.
"""

import os
import os.path as op

from nipype.pipeline import engine as pe
from nipype.interfaces import ants
from nipype.interfaces import afni
from nipype.interfaces import c3
from nipype.interfaces import fsl
from nipype.interfaces import nipy
from nipype.interfaces import utility as niu
from niworkflows.interfaces.masks import ComputeEPIMask, BETRPT
from niworkflows.interfaces.registration import FLIRTRPT, BBRegisterRPT
from niworkflows.data import get_mni_icbm152_nlin_asym_09c

from fmriprep.interfaces import DerivativesDataSink, FormatHMCParam
from fmriprep.interfaces.utils import nii_concat
from fmriprep.utils.misc import fix_multi_T1w_source_name, _first
from fmriprep.workflows.fieldmap import sdc_unwarp
from fmriprep.workflows.sbref import _extract_wm


def normalize_motion_func(in_file, format):
    import os
    import numpy as np
    def normalize_mc_params(params, source):
        """
        Normalize a single row of motion parameters to the SPM format.
        SPM saves motion parameters as:
            x   Right-Left          (mm)
            y   Anterior-Posterior  (mm)
            z   Superior-Inferior   (mm)
            rx  Pitch               (rad)
            ry  Yaw                 (rad)
            rz  Roll                (rad)
        """
        if source.upper() == 'FSL':
            params = params[[3, 4, 5, 0, 1, 2]]
        elif source.upper() in ('AFNI', 'FSFAST'):
            params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)]
            params[3:] = params[3:] * np.pi / 180.
        elif source.upper() == 'NIPY':
            from nipy.algorithms.registration import to_matrix44, aff2euler
            matrix = to_matrix44(params)
            params = np.zeros(6)
            params[:3] = matrix[:3, 3]
            params[-1:2:-1] = aff2euler(matrix)

        return params

    mpars = np.loadtxt(in_file)  # mpars is N_t x 6
    mpars = np.apply_along_axis(func1d=normalize_mc_params,
                                axis=1, arr=mpars,
                                source=format)
    np.savetxt("motion_params.txt", mpars)
    return os.path.abspath("motion_params.txt")


def create_custom_slice_timing_file_func(metadata):
    import os
    slice_timings = metadata["SliceTiming"]
    slice_timings_ms = [str(t) for t in slice_timings]
    out_file = "timings.1D"
    with open("timings.1D", "w") as fp:
        fp.write("\t".join(slice_timings_ms))

    return os.path.abspath(out_file)


# pylint: disable=R0914
def epi_hmc(metadata, name='EPI_HMC', settings=None):
    """
    Performs :abbr:`HMC (head motion correction)` over the input
    :abbr:`EPI (echo-planar imaging)` image.
    """
    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(niu.IdentityInterface(fields=['epi']), name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(
        fields=['xforms', 'epi_hmc', 'out_epi', 'epi_mask', 'epi_mean', 'movpar_file']), name='outputnode')

    normalize_motion = pe.Node(niu.Function(function=normalize_motion_func,
                                            input_names=["in_file", "format"],
                                            output_names=["out_file"]),
                               name="normalize_motion")

    # Head motion correction (hmc)
    hmc = pe.Node(fsl.MCFLIRT(
        save_mats=True, save_plots=True, mean_vol=True), name='EPI_hmc')
    hmc.interface.estimated_memory_gb = settings[
                                            "biggest_epi_file_size_gb"] * 3

    hcm2itk = pe.MapNode(c3.C3dAffineTool(fsl2ras=True, itk_transform=True),
                         iterfield=['transform_file'], name='hcm2itk')

    inu = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='EPImeanBias')

    # Calculate EPI mask on the average after HMC
    skullstrip_epi = pe.Node(ComputeEPIMask(generate_report=True, dilation=1),
                             name='skullstrip_epi')

    split = pe.Node(fsl.Split(dimension='t'), name='SplitEPI')
    split.interface.estimated_memory_gb = settings[
                                              "biggest_epi_file_size_gb"] * 3

    normalize_motion.inputs.format = "FSL"

    workflow.connect([
        (hmc, hcm2itk, [('mat_file', 'transform_file'),
                        ('mean_img', 'source_file'),
                        ('mean_img', 'reference_file')]),
        (hcm2itk, outputnode, [('itk_transform', 'xforms')]),
        (hmc, normalize_motion, [('par_file', 'in_file')]),
        (normalize_motion, outputnode, [('out_file', 'movpar_file')]),
        (hmc, inu, [('mean_img', 'input_image')]),
        (inu, skullstrip_epi, [('output_image', 'in_file')]),
        (inu, outputnode, [('output_image', 'epi_mean')]),
        (skullstrip_epi, outputnode, [('mask_file', 'epi_mask')]),
        (inputnode, split, [('epi', 'in_file')]),
        (split, outputnode, [('out_files', 'out_epi')]),
    ])

    realigned_output = False
    if "SliceTiming" in metadata:
        create_custom_slice_timing_file = pe.Node(niu.Function(function=create_custom_slice_timing_file_func,
                                                               input_names=["metadata"],
                                                               output_names=["out_file"]),
                                                  name="create_custom_slice_timing_file")
        create_custom_slice_timing_file.inputs.metadata = metadata

        # TODO: include -ignore ii
        func_slice_timing_correction = pe.Node(interface=afni.TShift(),
                                               name='func_slice_timing_correction')
        func_slice_timing_correction.inputs.outputtype = 'NIFTI_GZ'
        func_slice_timing_correction.inputs.tr = str(metadata["RepetitionTime"]) + "s"

        def prefix_at(x):
            return "@" + x

        workflow.connect([
            (inputnode, func_slice_timing_correction, [('epi', 'in_file')]),
            (create_custom_slice_timing_file, func_slice_timing_correction, [(('out_file', prefix_at),
                                                                               'tpattern')]),
            (func_slice_timing_correction, hmc, [('out_file', 'in_file')])
        ])

    else:
        workflow.connect([
            (inputnode, hmc, [('epi', 'in_file')])
        ])

    return workflow, realigned_output
{'fraction_non_alphanumeric': 0.1241854826488862, 'fraction_numerical': 0.009925746325200787, 'mean_word_length': 2.4061935483870966, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 29, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5253996', 'n_tokens_mistral': 4387, 'n_tokens_neox': 4150, 'n_words': 850}