Use inline javascript when specifying input string

Is it possible to use inline javascript in order to construct an input string in a workflow? Below is an example of my workflow:

cwlVersion: v1.2
class: Workflow

requirements:
  InlineJavascriptRequirement: {}

inputs:
  sampleID:
    type: string
  fastq1:
    type: File
  fastq2:
    type: File
  library: 
    type: string
  platform:
    type: string
  platformUnit:
    type: string

outputs:
  out:
    type: File
    outputSource: GATK_AddOrReplaceReadGroups/output_bam

steps:
  GATK_FastqToSam:
    run: ../../tools/GATK/GATK_FastqToSam.cwl
    in:
      fastq1: fastq1
      fastq2: fastq2
      output: $(inputs.sampleID + ".bam") 
      SM: sampleID
    out: [output_bam]
  GATK_AddOrReplaceReadGroups:
    run: ../../tools/GATK/GATK_AddOrReplaceReadGroups.cwl
    in:
      bam:
        source: GATK_FastqToSam/output_bam
      output: $(inputs.sampleID + ".RG.bam") 
      SM: sampleID
      LB: library
      PL: platform
      PU: platformUnit
    out: [output_bam]

Specifically, when specifying the input parameter named “output” I would like to concatenate the sampleID string to another string. You can see I’ve tried to do it like so

output: $(inputs.sampleID + ".RG.bam") 

However, cwltool gives me the following error:

ERROR Tool definition failed validation:
convert_fastq_to_bam.cwl:27:1: checking field 'steps'
convert_fastq_to_bam.cwl:36:3:   checking object
                                 'convert_fastq_to_bam.cwl#GATK_AddOrReplaceReadGroups'
convert_fastq_to_bam.cwl:38:5:     checking field 'in'
convert_fastq_to_bam.cwl:41:7:       checking object
                                     'convert_fastq_to_bam.cwl#GATK_AddOrReplaceReadGroups/output'
                                       Field 'source' references unknown identifier
                                       '$(inputs.sampleID + ".RG.bam")', tried
                                       file:///Users/me/Documents/cwl-demo-pipeline/workflows/alignment/convert_fastq_to_bam.cwl#$(inputs.sampleID
                                       + ".RG.bam")

Yes, you want to do this:

      output: { valueFrom: '$(inputs.sampleID + ".bam")' }
1 Like

Or even more concisely output: { valueFrom: $(inputs.sampleID).bam }

Michael meant to write:

output: { valueFrom: $(inputs.sampleID).bam }

Michael’s version is actually much better, as it is a plain parameter substitution and avoids doing any Javascript evaluation at all.

1 Like

Thank you for your help. I’m trying to run my workflow with the following command:

cwltool convert_fastq_to_bam.cwl --fastq1 ../../test_data/mysample_R1_001.fastq.gz --fastq2 ../../test_data/mysample_R2_001.fastq.gz --library "Solexa-272222" --platform "illumina" --platformUnit "H0164ALXX140820.2" --sampleID "mysample"

but am getting this error:

INFO [workflow ] start
INFO [workflow ] starting step GATK_FastqToSam
Expecting value: line 1 column 1 (char 0)
script was:
01 "use strict";
02 var inputs = {
03     "SM": "mysample",
04     "fastq1": {
05         "class": "File",
06         "location": "file:///Users/me/Documents/projects/cwl-demo-pipeline/test_data/mysample_R1_001.fastq.gz",
07         "size": 70944943,
08         "basename": "mysample_R1_001.fastq.gz",
09         "nameroot": "mysample_R1_001.fastq",
10         "nameext": ".gz"
11     },
12     "fastq2": {
13         "class": "File",
14         "location": "file:///Users/me/Documents/projects/cwl-demo-pipeline/test_data/mysample_R2_001.fastq.gz",
15         "size": 77256188,
16         "basename": "mysample_R2_001.fastq.gz",
17         "nameroot": "mysample_R2_001.fastq",
18         "nameext": ".gz"
19     },
20     "output": null
21 };
22 var self = null;
23 var runtime = {
24     "tmpdir": null,
25     "outdir": null
26 };
27 (function(){return ((inputs.sampleID));})()
stdout was: 'undefined'
stderr was: ''

Below is what my workflow currently looks like:

cwlVersion: v1.2
class: Workflow

requirements:
  InlineJavascriptRequirement: {}
  StepInputExpressionRequirement: {}

inputs:
  sampleID:
    type: string
  fastq1:
    type: File
  fastq2:
    type: File
  library: 
    type: string
  platform:
    type: string
  platformUnit:
    type: string


outputs:
  out:
    type: File
    outputSource: GATK_AddOrReplaceReadGroups/output_bam

steps:
  GATK_FastqToSam:
    run: ../../tools/GATK/GATK_FastqToSam.cwl
    in:
      fastq1: fastq1
      fastq2: fastq2
      output: { valueFrom: $(inputs.sampleID).bam }
      SM: sampleID
    out: [output_bam]
  GATK_AddOrReplaceReadGroups:
    run: ../../tools/GATK/GATK_AddOrReplaceReadGroups.cwl
    in:
      bam:
        source: GATK_FastqToSam/output_bam
      output: { valueFrom: $(inputs.sampleID).RG.bam }
      SM: sampleID
      LB: library
      PL: platform
      PU: platformUnit
    out: [output_bam]

Is there something I’m overlooking?

edit:
For what it’s worth, tetron’s original answer runs but produces undefined.bam as the value of output.

Try output: { valueFrom: $(inputs.SM).bam }