<jupyter_start><jupyter_text>New T1 Linear pipeline (remplace preprocessing DL)This pipeline uses clinica tools. Main requirement (clinica >= 0.3.2).  Reading input data (input node in Clinica implementation)<jupyter_code>from clinica.utils.inputs import check_bids_folder
from clinica.utils.participant import get_subject_session_list

bids_directory = '/Users/mdiazmel/tmp/DL/ADNI_BIDS_T1_new_test/'
tsv = '/Users/mdiazmel/tmp/DL/t1_linear_test_2img.tsv'


check_bids_folder(bids_directory)
input_dir = bids_directory
is_bids_dir = True
base_dir = '/Users/mdiazmel/tmp/DL/working_dir/'

sessions, subjects = get_subject_session_list(
    input_dir,
    tsv,
    is_bids_dir,
    False,
    base_dir
    )


print(sessions)
print(subjects)
from clinica.utils.exceptions import ClinicaBIDSError, ClinicaException
from clinica.utils.inputs import clinica_file_reader
from clinica.utils.input_files import T1W_NII

# Inputs from anat/ folder
# ========================
# T1w file:
try:
    t1w_files = clinica_file_reader(subjects,
                                    sessions,
                                    bids_directory,
                                    T1W_NII)
except ClinicaException as e:
    err = 'Clinica faced error(s) while trying to read files in your CAPS directory.\n' + str(e)
    raise ClinicaBIDSError(err)
print(t1w_files)
def get_input_fields():
    """"Specify the list of possible inputs of this pipelines.
    Returns:
    A list of (string) input fields name.
    """
    return ['t1w']
import nipype.pipeline.engine as npe
import nipype.interfaces.utility as nutil
from nipype.interfaces import ants

read_node = npe.Node(name="ReadingFiles",
                     iterables=[
                         ('t1w', t1w_files),
                         ],
                     synchronize=True,
                     interface=nutil.IdentityInterface(
                         fields=get_input_fields())
                    )
type(read_node)
from clinica.utils.filemanip import get_subject_id

image_id_node = npe.Node(
    interface=nutil.Function(
        input_names=['bids_or_caps_file'],
        output_names=['image_id'],
        function= get_subject_id),
    name='ImageID')<jupyter_output><empty_output><jupyter_text>Create the processing nodes.1. `n4biascorrection` by *ANTS*. Uses nipype interface.<jupyter_code>n4biascorrection = npe.Node(
    name='n4biascorrection',
    interface=ants.N4BiasFieldCorrection(
        dimension=3, 
        save_bias=True, 
        bspline_fitting_distance=600
        )
    )
type(n4biascorrection)<jupyter_output><empty_output><jupyter_text>2. `RegistrationSynQuick` by *ANTS*. Uses nipype interface.<jupyter_code>ref_template = '/Users/mdiazmel/tmp/DL/mni_icbm152_nlin_sym_09c_nifti/mni_icbm152_nlin_sym_09c/mni_icbm152_t1_tal_nlin_sym_09c.nii'

ants_registration_node = npe.Node(
   name='antsRegistrationSynQuick',
   interface=ants.RegistrationSynQuick()
   )
ants_registration_node.inputs.fixed_image = ref_template
ants_registration_node.inputs.transform_type = 'a'
ants_registration_node.inputs.dimension = 3<jupyter_output><empty_output><jupyter_text>3. Crop image (using nifti). Use custom interface.<jupyter_code>from clinicadl.preprocessing.T1_preprocessing_utils import crop_nifti

cropnifti = npe.Node(
    name='cropnifti',
    interface=nutil.Function(
        function=crop_nifti,
        input_names=['input_img', 'ref_img'],
        output_names=['output_img', 'crop_template']
    )
)
cropnifti.inputs.ref_img = ref_template<jupyter_output><empty_output><jupyter_text>4. Histogram-based intensity normalization. This is a custom function performed by the binary `ImageMath` included with *ANTS*.<jupyter_code>from clinicadl.preprocessing.T1_preprocessing_utils import ants_histogram_intensity_normalization

## histogram-based intensity normalization
intensitynorm = npe.Node(
    name='intensitynormalization',
    interface=nutil.Function(
        input_names=['image_dimension', 'crop_template', 'input_img'],
        output_names=['output_img'],
        function=ants_histogram_intensity_normalization
    )
)
intensitynorm.inputs.image_dimension = 3<jupyter_output><empty_output><jupyter_text>5. Prepare the writing and the outputs:<jupyter_code># Get containers to ptoduce the CAPS structure
def container_from_filename(bids_or_caps_filename):
    """Extract container from BIDS or CAPS file.
                    
    Args:
        bids_or_caps_filename (str): full path to BIDS or CAPS filename .
    Returns:
        Container path of the form "subjects/<participant_id>/<session_id>"
    Examples:
        >>> from clinica.utils.nipype import container_from_filename
        >>> container_from_filename('/path/to/bids/sub-CLNC01/ses-M00/anat/sub-CLNC01_ses-M00_T1w.nii.gz')
        'subjects/sub-CLNC01/ses-M00'
        >>> container_from_filename('caps/subjects/sub-CLNC01/ses-M00/dwi/preprocessing/sub-CLNC01_ses-M00_preproc.nii')
        'subjects/sub-CLNC01/ses-M00'
    """
    import os
    import re
    m = re.search(r'(sub-[a-zA-Z0-9]+)/(ses-[a-zA-Z0-9]+)', bids_or_caps_filename)
    if m is None:
        raise ValueError('Input filename is not in a BIDS or CAPS compliant format.'
                         ' It does not contain the participant and session ID.')
    subject = m.group(1)
    session = m.group(2)
    return os.path.join('subjects', subject, session)
def get_data_datasink(image_id):
    substitutions_ls = [  # registration
        (image_id + '_T1w_corrected.nii.gz',
         image_id + '_corrected_T1w.nii.gz'),
        (image_id + 'Warped_cropped_intensity_norm.nii.gz',
         image_id + '_space-MNI152NLin2009cSym_res-1x1x1_intensity_norm_T1w.nii.gz'),
        (image_id + 'Warped_cropped.nii.gz',
        image_id + '_space-MNI152NLin2009cSym_res-1x1x1_T1w.nii.gz'),
        (image_id + 'Warped_cropped.pt',
         image_id + '_space-MNI152NLin2009cSym_res-1x1x1_T1w.pt'),
        (image_id + 'Warped.nii.gz',
         image_id + '_space-MNI152NLin2009cSym_res-1x1x1_linear_registration_T1w.nii.gz')
        ]
#    regexp_substitutions_ls = [
        # I don't know why it's adding this empty folder, so I remove it:
        # NOTE, . means any characters and * means any number of repetition in python regex
#        (r'/out_file_crop/_cropnifti\d{1,4}/', r'/'),
#        (r'/out_file_inn/_intensitynormalization\d{1,4}/', r'/'),
#        (r'/out_file_reg/_antsRegistrationSyNQuick\d{1,4}/', r'/'),
#        (r'/out_pt/_cropnifti\d{1,4}/', r'/'),
        # I don't know why it's adding this empty folder, so I remove it:
#        (r'trait_added/_datasinker\d{1,4}/', r'')
#    ]
    
    return image_id, substitutions_ls
# Create node to write selected files into the CAPS
from nipype.interfaces.io import DataSink

get_ids = npe.Node(
    interface=nutil.Function(
        input_names=['image_id'],
        output_names=['image_id_out', 'subst_ls'],
        function=get_data_datasink),
    name="GetIDs")
    
# Find container path from t1w filename
# =====================================
container_path = npe.Node(
    nutil.Function(
        input_names=['bids_or_caps_filename'],
        output_names=['container'],
        function=container_from_filename),
    name='ContainerPath')


caps_directory = '/Users/mdiazmel/tmp/DL/ADNI_CAPS2'

write_node = npe.Node(
    name="WriteCaps",
    interface=DataSink()
)
write_node.inputs.base_directory = caps_directory
write_node.inputs.parameterization = False

#write_node.inputs.substitutions = subst_ls
#write_node.inputs.regexp_substitutions = regexp_subst_ls<jupyter_output><empty_output><jupyter_text>Connecting the workflowThis code shows how to connect the nodes that executes preprocessing.<jupyter_code>from clinica.utils.nipype import fix_join

working_dir = '/Users/mdiazmel/tmp/DL/working_dir2/'
wf = npe.Workflow(name='t1_linear_dl', base_dir=working_dir)

wf.connect([
    (read_node, image_id_node, [('t1w', 'bids_or_caps_file')]),
    (read_node, container_path, [('t1w', 'bids_or_caps_filename')]),
    (image_id_node , ants_registration_node, [('image_id', 'output_prefix')]),
    (read_node, n4biascorrection, [("t1w", "input_image")]),
    
    (n4biascorrection, ants_registration_node, [('output_image', 'moving_image')]),
    
    (ants_registration_node, cropnifti, [('warped_image', 'input_img')]),
    
    (cropnifti, intensitynorm, [('output_img', 'input_img')]),
    (cropnifti, intensitynorm, [('crop_template', 'crop_template')]),
    
    # Connect to DataSink
    (container_path, write_node, [(('container', fix_join, 't1_linear'), 'container')]),  # Là, y a des chances que tu remplace le join() par 't1_linear' (je me rappelle plus le CAPS ^^)
    (image_id_node, get_ids, [('image_id', 'image_id')]),
    (get_ids, write_node, [('image_id_out', '@image_id')]),
    (get_ids, write_node, [('subst_ls', 'substitutions')]),
    #(get_ids, write_node, [('regexp_subst_ls', 'regexp_substitutions')]),
    (n4biascorrection, write_node, [('output_image', '@outfile_corr')]),
    (ants_registration_node, write_node, [('warped_image', '@outfile_reg')]),
    (cropnifti, write_node, [('output_img', '@outfile_crop')]),
    (intensitynorm, write_node, [('output_img', '@outfile_int')])
    
])



wf.write_graph("workflow_graph.dot")
wf.write_graph(graph2use='flat')
wf.run(plugin='MultiProc', plugin_args={'n_procs': 2})<jupyter_output>200203-21:02:31,789 nipype.workflow INFO:
	 Workflow t1_linear_dl settings: ['check', 'execution', 'logging', 'monitoring']
200203-21:02:31,836 nipype.workflow INFO:
	 Running in parallel.
200203-21:02:31,844 nipype.workflow INFO:
	 [MultiProc] Running 0 tasks, and 6 jobs ready. Free memory (GB): 7.20/7.20, Free processors: 2/2.
200203-21:02:31,935 nipype.workflow INFO:
	 [Job 0] Cached (t1_linear_dl.n4biascorrection).
200203-21:02:31,940 nipype.workflow INFO:
	 [Job 1] Cached (t1_linear_dl.ContainerPath).
200203-21:02:33,846 nipype.workflow INFO:
	 [MultiProc] Running 0 tasks, and 4 jobs ready. Free memory (GB): 7.20/7.20, Free processors: 2/2.
200203-21:02:33,919 nipype.workflow INFO:
	 [Job 2] Cached (t1_linear_dl.ImageID).
200203-21:02:33,925 nipype.workflow INFO:
	 [Job 8] Cached (t1_linear_dl.n4biascorrection).
200203-21:02:35,925 nipype.workflow INFO:
	 [Job 3] Cached (t1_linear_dl.antsRegistrationSynQuick).
200203-21:02:35,931 nipype.workflow INFO:
	 [Node] Outdated cache found[...]
{'fraction_non_alphanumeric': 0.12592878510083952, 'fraction_numerical': 0.032133552060214225, 'mean_word_length': 4.021317829457364, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '634085', 'license': 'MIT', 'n_tokens_mistral': 3899, 'n_tokens_neox': 3643, 'n_words': 661, 'path': 'clinicadl/notebooks/input_node_example.ipynb', 'repo_name': '921974496/AD-DL', 'size': '10363'}