Process configuration
In nf-neuro, we use the task.ext
parameter namespace to define
configuration options that user can use to fine-tune the behavior of a module. Those options have two
specificities :
- They are optional by default. If a
parameter
is not defined,task.ext.parameter
will return the valuenull
. - They are static. Their value is bound to the module’s name. Dynamic parameters have to be defined using inputs.
The guidelines below present how to define those parameters, using the DENOISING_NLMEANS module example.
Defining optional parameter
Section titled “Defining optional parameter”The command scil_denoising_nlmeans.py accepts a few parameters that allow users to adjust its execution to the nature of their data :
- We can force the estimated noise distribution to be gaussian.
- The noise distribution can be set to a given sigma, estimated by a basic_sigma method or using the piesno method.
- We can set the number of coil use to acquire the MRI signal, using number_coils.
- We can restrict the noise estimation space using a mask.
- When using the basic_sigma method, it’s the mask_sigma parameter.
- We can force the use of all voxel with sigma_from_all_voxels.
The definition of their parameter in the module go in the groovy header part of the script section, the one
where the prefix
and args
variables are defined. Use the same operator logic, either the ternary
or elvis operator, to define the parameters above.
The full modifications of the module is given below. Take note of the mask_sigma
parameter, which required
the addition of a new input
, since it is a file which must be passed by nextflow at runtime. Also note the new
optional output, that returns the noise mask when the piesno
method is used :
input: tuple val(meta), path(image), path(mask) /* optional, input = [] */, path(noise_mask) /* optional, input = [] */output: tuple val(meta), path("*__denoised.nii.gz"), emit: image tuple val(meta), path("*__piesno_noise_mask.nii.gz"), emit: noise_mask, optional: true path "versions.yml", emit: versionsscript: def prefix = task.ext.prefix ?: "${meta.id}" def args = task.ext.args ?: [] def input_mask = mask ? "--mask_denoise $mask" : "" def noise_mask = noise_mask ? "--mask_sigma $noise_mask" : "" def ncoils = task.ext.number_of_coils ? "--number_coils $task.ext.number_of_coils" : "--number_coils 1" def sigma = task.ext.sigma ? "--sigma $task.ext.sigma" : "" def sigma_from_all_voxels = task.ext.sigma_from_all_voxels ? "--sigma_from_all_voxels" : "" def gaussian = task.ext.gaussian ? "--gaussian" : ""
def method = "" def save_mask = "" if ( !sigma ) { method = task.ext.method ? "--$task.ext.method" : "--basic_sigma" save_mask = (task.ext.method == "piesno") ? "--save_piesno_mask ${prefix}__piesno_noise_mask.nii.gz" : "" } """ export ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=1 export OMP_NUM_THREADS=1 export OPENBLAS_NUM_THREADS=1
scil_denoising_nlmeans.py $image ${prefix}__denoised.nii.gz $input_mask ${args.join(" ")} --processes $task.cpus scil_denoising_nlmeans.py $image ${prefix}__denoised.nii.gz $input_mask $noise_mask $save_mask \ $ncoils $gaussian $method $sigma $sigma_from_all_voxels \ ${args.join(" ")} --processes $tasks.cpus """
cat <<-END_VERSIONS > versions.yml "${task.process}": scilpy: \$(pip list | grep scilpy | tr -s ' ' | cut -d' ' -f2) END_VERSIONS """
With that, the module can be configured to the full extent of the command line it encloses. You will see how to access those parameters in the subworkflow configuration section. For now, it’s time to setup a container to host your dependencies, so users don’t have to install them by themselves.