fe3442d1b07842556d1084e0f319ed1bb72e09c5
[rnaseq-cwl-training.git] / lesson5 / lesson5.md
1 # Expressions
2
3 1. Expressions on step inputs
4
5 You might have noticed that the output bam files are all named
6 `Aligned.sortedByCoord.out.bam`.  This happens because because when we
7 call STAR, it gives the output a default file name.
8
9 Now, during workflow execution, this is usually not a problem.  The
10 workflow runner is smart enough to know that these files are different
11 and keep them separate.  This can even make development easier by not
12 having to worry about assigning unique file names to every file.
13
14 However, it is a problem for humans interpreting the output.  We can
15 fix this by setting the parameter `OutFileNamePrefix` on STAR.
16
17 In `alignment.cwl`, we can use `valueFrom` on the `OutFileNamePrefix`
18 input parameter to construct the output prefix from the input
19 filename.
20
21 ```
22 requirements:
23   StepInputExpressionRequirement: {}
24 steps:
25   ...
26   STAR:
27     ...
28     in:
29       ForwardReads: fq
30       ...
31       OutFileNamePrefix: {valueFrom: "$(inputs.ForwardReads.nameroot)."}
32 ```
33
34 The code between `$(...)` is called an "expression".  It is evaluated
35 when setting up the step to run, and the expression is replaced by the
36 result to get the parameter value.
37
38 An expression can refer to other inputs to the step that are either
39 directly connected to another value, or have a default value.  Here,
40 we refer to the input parameter ForwardReads, which is our fastq input
41 file.
42
43 ForwardReads is a File object, not a plain file name, so it has some
44 fields of its own.  The file object has a number of fields that we can
45 use.  These include `basename` (the name of the file, without a
46 directory), `size` (file size, in bytes), `nameext` (the last file
47 extension) and `nameroot` (the name with `nameext` removed).  Using
48
49 Finally, our expression is embedded in a string, so after replacing
50 the expression with the value of `inputs.ForwardReads.nameroot`, it
51 adds the remainder of the string, which just is a dot `.`.  This is to
52 separate the leading part of our filename from the "Aligned.bam"
53 extension that will be added by STAR.
54
55 2. Organizing output files into Directories
56
57 This is a more advanced example.
58
59 Create `subdirs.cwl`:
60
61 ```
62 cwlVersion: v1.2
63 class: ExpressionTool
64 requirements:
65   InlineJavascriptRequirement: {}
66 inputs:
67   fq: File[]
68   bams: File[]
69   qc: File[]
70 outputs:
71   dirs: Directory[]
72 expression: |-
73   ${
74   var dirs = [];
75   for (var i = 0; i < inputs.bams.length; i++) {
76     dirs.push({
77       "class": "Directory",
78       "basename": inputs.fq[i].nameroot,
79       "listing": [inputs.bams[i], inputs.qc[i]]
80     });
81   }
82   return {"dirs": dirs};
83   }
84 ```
85
86 Then change `main.cwl`:
87
88 ```
89 steps:
90   ...
91   output-subdirs:
92     run: subdirs.cwl
93     in:
94       fq: fq
95       bams: alignment/bam_sorted_indexed
96       qc: alignment/qc_html
97     out: [dirs]
98 outputs:
99   dirs:
100     type: Directory[]
101     outputSource: output-subdirs/dirs
102   featurecounts:
103     type: File
104     outputSource: featureCounts/featurecounts
105 ```
106
107 3. Other uses for expressions
108
109 - Creating configuration files on the fly.