From 7340fce916bc8f39f6bd522db51c080b642be4cc Mon Sep 17 00:00:00 2001
From: Anthony Gagnon <anthony.gagnon7@usherbrooke.ca>
Date: Thu, 9 Jan 2025 19:52:47 +0000
Subject: [PATCH 1/2] added required parameters specifying dti and fodf shells
 for more reproducibility

---
 conf/modules.config                           |  6 ++++++
 nextflow.config                               |  2 ++
 nextflow_schema.json                          | 20 ++++++++++++++++---
 subworkflows/nf-neuro/preproc_t1/main.nf      |  1 +
 .../nf-neuro/preproc_t1/preproc_t1.diff       |  3 ++-
 workflows/pediatric.nf                        |  2 +-
 6 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/conf/modules.config b/conf/modules.config
index 331f68e..818c61e 100644
--- a/conf/modules.config
+++ b/conf/modules.config
@@ -356,6 +356,8 @@ process {
     withName: 'NF_PEDIATRIC:PEDIATRIC:PREPROC_DWI:NORMALIZE_DWI' {
         ext.fa_mask_threshold = params.dwi_normalize_fa_mask_threshold
         ext.dwi_shell_tolerance = params.dwi_normalize_shell_tolerance
+        ext.dti_shells = params.dti_shells
+        ext.max_dti_shell_value = params.dti_max_shell_value
         publishDir = [
             path: { "${params.outdir}/${meta.id}/dwi/"},
             mode: params.publish_dir_mode,
@@ -458,6 +460,7 @@ process {
         ext.dwi_shell_tolerance = params.dti_shell_tolerance
         ext.max_dti_shell_value = params.dti_max_shell_value
         ext.b0_thr_extract_b0 = params.dti_b0_threshold
+        ext.dti_shells = params.dti_shells
 
         // ** DTI metrics to output ** //
         ext.ad = true
@@ -502,6 +505,8 @@ process {
         ext.dwi_shell_tolerance = params.frf_dwi_shell_tolerance
         ext.max_dti_shell_value = params.frf_max_dti_shell_value
         ext.min_fodf_shell_value = params.frf_min_fodf_shell_value
+        ext.fodf_shells = params.fodf_shells
+        ext.dti_shells = params.dti_shells
         ext.b0_thr_extract_b0 = params.frf_b0_threshold
         ext.set_method = params.frf_set_method
         ext.set_frf = params.frf_set_frf
@@ -522,6 +527,7 @@ process {
     withName: 'NF_PEDIATRIC:PEDIATRIC:RECONST_FODF' {
         ext.dwi_shell_tolerance = params.fodf_shell_tolerance
         ext.min_fodf_shell_value = params.fodf_min_fodf_shell_value
+        ext.fodf_shells = params.fodf_shells
         ext.b0_thr_extract_b0 = params.fodf_b0_threshold
         ext.sh_order = params.fodf_sh_order
         ext.sh_basis = params.fodf_sh_basis
diff --git a/nextflow.config b/nextflow.config
index dd302d2..651e167 100644
--- a/nextflow.config
+++ b/nextflow.config
@@ -103,6 +103,7 @@ params {
     dti_shell_tolerance                     = 50
     dti_max_shell_value                     = 1500
     dti_b0_threshold                        = 20
+    dti_shells                              = null
 
     // FRF
     frf_fa                                  = 0.7
@@ -121,6 +122,7 @@ params {
     // FODF Metrics
     fodf_shell_tolerance                    = 50
     fodf_min_fodf_shell_value               = 100
+    fodf_shells                             = null
     fodf_b0_threshold                       = 20
     fodf_sh_order                           = 8
     fodf_sh_basis                           = "descoteaux07"
diff --git a/nextflow_schema.json b/nextflow_schema.json
index 0f666b7..1d20aab 100644
--- a/nextflow_schema.json
+++ b/nextflow_schema.json
@@ -406,6 +406,7 @@
             "fa_icon": "fas fa-brain",
             "description": "Options for DTI processing.",
             "help_text": "These options are used to configure the DTI processing steps in the pipeline. You can use these options to customise the behaviour of the DTI processing steps.",
+            "required": ["dti_shells"],
             "properties": {
                 "dti_shell_tolerance": {
                     "type": "integer",
@@ -419,7 +420,7 @@
                     "description": "Maximum shell value used in the DTI processing step.",
                     "fa_icon": "fas fa-brain",
                     "default": 1500,
-                    "hidden": false
+                    "hidden": true
                 },
                 "dti_b0_threshold": {
                     "type": "integer",
@@ -427,6 +428,12 @@
                     "fa_icon": "fas fa-brain",
                     "default": 20,
                     "hidden": true
+                },
+                "dti_shells": {
+                    "type": "string",
+                    "description": "Shells used in the DTI processing step.",
+                    "fa_icon": "fas fa-brain",
+                    "hidden": false
                 }
             }
         },
@@ -477,14 +484,14 @@
                     "description": "Maximum DTI shell value used.",
                     "fa_icon": "fas fa-brain",
                     "default": 1500,
-                    "hidden": false
+                    "hidden": true
                 },
                 "frf_min_fodf_shell_value": {
                     "type": "integer",
                     "description": "Minimum FODF shell value used.",
                     "fa_icon": "fas fa-brain",
                     "default": 100,
-                    "hidden": false
+                    "hidden": true
                 },
                 "frf_b0_threshold": {
                     "type": "integer",
@@ -530,6 +537,7 @@
             "fa_icon": "fas fa-brain",
             "description": "Options for FODF processing.",
             "help_text": "These options are used to configure the FODF processing steps in the pipeline. You can use these options to customise the behaviour of the FODF processing steps.",
+            "required": ["fodf_shells"],
             "properties": {
                 "fodf_shell_tolerance": {
                     "type": "integer",
@@ -543,6 +551,12 @@
                     "description": "Minimum FODF shell value used.",
                     "fa_icon": "fas fa-brain",
                     "default": 100,
+                    "hidden": true
+                },
+                "fodf_shells": {
+                    "type": "string",
+                    "description": "Shells used in the FODF processing step.",
+                    "fa_icon": "fas fa-brain",
                     "hidden": false
                 },
                 "fodf_b0_threshold": {
diff --git a/subworkflows/nf-neuro/preproc_t1/main.nf b/subworkflows/nf-neuro/preproc_t1/main.nf
index 5ca4ec9..a77c95b 100644
--- a/subworkflows/nf-neuro/preproc_t1/main.nf
+++ b/subworkflows/nf-neuro/preproc_t1/main.nf
@@ -92,6 +92,7 @@ workflow PREPROC_T1 {
             ch_bet = IMAGE_RESAMPLE.out.image
                 .join(ch_template)
                 .join(ch_probability_map)
+                .map{ it + [[], []] }
 
             BETCROP_ANTSBET ( ch_bet )
             ch_versions = ch_versions.mix(BETCROP_ANTSBET.out.versions.first())
diff --git a/subworkflows/nf-neuro/preproc_t1/preproc_t1.diff b/subworkflows/nf-neuro/preproc_t1/preproc_t1.diff
index dc38d6a..7e25254 100644
--- a/subworkflows/nf-neuro/preproc_t1/preproc_t1.diff
+++ b/subworkflows/nf-neuro/preproc_t1/preproc_t1.diff
@@ -3,7 +3,7 @@ Changes in component 'nf-neuro/preproc_t1'
 Changes in 'preproc_t1/main.nf':
 --- subworkflows/nf-neuro/preproc_t1/main.nf
 +++ subworkflows/nf-neuro/preproc_t1/main.nf
-@@ -88,9 +88,10 @@
+@@ -88,9 +88,11 @@
              // The template and probability maps are mandatory if running antsBET. Since the
              // error message from nextflow when they are absent is either non-informative or
              // missing, we use ifEmpty to provide a more informative one.
@@ -13,6 +13,7 @@ Changes in 'preproc_t1/main.nf':
 -                .join(ch_probability_map.ifEmpty{ error("ANTS BET needs a tissue probability map") })
 +                .join(ch_template)
 +                .join(ch_probability_map)
++                .map{ it + [[], []] }
  
              BETCROP_ANTSBET ( ch_bet )
              ch_versions = ch_versions.mix(BETCROP_ANTSBET.out.versions.first())
diff --git a/workflows/pediatric.nf b/workflows/pediatric.nf
index 4935ce2..c3097be 100644
--- a/workflows/pediatric.nf
+++ b/workflows/pediatric.nf
@@ -126,7 +126,7 @@ workflow PEDIATRIC {
 
         ch_template = Channel.fromPath(params.t1_bet_template, checkIfExists: true)
         ch_probability_map = Channel.fromPath(params.t1_bet_template_probability_map, checkIfExists: true)
-            .map{ it + [[], []] }
+
         if ( params.t1_synthstrip_weights ) {
             ch_t1_weights = Channel.fromPath(params.t1_synthstrip_weights, checkIfExists: false)
         } else {

From 8b8e8ab8191b8cad472d6c5854e4155bcde1cf02 Mon Sep 17 00:00:00 2001
From: Anthony Gagnon <anthony.gagnon7@usherbrooke.ca>
Date: Thu, 9 Jan 2025 23:19:33 +0000
Subject: [PATCH 2/2] move checkup to workflow, update docs, and tests

---
 CHANGELOG.md                |  4 +++
 docs/usage.md               |  4 +--
 nextflow_schema.json        |  2 --
 tests/chained.nf.test       | 12 +++++++
 tests/multisubjects.nf.test |  6 ++++
 tests/tracking.nf.test      | 66 +++++++++++++++++++++++++++++++++++++
 workflows/pediatric.nf      |  3 ++
 7 files changed, 93 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8090e47..c12516f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased] - [2025-01-08]
 
+### `Added`
+
+- Required --dti_shells and --fodf_shells parameters.
+
 ### `Changed`
 
 - Fastsurfer and freesurfer outputs are now in their own dedicated output folder.
diff --git a/docs/usage.md b/docs/usage.md
index 0bc6748..80b91d3 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -122,10 +122,10 @@ An [example samplesheet](../assets/samplesheet.csv) has been provided with the p
 The typical command for running the pipeline is as follows:
 
 ```bash
-nextflow run scilus/nf-pediatric -r main --input ./samplesheet.csv --outdir ./results -profile docker
+nextflow run scilus/nf-pediatric -r main --input ./samplesheet.csv --outdir ./results --dti_shells "0 1000" --fodf_shells "0 1000" -profile docker
 ```
 
-This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles.
+This will launch the pipeline with the `docker` configuration profile. There is only 4 parameters that need to be supplied at runtime: `--input`: for the path to your samplesheet, `--oudir`: path to the output directory, `--dti_shells`: if the tracking profile is selected, you need to identify which shell to use for DTI fitting (0 and 1000 were selected in the previous example), and `--fodf_shells`: if the tracking profile is selected, specify your shells as for the DTI parameter. See below for more information about profiles.
 
 Note that the pipeline will create the following files in your working directory:
 
diff --git a/nextflow_schema.json b/nextflow_schema.json
index 1d20aab..5bfc7eb 100644
--- a/nextflow_schema.json
+++ b/nextflow_schema.json
@@ -406,7 +406,6 @@
             "fa_icon": "fas fa-brain",
             "description": "Options for DTI processing.",
             "help_text": "These options are used to configure the DTI processing steps in the pipeline. You can use these options to customise the behaviour of the DTI processing steps.",
-            "required": ["dti_shells"],
             "properties": {
                 "dti_shell_tolerance": {
                     "type": "integer",
@@ -537,7 +536,6 @@
             "fa_icon": "fas fa-brain",
             "description": "Options for FODF processing.",
             "help_text": "These options are used to configure the FODF processing steps in the pipeline. You can use these options to customise the behaviour of the FODF processing steps.",
-            "required": ["fodf_shells"],
             "properties": {
                 "fodf_shell_tolerance": {
                     "type": "integer",
diff --git a/tests/chained.nf.test b/tests/chained.nf.test
index 899de03..91bba83 100644
--- a/tests/chained.nf.test
+++ b/tests/chained.nf.test
@@ -53,6 +53,9 @@ nextflow_pipeline {
                 params.connectomics = true
                 params.tracking = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
             }
         }
 
@@ -85,6 +88,9 @@ nextflow_pipeline {
                 params.tracking = true
                 params.freesurfer = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
                 params.use_fastsurfer = true
                 params.fs_license = "https://www.dropbox.com/scl/fi/0s8lp6lydyd0rxawxb4jm/license.txt?rlkey=hz54oc0d4sor69avqphtrjvgn&st=9e0yij97&dl=0"
             }
@@ -122,6 +128,9 @@ nextflow_pipeline {
                 params.connectomics = true
                 params.tracking = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
             }
         }
 
@@ -164,6 +173,9 @@ nextflow_pipeline {
                 params.local_min_len                    = 15
                 params.local_fa_seeding_mask_threshold  = 0.10
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
             }
         }
 
diff --git a/tests/multisubjects.nf.test b/tests/multisubjects.nf.test
index 8ba466d..bd68f63 100644
--- a/tests/multisubjects.nf.test
+++ b/tests/multisubjects.nf.test
@@ -14,6 +14,9 @@ nextflow_pipeline {
                 params.outdir = "$outputDir"
                 params.use_fastsurfer = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
                 params.connectomics = true
                 params.tracking = true
                 params.freesurfer = true
@@ -55,6 +58,9 @@ nextflow_pipeline {
                 params.tracking = true
                 params.infant = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
                 // ** Infant specific parameters ** //
                 params.dwi_run_synthstrip               = true
                 params.dwi_normalize_fa_mask_threshold  = 0.10
diff --git a/tests/tracking.nf.test b/tests/tracking.nf.test
index 2f38145..fcdec83 100644
--- a/tests/tracking.nf.test
+++ b/tests/tracking.nf.test
@@ -13,6 +13,9 @@ nextflow_pipeline {
                 params.input = "$projectDir/tests/data/samplesheet_testtracking.csv"
                 params.outdir = "$outputDir"
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
                 params.tracking = true
 
             }
@@ -43,6 +46,9 @@ nextflow_pipeline {
                 params.input = "$projectDir/tests/data/samplesheet_testtracking.csv"
                 params.outdir = "$outputDir"
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
                 params.tracking = true
                 params.skip_dwi_preprocessing = true
 
@@ -76,6 +82,9 @@ nextflow_pipeline {
 
                 params.tracking = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
             }
         }
 
@@ -85,6 +94,48 @@ nextflow_pipeline {
         }
     }
 
+    test("Tracking profile no dti shells - should fail") {
+
+        when {
+            params {
+
+                params.input = "$projectDir/tests/data/samplesheet_testtracking_norev.csv"
+                params.outdir = "$outputDir"
+
+                params.tracking = true
+
+                params.fodf_shells = "0 1000"
+
+            }
+        }
+
+        then {
+            assert workflow.failed
+            assert workflow.stdout.contains("Please provide the DTI shells using --dti_shells parameter")
+        }
+    }
+
+    test("Tracking profile no fodf shells - should fail") {
+
+        when {
+            params {
+
+                params.input = "$projectDir/tests/data/samplesheet_testtracking_norev.csv"
+                params.outdir = "$outputDir"
+
+                params.tracking = true
+
+                params.dti_shells = "0 1000"
+
+            }
+        }
+
+        then {
+            assert workflow.failed
+            assert workflow.stdout.contains("Please provide the FODF shells using --fodf_shells parameter")
+        }
+    }
+
     test("Tracking profile no dwi - should fail") {
 
         when {
@@ -93,6 +144,9 @@ nextflow_pipeline {
                 params.input = "$projectDir/tests/data/samplesheet_testtracking_nodwi.csv"
                 params.outdir = "$outputDir"
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
                 params.tracking = true
 
             }
@@ -126,6 +180,9 @@ nextflow_pipeline {
                 params.local_fa_seeding_mask_threshold  = 0.10
                 params.run_local_tracking               = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
             }
         }
 
@@ -167,6 +224,9 @@ nextflow_pipeline {
                 params.local_min_len                    = 15
                 params.local_fa_seeding_mask_threshold  = 0.10
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
             }
         }
 
@@ -187,6 +247,9 @@ nextflow_pipeline {
                 params.tracking = true
                 params.infant = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
                 // ** Infant specific parameters ** //
                 params.dwi_run_synthstrip               = true
                 params.dwi_normalize_fa_mask_threshold  = 0.10
@@ -217,6 +280,9 @@ nextflow_pipeline {
                 params.tracking = true
                 params.infant = true
 
+                params.dti_shells = "0 1000"
+                params.fodf_shells = "0 1000"
+
                 // ** Infant specific parameters ** //
                 params.dwi_run_synthstrip               = true
                 params.dwi_normalize_fa_mask_threshold  = 0.10
diff --git a/workflows/pediatric.nf b/workflows/pediatric.nf
index c3097be..02cfe42 100644
--- a/workflows/pediatric.nf
+++ b/workflows/pediatric.nf
@@ -152,6 +152,9 @@ workflow PEDIATRIC {
     //
     if ( params.tracking ) {
 
+        if ( !params.dti_shells ) { error "Please provide the DTI shells using --dti_shells parameter" }
+        if ( !params.fodf_shells ) { error "Please provide the FODF shells using --fodf_shells parameter" }
+
         /* Load topup config if provided */
         if ( params.dwi_susceptibility_config_file ) {
             if ( file(params.dwi_susceptibility_config_file).exists() ) {