cwltool "invalid field" error messages
0
0
Entering edit mode
5.4 years ago
Tom ▴ 540

Hello everyone!

I have written an ExpressionTool that is supposed to take files/directories as input and put them all into a folder. When using this ExpressionTool in the context of a workflow i always get the following errors:

[step pooling_output] start
invalid field `nameroot`, expected one of: 'class', 'location', 'path', 'basename', 'listing'
invalid field `nameext`, expected one of: 'class', 'location', 'path', 'basename', 'listing'
[step pooling_output] completed success

I don't know what these are supposed to mean, and i don't know which part of the code is responsible. nameext isn't even referenced in the ExpressionTool. What makes me confused is that the error messages only show up when i use the ExpressionTool as part of a Workflow (example below). I tried running several workflows up to the point where the ExpressionTool would be used and collected their output at this point. When i then feed these exact outputs into the ExpressionTool, no error messages will show up. Could this just a be bug in cwltool? I now meticulously check the output of every workflow i run out of fear that the tool might somehow garble the output (which it has done once in the past, but that specific problem has been fixed).

A big thank you to anyone who can provide insight! Cheers

The ExpressionTool:

(I suspect this might strike some as a horrifying solution. Especially because of the separate inputs for arrays and single items. But i have yet to find a better way to do this in cwl. Happy to take suggestions!)

cwlVersion: v1.0
class: ExpressionTool
label: Returns a directory named after inputs.newname, containing all input files and directories.

requirements:
  InlineJavascriptRequirement: {}

inputs:
  file_single:
    type: File?
    label: A single file which will be placed in the output directory.
  file_array:
    type: File[]?
    label: An array of files which will be placed in the output directory.
  directory_single:
    type: Directory?
    label: A single directory which will be placed in the output directory as a subdirectory.
  directory_array:
    type: Directory[]?
    label: An array of directories which will be placed in the output directory as subdirectories.
  newname:
    type: string?
    label: Name of the output-directory. If no input is provided, tool will try use the nameroot of file_single, directory_single, file_array[0], directory_array[0] (in this order).

outputs:
  pool_directory:
    type: Directory
    label: Directory where all input files and subdirectories will be pooled. Named after inputs.newname.

expression: |
  ${
    //Check if an input for newname was provided. If yes, use this as new directory name.
    var newName = "";
    var needName = true;
    if ( inputs.newname != undefined ) {
      newName = inputs.newname;
      needName = false;
    }
    //Check which input files / directories are present. Add them to the new directory.
    //If no input for newname was provided, use the name of one of the files or directories.
    var outputList = [];
    if ( inputs.file_single != undefined ) {
      outputList.push( inputs.file_single );
      if ( needName == true ) {
        newName = inputs.file_single.nameroot;
        needName = false;
      }
    }
    if ( inputs.directory_single != undefined ) {
      outputList.push( inputs.directory_single );
      if ( needName == true ) {
        newName = inputs.directory_single.basename;
        needName = false;
      }
    }
    if ( inputs.file_array != undefined ) {
      for ( var count = 0; count < inputs.file_array.length; count++ ) {
        var nextfile = inputs.file_array[count];
        outputList.push( nextfile );
      }
      if ( needName == true ) {
        newName = ((inputs.file_array)[0]).nameroot;
        needName = false;
      }
    }
    if ( inputs.directory_array != undefined ) {
      for ( var count = 0; count < inputs.directory_array.length; count++ ) {
        var nextdir = inputs.directory_array[count];
        outputList.push( nextdir );
      }
      if ( needName == true ) {
        newName = ((inputs.directory_array)[0]).basename;
        needName = false;
      }
    }
    return {
      "pool_directory": {
        "class": "Directory",
        "basename": newName,
        "listing": outputList
      }
    };
  }

A simple workflow which uses it:

cwlVersion: v1.0
class: Workflow
label: Uses various quality control tools on the input assembly.

requirements:
  StepInputExpressionRequirement: {}

hints:
  SoftwareRequirement:
    packages:
      quast:
        specs: [ https://identifiers.org/RRID:SCR_001228 ]
        version: [ "5.0.2" ]

inputs:
  assembly:
    label: Assembly to perform qc on.
    type: File
  worker_threads:
    label: Number of CPU-threads used in computationally intensive steps.
    type: int
    default: 1

outputs:
  assembly_qc_directory:
    type: Directory
    outputSource: pooling_output/pool_directory

steps:
  quast:
    run: ../quastTool.cwl
    in:
      assembly: assembly
      worker_threads: worker_threads
    out: [report_directory]
  pooling_output:
    run: ../poolingTool.cwl
    in:
      directory_single: quast/report_directory
      newname:
        valueFrom: assembly-qc-reports
    out: [pool_directory]
cwl cwltool • 1.2k views
ADD COMMENT
1
Entering edit mode

FYI, this sounds like an error in cwltool, I am investigating

ADD REPLY

Login before adding your answer.

Traffic: 2668 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6