Question: cwltool "invalid field" error messages
0
gravatar for Tom
12 months ago by
Tom530
Tom530 wrote:

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 • 325 views
ADD COMMENTlink modified 12 months ago • written 12 months ago by Tom530
1

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

ADD REPLYlink written 11 months ago by Michael R. Crusoe1.8k
Please log in to add an answer.

Help
Access

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.
Powered by Biostar version 2.3.0
Traffic: 1030 users visited in the last hour