Skip to content

Commit

Permalink
more metadata, added test, fix to modules and more configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexVCaron committed Dec 17, 2024
1 parent 2b7a568 commit 1e37018
Show file tree
Hide file tree
Showing 8 changed files with 1,243 additions and 32 deletions.
6 changes: 3 additions & 3 deletions modules/nf-neuro/preproc/eddy/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ process PREPROC_EDDY {
task.ext.when == null || task.ext.when

script:
def args = task.ext.args ?: ''
def eddy_options = task.ext.args ? "--eddy_options \"$task.ext.args\"" : ""
def prefix = task.ext.prefix ?: "${meta.id}"
def slice_drop_flag = task.ext.slice_drop_correction ? "--slice_drop_correction " : ""
def bet_topup_before_eddy_f = task.ext.bet_topup_before_eddy_f ?: ""
Expand Down Expand Up @@ -74,7 +74,7 @@ process PREPROC_EDDY {
--readout $readout --out_script --fix_seed\
--n_reverse \${number_rev_dwi}\
--lsr_resampling\
$slice_drop_flag
$slice_drop_flag $eddy_options
else
scil_dwi_extract_b0.py \${dwi} \${bval} \${bvec} ${prefix}__b0.nii.gz --mean\
--b0_threshold $b0_thr_extract_b0 --skip_b0_check
Expand All @@ -89,7 +89,7 @@ process PREPROC_EDDY {
--eddy_cmd $eddy_cmd --b0_thr $b0_thr_extract_b0\
--encoding_direction $encoding\
--readout $readout --out_script --fix_seed\
$slice_drop_flag
$slice_drop_flag $eddy_options
fi
echo "--very_verbose $extra_args" >> eddy.sh
Expand Down
1 change: 1 addition & 0 deletions subworkflows/nf-neuro/preproc_t1/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ workflow PREPROC_T1 {
ch_bet = IMAGE_RESAMPLE.out.image
.join(ch_template.ifEmpty{ error("ANTS BET needs a template") })
.join(ch_probability_map.ifEmpty{ error("ANTS BET needs a tissue probability map") })
.map{ it + [[], []] }

BETCROP_ANTSBET ( ch_bet )
ch_versions = ch_versions.mix(BETCROP_ANTSBET.out.versions.first())
Expand Down
32 changes: 24 additions & 8 deletions subworkflows/nf-neuro/tractoflow/main.nf
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

// PREPROCESSING
include { PREPROC_DWI } from '../../../subworkflows/nf-neuro/preproc_dwi/main'
include { PREPROC_T1 } from '../../../subworkflows/nf-neuro/preproc_t1/main'
include { PREPROC_DWI } from '../preproc_dwi/main'
include { PREPROC_T1 } from '../preproc_t1/main'
include { RECONST_DTIMETRICS as REGISTRATION_FA } from '../../../modules/nf-neuro/reconst/dtimetrics/main'
include { REGISTRATION as T1_REGISTRATION } from '../../../subworkflows/nf-neuro/registration/main'
include { REGISTRATION as T1_REGISTRATION } from '../registration/main'
include { REGISTRATION_ANTSAPPLYTRANSFORMS as TRANSFORM_WMPARC } from '../../../modules/nf-neuro/registration/antsapplytransforms/main'
include { REGISTRATION_ANTSAPPLYTRANSFORMS as TRANSFORM_APARC_ASEG } from '../../../modules/nf-neuro/registration/antsapplytransforms/main'
include { ANATOMICAL_SEGMENTATION } from '../../../subworkflows/nf-neuro/anatomical_segmentation/main'
include { ANATOMICAL_SEGMENTATION } from '../anatomical_segmentation/main'

// RECONSTRUCTION
include { RECONST_FRF } from '../../../modules/nf-neuro/reconst/frf/main'
Expand All @@ -32,10 +32,10 @@ def group_frf ( label, ch_frf ) {
workflow TRACTOFLOW {
take:
ch_dwi // channel : [required] meta, dwi, bval, bvec
ch_t1 // channel : [required] meta, t1
ch_sbref // channel : [optional] meta, sbref
ch_rev_dwi // channel : [optional] meta, rev_dwi, rev_bval, rev_bvec
ch_rev_sbref // channel : [optional] meta, rev_sbref
ch_t1 // channel : [required] meta, t1
ch_wmparc // channel : [optional] meta, wmparc
ch_aparc_aseg // channel : [optional] meta, aparc_aseg
ch_topup_config // channel : [optional] topup_config
Expand Down Expand Up @@ -157,10 +157,13 @@ workflow TRACTOFLOW {
ch_versions = ch_versions.mix(RECONST_FRF.out.versions.first())

/* Run fiber response aeraging over subjects */
ch_single_frf = RECONST_FRF.out.frf
.map{ it + [[], []] }

ch_fiber_response = RECONST_FRF.out.wm_frf
.join(RECONST_FRF.out.gm_frf)
.join(RECONST_FRF.out.csf_frf)
.mix(RECONST_FRF.out.frf)
.mix(ch_single_frf)

if ( params.fodf_use_average_frf ) {
ch_single_frf = group_frf("ssst", RECONST_FRF.out.frf)
Expand All @@ -177,8 +180,21 @@ workflow TRACTOFLOW {
RECONST_MEANFRF( ch_meanfrf )
ch_versions = ch_versions.mix(RECONST_MEANFRF.out.versions.first())

ch_fiber_response = RECONST_FRF.out.map{ it[0] }
.combine( RECONST_MEANFRF.out.meanfrf )
ch_meanfrf = RECONST_MEANFRF.out.meanfrf
.map{ ["frf"] + it }
.branch{
ssst: it[1] == "ssst"
wm: it[1] == "wm"
gm: it[1] == "gm"
csf: it[1] == "csf"
}

ch_fiber_response = ch_meanfrf.wm.map{ [it[0], it[2]] }
.join(ch_meanfrf.gm.map{ [it[0], it[2]] })
.join(ch_meanfrf.csf.map{ [it[0], it[2]] })
.map{ it[1..-1] }
.mix(ch_meanfrf.ssst.map{ [it[1], [], []] })
.combine(RECONST_FRF.out.map{ it[0] })
}

//
Expand Down
15 changes: 9 additions & 6 deletions subworkflows/nf-neuro/tractoflow/meta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ description: |
This subworkflow implements the TractoFlow [1] pipeline. It can process raw diffusion and T1 weighted image to reduce
acquisition biases, align anatomical and diffusion space, compute DTI and fODF metrics and generate whole brain
tractograms.
--------- Steps --------------------
---------- Configuration ----------
- nextflow.config : contains an example configuration for the subworkflow. Includes :
- modules.config : contains the bindings to the modules parameters and some defaults making it Tractoflow.
-------------- Steps --------------
PREPROCESS DWI (preproc_dwi, nf-neuro)
Preprocess the DWI image including brain extraction, MP-PCA denoising, eddy current and motion correction, N4 bias
correction, normalization and resampling.
Expand Down Expand Up @@ -53,6 +56,11 @@ input:
description: |
The input channel containing the DWI file, B-values and B-vectors in FSL format files.
Structure: [ val(meta), path(dwi), path(bval), path(bvec) ]
- ch_t1:
type: file
description: |
The input channel containing the anatomical T1 weighted image.
Structure: [ val(meta), path(t1) ]
- ch_sbref:
type: file
description: |
Expand All @@ -68,11 +76,6 @@ input:
description: |
(Optional) The input channel containing the reverse b0 file.
Structure: [ val(meta), path(rev_b0) ]
- ch_t1:
type: file
description: |
The input channel containing the anatomical T1 weighted image.
Structure: [ val(meta), path(t1) ]
- ch_aparc_aseg:
type: file
description: |
Expand Down
214 changes: 214 additions & 0 deletions subworkflows/nf-neuro/tractoflow/modules.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@

process {

/* SUBWORKFLOWS CONFIGURATION */

withName: "TRACTOFLOW:PREPROC_DWI:DENOISE_DWI" {
ext.extent = params.dwi_noise_filter_patch_size
}

withName: "TRACTOFLOW:PREPROC_DWI:DENOISE_REVDWI" {
ext.extent = params.dwi_noise_filter_patch_size
}

withName: "TRACTOFLOW:PREPROC_DWI:TOPUP_EDDY:UTILS_EXTRACTB0" {
ext.b0_extraction_strategy = "mean"
}

withName: "TRACTOFLOW:PREPROC_DWI:TOPUP_EDDY:PREPROC_TOPUP" {
ext.prefix_topup = params.dwi_susceptibility_filter_output_prefix
ext.default_config_topup = params.dwi_susceptibility_filter_config_file
ext.encoding = "y" //FIXME : this is subject bound, pass through meta ?
ext.readout = 0.062 //FIXME : this is subject bound, pass through meta ?
ext.b0_thr_extract_b0 = params.dwi_b0_extract_threshold
}

withName: "TRACTOFLOW:PREPROC_DWI:TOPUP_EDDY:PREPROC_EDDY" {
ext.prefix_topup = params.dwi_susceptibility_filter_output_prefix
ext.slice_drop_flag = params.dwi_motion_and_eddy_filter_restore_slices
ext.bet_topup_before_eddy_f = params.dwi_motion_and_eddy_filter_bet_f_threshold
ext.eddy_cmd = params.dwi_motion_and_eddy_filter_command
ext.dilate_b0_mask_prelim_brain_extraction = params.dwi_mask_prelim_bet_dilation_radius
ext.bet_prelim_f = params.dwi_mask_prelim_bet_f_threshold
ext.b0_thr_extract_b0 = params.dwi_b0_extract_threshold
ext.encoding = "y" //FIXME : this is subject bound, pass through meta ?
ext.readout = 0.062 //FIXME : this is subject bound, pass through meta ?
ext.args = params.dwi_motion_and_eddy_filter_command_args
}

withName: "TRACTOFLOW:PREPROC_DWI:BETCROP_FSLBETCROP" {
ext.bet_f = params.dwi_mask_final_bet_f_threshold
ext.b0_thr = params.dwi_b0_extract_threshold
ext.crop = true
ext.dilate = false
}

withName: "TRACTOFLOW:PREPROC_DWI:N4_DWI" {
ext.bspline_knot_per_voxel = params.dwi_intensities_normalize_density
ext.shrink_factor = params.dwi_intensities_normalize_subsampling
}

withName: "TRACTOFLOW:PREPROC_DWI:RESAMPLE_DWI" {
ext.voxel_size = params.dwi_spatial_resample_resolution
ext.interp = params.dwi_spatial_resample_interpolation
ext.first_suffix = "dwi"
}

withName: "TRACTOFLOW:PREPROC_DWI:BETCROP_CROPVOLUME" {
ext.output_bbox = false
}

withName: "TRACTOFLOW:PREPROC_DWI:RESAMPLE_MASK" {
ext.voxel_size = params.dwi_spatial_resample_resolution
ext.interp = "nn"
ext.first_suffix = "dwi_mask"
}

withName: "TRACTOFLOW:PREPROC_T1:BETCROP_CROPVOLUME_T1" {
ext.output_bbox = true
ext.first_suffix = "t1"
}

withName: "TRACTOFLOW:PREPROC_T1:IMAGE_RESAMPLE" {
ext.voxel_size = params.t1_spatial_resample_resolution
ext.interp = params.t1_spatial_resample_interpolation
ext.first_suffix = "t1"
}

//withName: "TRACTOFLOW:T1_REGISTRATION:REGISTER_ANATTODWI" {
// Nothing to do !
//}

//withName: "TRACTOFLOW:ANATOMICAL_SEGMENTATION:SEGMENTATION_FASTSEG" {
// Nothing to do !
//}

//withName: "TRACTOFLOW:ANATOMICAL_SEGMENTATION:SEGMENTATION_FREESURFERSEG" {
// Nothing to do !
//}

/* MODULES CONFIGURATION */

withName: "TRACTOFLOW:REGISTRATION_FA" {
ext.fa = true
ext.ad = false
ext.evecs = false
ext.evals = false
ext.ga = false
ext.rgb = false
ext.md = false
ext.mode = false
ext.norm = false
ext.rd = false
ext.tensor = false
ext.nonphysical = false
ext.pulsation = false
ext.residual = false
}

withName: "TRACTOFLOW:TRANSFORM_WMPARC" {
ext.dimensionality = 3
ext.image_type = 0
ext.interpolation = "NearestNeighbor"
ext.output_dtype = "uchar"
ext.default_val = 0
}

withName: "TRACTOFLOW:TRANSFORM_APARC_ASEG" {
ext.dimensionality = 3
ext.image_type = 0
ext.interpolation = "MultiLabel"
ext.output_dtype = "short"
ext.default_val = 0
}

withName: "TRACTOFLOW:RECONST_FRF" {
ext.fa = params.dwi_fodf_fit_frf_max_fa_threshold
ext.fa_min = params.dwi_fodf_fit_frf_min_fa_threshold
ext.nvox_min = params.dwi_fodf_fit_frf_min_n_voxels
ext.roi_radius = params.dwi_fodf_fit_frf_roi_radius
ext.set_frf = params.dwi_fodf_fit_force_frf ? true : false
ext.manual_frf = params.dwi_fodf_fit_force_frf
}

//withName: "RECONST_MEANFRF" {
// Nothing to do !
//}

withName: "TRACTOFLOW:RECONST_DTIMETRICS" {
ext.ad = true
ext.evecs = true
ext.evals = true
ext.fa = true
ext.ga = true
ext.rgb = true
ext.md = true
ext.mode = true
ext.norm = true
ext.rd = true
ext.tensor = true
ext.nonphysical = true
ext.pulsation = true
ext.residual = true
}

withName: "TRACTOFLOW:RECONST_FODF" {
ext.b0_thr_extract_b0 = params.dwi_b0_extract_threshold
ext.dwi_shell_tolerance = params.dwi_shell_extract_tolerance
ext.min_fodf_shell_value = params.dwi_fodf_fit_shell_min_bval
ext.fodf_shells = params.dwi_fodf_fit_shells
ext.sh_order = params.dwi_fodf_fit_order
ext.sh_basis = params.dwi_fodf_fit_basis
ext.fa_threshold = params.dwi_fodf_fit_peaks_ventricle_max_fa
ext.md_threshold = params.dwi_fodf_fit_peaks_ventricle_min_md
ext.relative_threshold = params.dwi_fodf_fit_peaks_relative_threshold
ext.fodf_metrics_a_factor = params.dwi_fodf_fit_peaks_absolute_factor
ext.absolute_peaks = true
ext.peaks = true
ext.peak_indices = true
ext.afd_max = true
ext.afd_total = true
ext.afd_sum = true
ext.nufo = true
}

withName: "TRACTOFLOW:TRACKING_PFTTRACKING" {
ext.pft_seeding_mask_type = params.fodf_pft_fit_seeding_type
ext.pft_fa_seeding_mask_threshold = params.fodf_pft_fit_seeding_fa_mask_threshold
ext.pft_seeding = params.fodf_pft_fit_seeding_strategy
ext.pft_nbr_seeds = params.fodf_pft_fit_seeding_n_seeds
ext.pft_algo = params.fodf_pft_fit_algorithm
ext.pft_step = params.fodf_pft_fit_step_size
ext.pft_theta = params.fodf_pft_fit_theta_max_deviation
ext.pft_sfthres = params.fodf_pft_fit_sf_threshold
ext.pft_sfthres_init = params.fodf_pft_fit_sf_initial_threshold
ext.pft_min_len = params.fodf_pft_fit_streamline_min_length
ext.pft_max_len = params.fodf_pft_fit_streamline_max_length
ext.pft_particles = params.fodf_pft_fit_filter_n_particles
ext.pft_back = params.fodf_pft_fit_filter_backward_step_size
ext.pft_front = params.fodf_pft_fit_filter_forward_step_size
ext.pft_random_seed = params.fodf_pft_fit_random_seed
ext.pft_compress_streamlines = params.fodf_pft_fit_compress_tractogram
ext.pft_compress_value = params.fodf_pft_fit_compress_max_displacement
ext.basis = params.dwi_fodf_fit_basis
}

withName: "TRACTOFLOW:TRACKING_LOCALTRACKING" {
ext.local_tracking_mask_type = params.fodf_local_fit_tracking_mask_type
ext.local_fa_tracking_mask_threshold = params.fodf_local_fit_tracking_mask_fa_threshold
ext.local_seeding_mask_type = params.fodf_local_fit_seeding_type
ext.local_fa_seeding_mask_threshold = params.fodf_local_fit_seeding_fa_threshold
ext.local_seeding = params.fodf_local_fit_seeding_strategy
ext.local_nbr_seeds = params.fodf_local_fit_seeding_n_seeds
ext.local_algo = params.fodf_local_fit_algorithm
ext.local_step = params.fodf_local_fit_step_size
ext.local_theta = params.fodf_local_fit_theta_max_deviation
ext.local_sfthres = params.fodf_local_fit_sf_threshold
ext.local_min_len = params.fodf_local_fit_streamline_min_length
ext.local_max_len = params.fodf_local_fit_streamline_max_length
ext.local_random_seed = params.fodf_local_fit_random_seed
ext.local_compress_streamlines = params.fodf_local_fit_compress_tractogram
ext.local_compress_value = params.fodf_local_fit_compress_max_displacement
ext.basis = params.dwi_fodf_fit_basis
}
}
Loading

0 comments on commit 1e37018

Please sign in to comment.