<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:
"""
Anatomical Reference -processing workflows.

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

"""
from __future__ import print_function, division, absolute_import, unicode_literals

import os.path as op

from niworkflows.nipype.interfaces import ants
from niworkflows.nipype.interfaces import freesurfer as fs
from niworkflows.nipype.interfaces import utility as niu
from niworkflows.nipype.interfaces import io as nio
from niworkflows.nipype.pipeline import engine as pe

from niworkflows.interfaces.registration import RobustMNINormalizationRPT
from niworkflows.anat.skullstrip import afni_wf as init_skullstrip_afni_wf
import niworkflows.data as nid
from niworkflows.interfaces.masks import BrainExtractionRPT
from niworkflows.interfaces.segmentation import FASTRPT, ReconAllRPT

from fmriprep.interfaces import DerivativesDataSink, StructuralReference, MakeMidthickness
from fmriprep.interfaces.images import ConformSeries
from fmriprep.interfaces.reports import AnatomicalSummary
from fmriprep.utils.misc import fix_multi_T1w_source_name, add_suffix


#  pylint: disable=R0914
def init_anat_preproc_wf(skull_strip_ants, output_spaces, template, debug, freesurfer,
                         omp_nthreads, hires, reportlets_dir, output_dir,
                         name='anat_preproc_wf'):
    """T1w images preprocessing pipeline"""

    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(
        niu.IdentityInterface(fields=['t1w', 't2w', 'subjects_dir']),
        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(
        fields=['t1_preproc', 't1_brain', 't1_mask', 't1_seg', 't1_tpms',
                't1_2_mni', 't1_2_mni_forward_transform', 't1_2_mni_reverse_transform',
                'mni_mask', 'mni_seg', 'mni_tpms',
                'subjects_dir', 'subject_id', 'fs_2_t1_transform', 'surfaces']),
        name='outputnode')

    def bidsinfo(in_file):
        from fmriprep.interfaces.bids import BIDS_NAME
        match = BIDS_NAME.search(in_file)
        params = match.groupdict() if match is not None else {}
        return tuple(map(params.get, ['subject_id', 'ses_id', 'task_id',
                                      'acq_id', 'rec_id', 'run_id']))

    bids_info = pe.Node(
        niu.Function(function=bidsinfo,
                     output_names=['subject_id', 'ses_id', 'task_id',
                                   'acq_id', 'rec_id', 'run_id']),
        name='bids_info',
        run_without_submitting=True)

    summary = pe.Node(
        AnatomicalSummary(output_spaces=output_spaces, template=template),
        name='summary')

    # 0. Reorient T1w image(s) to RAS and resample to common voxel space
    t1_conform = pe.Node(ConformSeries(), name='t1_conform')

    # 1. Align and merge if several T1w images are provided
    t1_merge = pe.Node(
        # StructuralReference is fs.RobustTemplate if > 1 volume, copying otherwise
        StructuralReference(auto_detect_sensitivity=True,
                            initial_timepoint=1,      # For deterministic behavior
                            intensity_scaling=True,   # 7-DOF (rigid + intensity)
                            subsample_threshold=200,
                            ),
        name='t1_merge')

    # 2. T1 Bias Field Correction
    # Bias field correction is handled in skull strip workflows.

    # 3. Skull-stripping
    skullstrip_wf = init_skullstrip_afni_wf(name='skullstrip_afni_wf')
    if skull_strip_ants:
        skullstrip_wf = init_skullstrip_ants_wf(name='skullstrip_ants_wf',
                                                debug=debug,
                                                omp_nthreads=omp_nthreads)

    # 4. Segmentation
    t1_seg = pe.Node(FASTRPT(generate_report=True, segments=True,
                             no_bias=True, probability_maps=True),
                     name='t1_seg')

    # 5. Spatial normalization (T1w to MNI registration)
    t1_2_mni = pe.Node(
        RobustMNINormalizationRPT(
            float=True,
            generate_report=True,
            num_threads=omp_nthreads,
            flavor='testing' if debug else 'precise',
        ),
        name='t1_2_mni'
    )
    # should not be necessary but does not hurt - make sure the multiproc
    # scheduler knows the resource limits
    t1_2_mni.interface.num_threads = omp_nthreads

    # Resample the brain mask and the tissue probability maps into mni space
    mni_mask = pe.Node(
        ants.ApplyTransforms(dimension=3, default_value=0, float=True,
                             interpolation='NearestNeighbor'),
        name='mni_mask'
    )

    mni_seg = pe.Node(
        ants.ApplyTransforms(dimension=3, default_value=0, float=True,
                             interpolation='NearestNeighbor'),
        name='mni_seg'
    )

    mni_tpms = pe.MapNode(
        ants.ApplyTransforms(dimension=3, default_value=0, float=True,
                             interpolation='Linear'),
        iterfield=['input_image'],
        name='mni_tpms'
    )

    def set_threads(in_list, maximum):
        return min(len(in_list), maximum)

    workflow.connect([
        (inputnode, bids_info, [(('t1w', fix_multi_T1w_source_name), 'in_file')]),
        (inputnode, t1_conform, [('t1w', 't1w_list')]),
        (t1_conform, t1_merge, [('t1w_list', 'in_files'),
                                (('t1w_list', set_threads, omp_nthreads), 'num_threads'),
                                (('t1w_list', add_suffix, '_template'), 'out_file')]),<commit_msg>ENH: Do not use unbiased template if N > 2<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:
"""
Anatomical Reference -processing workflows.

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

"""
from __future__ import print_function, division, absolute_import, unicode_literals

import os.path as op

from niworkflows.nipype.interfaces import ants
from niworkflows.nipype.interfaces import freesurfer as fs
from niworkflows.nipype.interfaces import utility as niu
from niworkflows.nipype.interfaces import io as nio
from niworkflows.nipype.pipeline import engine as pe

from niworkflows.interfaces.registration import RobustMNINormalizationRPT
from niworkflows.anat.skullstrip import afni_wf as init_skullstrip_afni_wf
import niworkflows.data as nid
from niworkflows.interfaces.masks import BrainExtractionRPT
from niworkflows.interfaces.segmentation import FASTRPT, ReconAllRPT

from fmriprep.interfaces import DerivativesDataSink, StructuralReference, MakeMidthickness
from fmriprep.interfaces.images import ConformSeries
from fmriprep.interfaces.reports import AnatomicalSummary
from fmriprep.utils.misc import fix_multi_T1w_source_name, add_suffix


#  pylint: disable=R0914
def init_anat_preproc_wf(skull_strip_ants, output_spaces, template, debug, freesurfer,
                         omp_nthreads, hires, reportlets_dir, output_dir,
                         name='anat_preproc_wf'):
    """T1w images preprocessing pipeline"""

    workflow = pe.Workflow(name=name)

    inputnode = pe.Node(
        niu.IdentityInterface(fields=['t1w', 't2w', 'subjects_dir']),
        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(
        fields=['t1_preproc', 't1_brain', 't1_mask', 't1_seg', 't1_tpms',
                't1_2_mni', 't1_2_mni_forward_transform', 't1_2_mni_reverse_transform',
                'mni_mask', 'mni_seg', 'mni_tpms',
                'subjects_dir', 'subject_id', 'fs_2_t1_transform', 'surfaces']),
        name='outputnode')

    def bidsinfo(in_file):
        from fmriprep.interfaces.bids import BIDS_NAME
        match = BIDS_NAME.search(in_file)
        params = match.groupdict() if match is not None else {}
        return tuple(map(params.get, ['subject_id', 'ses_id', 'task_id',
                                      'acq_id', 'rec_id', 'run_id']))

    bids_info = pe.Node(
        niu.Function(function=bidsinfo,
                     output_names=['subject_id', 'ses_id', 'task_id',
                                   'acq_id', 'rec_id', 'run_id']),
        name='bids_info',
        run_without_submitting=True)

    summary = pe.Node(
        AnatomicalSummary(output_spaces=output_spaces, template=template),
        name='summary')

    # 0. Reorient T1w image(s) to RAS and resample to common voxel space
    t1_conform = pe.Node(ConformSeries(), name='t1_conform')

    # 1. Align and merge if several T1w images are provided
    t1_merge = pe.Node(
        # StructuralReference is fs.RobustTemplate if > 1 volume, copying otherwise
        StructuralReference(auto_detect_sensitivity=True,
                            initial_timepoint=1,      # For deterministic behavior
                            intensity_scaling=True,   # 7-DOF (rigid + intensity)
                            subsample_threshold=200,
                            ),
        name='t1_merge')

    # 2. T1 Bias Field Correction
    # Bias field correction is handled in skull strip workflows.

    # 3. Skull-stripping
    skullstrip_wf = init_skullstrip_afni_wf(name='skullstrip_afni_wf')
    if skull_strip_ants:
        skullstrip_wf = init_skullstrip_ants_wf(name='skullstrip_ants_wf',
                                                debug=debug,
                                                omp_nthreads=omp_nthreads)

    # 4. Segmentation
    t1_seg = pe.Node(FASTRPT(generate_report=True, segments=True,
                             no_bias=True, probability_maps=True),
                     name='t1_seg')

    # 5. Spatial normalization (T1w to MNI registration)
    t1_2_mni = pe.Node(
        RobustMNINormalizationRPT(
            float=True,
            generate_report=True,
            num_threads=omp_nthreads,
            flavor='testing' if debug else 'precise',
        ),
        name='t1_2_mni'
    )
    # should not be necessary but does not hurt - make sure the multiproc
    # scheduler knows the resource limits
    t1_2_mni.interface.num_threads = omp_nthreads

    # Resample the brain mask and the tissue probability maps into mni space
    mni_mask = pe.Node(
        ants.ApplyTransforms(dimension=3, default_value=0, float=True,
                             interpolation='NearestNeighbor'),
        name='mni_mask'
    )

    mni_seg = pe.Node(
        ants.ApplyTransforms(dimension=3, default_value=0, float=True,
                             interpolation='NearestNeighbor'),
        name='mni_seg'
    )

    mni_tpms = pe.MapNode(
        ants.ApplyTransforms(dimension=3, default_value=0, float=True,
                             interpolation='Linear'),
        iterfield=['input_image'],
        name='mni_tpms'
    )

    def set_threads(in_list, maximum):
        return min(len(in_list), maximum)

    def len_above_thresh(in_list, threshold):
        return len(in_list) > threshold

    workflow.connect([
        (inputnode, bids_info, [(('t1w', fix_multi_T1w_source_name), 'in_file')]),
        (inputnode, t1_conform, [('t1w', 't1w_list')]),
        (t1_conform, t1_merge, [('t1w_list', 'in_files'),
                                (('t1w_list', set_threads, omp_nthreads), 'num_threads'),
                                (('t1w_list', len_above_thresh, 2), 'fixed_timepoint'),
                                (('t1w_list', len_above_thresh, 2), 'no_iteration'),
                                (('t1w_list', add_suffix, '_template'), 'out_file')]),
{'fraction_non_alphanumeric': 0.09781021897810219, 'fraction_numerical': 0.0124516960068699, 'mean_word_length': 2.598887515451174, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4989272', 'n_tokens_mistral': 3830, 'n_tokens_neox': 3614, 'n_words': 767}