Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle tools that returns exit code status 1 in stub sections. #40

Open
gagnonanthony opened this issue Nov 21, 2024 · 3 comments
Open
Assignees
Labels
bug Something isn't working

Comments

@gagnonanthony
Copy link
Contributor

When running a stub run for testing pipelines, some tools (such as ANTs) return an exit code status 1 when calling the help script. Example:

  Test [91f130a6] 'Connectomics + tracking profiles - should run successfully' FAILED (47.426s)

  Assertion failed:

  assert workflow.success
         |        |
         workflow false

  Nextflow stdout:

  ERROR ~ Error executing process > 'NF_PEDIATRIC:PEDIATRIC:PREPROC_T1:BETCROP_ANTSBET (sub-test)'

  Caused by:
    Process `NF_PEDIATRIC:PEDIATRIC:PREPROC_T1:BETCROP_ANTSBET (sub-test)` terminated with an error exit status (1)


  Command executed:

    antsBrainExtraction.sh
    scil_volume_math.py -h
    mrcalc -h

    touch sub-test__t1_bet.nii.gz
    touch sub-test__t1_bet_mask.nii.gz

    cat <<-END_VERSIONS > versions.yml
    "NF_PEDIATRIC:PEDIATRIC:PREPROC_T1:BETCROP_ANTSBET":
        scilpy: $(pip list | grep scilpy | tr -s ' ' | cut -d' ' -f2)
        mrtrix: $(mrcalc -version 2>&1 | sed -n 's/== mrcalc \([0-9.]\+\).*/\1/p')
        ants: $(antsRegistration --version | grep "Version" | sed -E 's/.*v([0-9]+\+\).*/\1/')
    END_VERSIONS

  Command exit status:
    1

  Command output:

    ==========
    == CUDA ==
    ==========

    CUDA Version 11.7.1

    Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

    This container image and its contents are governed by the NVIDIA Deep Learning Container License.
    By pulling and using the container, you accept the terms and conditions of this license:
    https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license

    A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience.

    WARNING: The NVIDIA Driver was not detected.  GPU functionality will not be available.
       Use the NVIDIA Container Toolkit to start this container with GPU support; see
       https://docs.nvidia.com/datacenter/cloud-native/ .

  Command error:
                  -o outputPrefix

    Example:

      bash /ants/bin/antsBrainExtraction.sh -d 3 -a t1.nii.gz -e brainWithSkullTemplate.nii.gz -m brainPrior.nii.gz -o output

    Required arguments:

         -d:  Image dimension                       2 or 3 (for 2- or 3-dimensional image)
         -a:  Anatomical image                      Structural image, typically T1.  If more than one
                                                    anatomical image is specified, subsequently specified
                                                    images are used during the segmentation process.  However,
                                                    only the first image is used in the registration of priors.
                                                    Our suggestion would be to specify the T1 as the first image.
         -e:  Brain extraction template             Anatomical template created using e.g. LPBA40 data set with
                                                    buildtemplateparallel.sh in ANTs.
         -m:  Brain extraction probability mask     Brain probability mask created using e.g. LPBA40 data set which
                                                    have brain masks defined, and warped to anatomical template and
                                                    averaged resulting in a probability image.
         -o:  Output prefix                         Output directory + file prefix

    Optional arguments:

         -c:  Tissue classification                 A k-means segmentation is run to find gray or white matter around
                                                    the edge of the initial brain mask warped from the template.
                                                    This produces a segmentation image with K classes, ordered by mean
                                                    intensity in increasing order. With this option, you can control
                                                    K and tell the script which classes represent CSF, gray and white matter.
                                                    Format (\"KxcsfLabelxgmLabelxwmLabel\")
                                                    Examples:
                                                             -c 3x1x2x3 for T1 with K=3, CSF=1, GM=2, WM=3 (default)
                                                             -c 3x3x2x1 for T2 with K=3, CSF=3, GM=2, WM=1
                                                             -c 3x1x3x2 for FLAIR with K=3, CSF=1 GM=3, WM=2
                                                             -c 4x4x2x3 uses K=4, CSF=4, GM=2, WM=3

         -f:  Brain extraction registration mask    Mask used for registration to limit the metric computation to
                                                    a specific region.
         -r:  Initial moving transform              An ITK affine transform (eg, from antsAI or ITK-SNAP) for the moving image.
                                                    Without this option, this script calls antsAI to search for a good initial moving
                                                    transform.
         -s:  Image file suffix                     Any of the standard ITK IO formats e.g. nrrd, nii.gz (default), mhd
         -u:  Use random seeding                    Use random number generated from system clock (1 (default)) or a fixed seed (0). Using
                                                    "-u 0" overrides a system setting of ANTS_RANDOM_SEED. To produce identical results,
                                                    multi-threading must also be disabled by setting the environment variable
                                                    ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=1.
         -k:  Keep temporary files                  Keep brain extraction/segmentation warps, etc (default = false).
         -q:  Use floating point precision          Use antsRegistration with floating point precision.

         -z:  Test / debug mode                     If > 0, runs a faster version of the script. Only for debugging, results will not be good.

  Work dir:
    /Users/anthonygagnon/code/nf-pediatric/.nf-test/tests/91f130a629851b164f125df47c95c074/work/57/a51a7869139f978115ce871f662540

  Container:
    docker.io/scilus/scilus:2.0.2

  Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out`

   -- Check '/Users/anthonygagnon/code/nf-pediatric/.nf-test/tests/91f130a629851b164f125df47c95c074/meta/nextflow.log' file for details
  ERROR ~ Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting

   -- Check '/Users/anthonygagnon/code/nf-pediatric/.nf-test/tests/91f130a629851b164f125df47c95c074/meta/nextflow.log' file for details
  Nextflow stderr:

  shell-init: error retrieving current directory: getcwd: cannot access parent directories: Undefined error: 0

nf-core does provide suggestions on how to deal with this (https://nf-co.re/docs/guidelines/components/modules#capturing-exit-codes), but it seems only to make nextflow ignore the output of the command, which is not really wanted when we want to make sure the command is available within the container.

List of possible solutions from my quick search:

  • Redirect the output to a stdout.log file, and assert it contains more than one line (an unavailable script still returns a singe line output)
  • Catch the exit code somehow, then feed the correct one to nextflow.
@gagnonanthony gagnonanthony added the bug Something isn't working label Nov 21, 2024
@AlexVCaron
Copy link
Collaborator

Here are the ways I found that prevent the error code when it happens. We can decide together on how to handle it @arnaudbore @gagnonanthony.

  • Add ! before the command (like ! antsBrainExtractionsh). It inverts the output code, so 1 becomes 0. However, it also flips 0 into 1, so use carefully. Not tested with other codes. It's short and effective and would error out when the problem is fixed on the dependency's side.

  • Put braces {} around the commands and catch the potential error code with ||. It's nice because you can do it one shot for all commands and you have fine grained control on codes caught. But it's kinda ugly :

codes=( 1 2 127 )
{

command1
command2
...

} || [[ " ${codes[@]} " =~ " $? " ]] && exit 0
  • Create a trap to catch any error code that get raised, simply : trap 'exit 0' ERR. However, just like that, it catches any code and transforms it in a 0, and makes calling the help useless. But we can use a function for trap, like trap 'handle_code' ERR, such as :
function handle_code () {
local code=$?
ignore=( 1 2 ... )

if [[ " ${ignore[@]} " =~ " $code " ]]
then
    exit 0
else
    exit $code
fi
}

or shorter :

function handle_code () {
local code=$?
ignore=( 1 2 ... )
exit $([[ " ${ignore[@]} " =~ " $code " ]] && echo 0 || echo $code)
}

@AlexVCaron
Copy link
Collaborator

I find the trap with the function to be the most effective. We can provide the lines in the documentation, the dev just copy-paste them. It's also something that could be easily integrated in a potential template.

The ! is definitely simpler though and could be enough for now.

@gagnonanthony
Copy link
Contributor Author

I also like the trap solution, even though it is more complicated than the !. Once it's documented, I feel everyone should be able to use it. What do you think @arnaudbore ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants