{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","settings":"","results":{"codes":[]},"params":[]},"next":{"description":"","pages":[]},"title":"CWL v1.2 conditional execution","type":"basic","slug":"cwl-v12-conditional-execution","excerpt":"","body":"## Overview\n\nStarting with CWL version v1.2 workflow steps can be skipped if a specified condition is met. The condition that defines whether a step will be executed or not is set through an expression entered in the **Run Condition** setting of a step input. The **Run Condition** expression is then mapped to the [when](https://www.commonwl.org/v1.2/Workflow.html#Conditional_execution_(Optional)) CWL field in the underlying CWL code.\n\nA step that is not executed is \"skipped\" and produces null for all output parameters. Conditional step outputs are then managed using the **Pick Value Method** ([PickValueMethod](https://www.commonwl.org/v1.2/Workflow.html#PickValueMethod) in CWL) on downstream workflow step inputs or workflow outputs. To understand how the flow works, please take a look at the following workflow diagram:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/b59263f-conditionals-diagram.png\",\n        \"conditionals-diagram.png\",\n        948,\n        515,\n        \"#f2f4f3\"\n      ]\n    }\n  ]\n}\n[/block]\nYou can see that one output of _Tool A_ is connected both to _Tool B_ and _Output 2_. If we are trying to set up that, for example,_Tool B_ is executed only if a certain condition is met, an appropriate conditional expression is entered in _Tool B_'s **Run Condition** settings in the workflow editor. This results in _Tool B_ either returning some values on its outputs if it is executed, or returning null if the condition is not met and the tool is \"skipped\" during workflow execution.\n\nOne of _Tool B_'s outputs is also connected to _Output 2_ through _Link 1_, meaning that _Output 2_ will need a way to select a value to return as the result since it has two inbound data connections (_Link 1_ and _Link 2_). Therefore, _Output 2_ has **Pick Value Method** set so it could select the appropriate value from the two inbound connections. In this case, **Pick Value Method** is configured on a workflow output port, but it can also be configured on a tool input port, if we were to send the output of _Tool A_and _Tool B_ to another tool for further downstream processing instead of presenting it as a workflow output.\n\nLearn more about available [Pick Value](#section-managing-conditional-step-outputs-with-pickvalue) options and how to [implement conditionals in real scenarios](#section-implementing-conditionals-in-real-scenarios).\n\n## Setting a condition for step execution\n\nTo set a condition for step execution:\n1. Navigate to a project.\n2. On the main menu bar select **Apps**. The apps list opens.\n3. Click the name of the app you want to edit.\n4. In the top-right corner click **Edit**. The workflow editor opens.\n5. While on the **Visual Editor** tab, double-click the step in the workflow diagram that you want to edit.\n6. In the object inspector on the right, click the **Step** tab. \n7. Scroll down to the **Run Condition** section and click **Set expression**.\n8. Click **</>** to open the expression editor and enter your expression, then click **Save**.\n9. Click <save-icon> and enter an optional note describing the change.\n10. Click **Save**.\n\n## Managing conditional step outputs with pickValue\n\nWhen the condition for running a step returns false, the step is skipped and it returns null on all outputs. The downstream tools most likely don’t need that null, but want a real value. For this reason **Pick Value Method** was introduced on step inputs to help with correcting null values in a desired manner, depending on the workflow configuration.\n\nTo deal with returned null values, **Pick Value Method** uses the following methods:\n\n* `first_non_null` - Picks the first non-null value in the list of returned values. Returns an error if there isn't a non-null value.\n* `the_only_non_null` - Picks the only non-null value in the list of returned values. Returns an error if there is more than one non-nul value.\n* `all_non_null` - Picks all non-null values from the list if returned values. If all values are null, the result is an empty list.\n\nLearn more about [pickValue](https://www.commonwl.org/v1.2/Workflow.html#PickValueMethod) and [how it picks values among inbound data](https://www.commonwl.org/v1.2/Workflow.html#Picking_non-null_values_among_inbound_data_links).\n\n## Implementing conditionals in real scenarios\n\nCombinations of **Run Condition** and **Pick Value Method** allow for a lot of flexibility when specifying a workflow logic. Here we’ll show common patterns on a few real examples.\n\n### Optional step\n\nThis example will show how to create a workflow input that will serve as a switch and enable you to select whether to run or skip a tool (step) during workflow execution. To demonstrate this, we will be creating a new workflow using**BWA Mem Bundle** and the CWL 1.0 version of **Picard MarkDuplicates**.\n1. Navigate to a project.\n2. On the main menu bar select **Apps**. The apps list opens.\n3. In the top-right corner click **Add app**.\n4. Select the **Create New App** tab.\n5. Click **Create a Worfklow**.\n6. Name the workflow. Make sure that the selected CWL version is **v1.2**.\n7. Click **Create**. The workflow editor opens.\n8. In the pane on the left, select the **Public Apps** tab.\n9. Search for **BWA MEM Bundle**.\n10. Drag and drop the **BWA MEM Bundle** app to the canvas on the right.\n11. Back on the **Public Apps** tab search for **Picard MarkDuplicates** CWL 1.0.\n12. Drag and drop the app from the apps list to the canvas on the right.\n13. Click and drag the input and output nodes on both tools to create workflow inputs, outputs and tool connections as shown below:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/80acd7e-optional-step-example-1.png\",\n        \"optional-step-example-1.png\",\n        950,\n        558,\n        \"#f2f4f4\"\n      ]\n    }\n  ]\n}\n[/block]\n\n14. Double-click **Picard MarkDuplicates**. Object inspector opens.\n15. In the object inspector on the right, select the **Inputs** tab and scroll down to the bottom of the list.\n16. Click **Add new input**. A new input port named **custom_input** is created.\n17. Change the input type from **Default** to **Port**. The new input port shows up on **Picard MarkDuplicates**.\n18. Click and drag the **custom_input** input port to the left to create a new workflow input.\n19. Double-click the newly-created input port and change its **ID** to **run_mark_duplicates**. Note that this input port will still be referred to as **custom_input** when used in the code later on. Your workflow should now look like this:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/a71c172-optional-step-example-2.png\",\n        \"optional-step-example-2.png\",\n        834,\n        511,\n        \"#f2f4f4\"\n      ]\n    }\n  ]\n}\n[/block]\n20. Double-click **Picard MarkDuplicates**. Object inspector opens.\n21. In the object inspector on the right, select the **Step** tab and scroll down to the bottom of the list.\n22. In the **Run Condition** section click **Set expression**.\n23. Click **</>** to open the expression editor and enter the following expression:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"$(inputs.custom_input)\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n\n24. Click **Save**.\n25. Now double-click the **Deduped BAM** workflow output.\n26. In the object inspector on the right, scroll down to the bottom of the list.\n27. In the **Pick Value Method** dropdown, select **First non null**. This means that the value returned on this output will be the first non-null item it gets through its inbound links. So, when running this workflow, if the user selects to skip **Picard MarkDuplicates**, the output of the tool output will be null. Therefore, the first non-null item received by the **Deduped BAM** output is the file returned through the second inbound link, from **BWA MEM Bundle**.\n28. Click <i class=\"fa fa-floppy-o\" aria-hidden=\"true\"></i> and enter an optional note describing the change.\n29. Click **Save**. Your workflow is now ready to be run. This is what a draft task with configured parameters looks like:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/208dc49-optional-step-example-4.png\",\n        \"optional-step-example-4.png\",\n        1070,\n        604,\n        \"#f8f9fa\"\n      ]\n    }\n  ]\n}\n[/block]\n\nWhen using the **First non null** option for **Pick Value Method**, note that the order of inbound connections is very important as it determines which inbound data will be evaluated first. In the example above, the **Deduped BAM** output has two inbound connections, the one from **Picard MarkDuplicates** and the one from **BWA MEM Bundle**. As the logic is to use the file produced by **Picard MarkDuplicates** if it exists, or use the file produced by **BWA MEM Bundle** otherwise, **Pick Value Method** should first check the output of **Picard MarkDuplicates**. If this output is null, then the one produced by **BWA MEM Bundle** is the first non-null value, and is selected by the **Pick Value Method**.\n\nTo check the order of inbound connections, see the **Connections** section for the tool input port or workflow output port you are setting **Pick Value Method** for:\n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/c27ebb8-optional-step-example-3.png\",\n        \"optional-step-example-3.png\",\n        777,\n        561,\n        \"#f4f4f3\"\n      ]\n    }\n  ]\n}\n[/block]\nIf you need to change the order of connections, this is done directly in the CWL code, which is accessed by clicking the **Code** tab in the editor. For a workflow output, you need to change the order of items in `outputSource`, within the `outputs` section of the workflow CWL code. For a step input, you need to change the order of items in the `in.source` property of the specific workflow step.\n\n### Multiple choice\n\nThis example will deal with the situation of having multiple variant callers perform variant calling on an input file. We will add a new boolean input to each variant caller, and this input will act as a switch that allows users to enable or disable the use of the specific variant caller in the workflow. This is achieved by setting each variant caller's **Run Condition** to evaluate whether the \"switch\" input is set to true or false. Finally, outputs of each variant caller will be linked to a single input of a consensus calling app, whose **Pick Value Method** will be set up to use **all non null** inputs.\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"\",\n  \"body\": \"Note that the tools that are a part of the workflow are not actual tools, but generic placeholders for any variant calling tool. Also, the number of variant callers in the example is three, but you can use the procedure below to configure a different number (2 or more) of tools to be used, by following the setup described in the example below.\"\n}\n[/block]\n\nTo set up a multiple-choice variant calling workflow follow the steps below:\n1. Navigate to a project.\n2. On the main menu bar select **Apps**. The apps list opens.\n3. In the top-right corner click **Add app**.\n4. Select the **Create New App** tab.\n5. Click **Create a Worfklow**.\n6. Name the workflow. Make sure that the selected CWL version is **v1.2**.\n7. Click **Create**. The workflow editor opens.\n8. In the pane on the left, select the **Public Apps** tab.\n9. Search for the variant callers and consensus callers you want to add to your workflow.\n10. Drag and drop each app from the apps list to the canvas on the right.\n11. Click and drag the input and output nodes on all tools to create workflow inputs, outputs and tool connections as shown below:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/707ac24-multiple-choice-1.png\",\n        \"multiple-choice-1.png\",\n        813,\n        508,\n        \"#f0f3f3\"\n      ]\n    }\n  ]\n}\n[/block]\n\n12. Double-click one of the variant calling tools. Object inspector opens.\n13. In the object inspector on the right, select the **Inputs** tab and scroll down to the bottom of the list.\n14. Click **Add new input**. A new input port named **custom_input** is created.\n15. Change the input type from **Default** to **Port**. The new input port shows up on the tool.\n16. Click and drag the **custom_input** input port to the left to create a new workflow input.\n17. Double-click the newly-created input port and change its **ID** to e.g. **run_variant_caller_1**. Note that this input port will still be referred to as **custom_input** when used in the code later on. Your workflow should now look like this:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/8a49469-multiple-choice-2.png\",\n        \"multiple-choice-2.png\",\n        776,\n        567,\n        \"#eff2f2\"\n      ]\n    }\n  ]\n}\n[/block]\n\n18. Double-click the variant calling tool you were editing. Object inspector opens.\n19. In the object inspector on the right, select the **Step** tab and scroll down to the bottom of the list.\n20. In the **Run Condition** section click **Set expression**.\n21. Click **</>** to open the expression editor and enter the following expression:\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"$(inputs.custom_input)\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n22. Click **Save**.\n23. Repeat steps 12 to 22 for the other variant callers in the workflow.\n24. Now double-click the consensus calling tool.\n25. In the object inspector on the right, scroll down to the bottom of the list.\n26. In the **Pick Value Method** dropdown, select **All non null**. This means that the values used by this tool will be all non-null items it gets through its inbound links.\n27. In the object inspector select the **Step** tab.\n28. In the **Run Condition** section click **Set expression**.\n29. Click **</>** to open the expression editor and enter the following expression, making sure to replace `in_file` with the name of the input where the tool receives input files from variant callers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"$(inputs.in_file.length > 0)\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\n\n30. Click **Save**.\n31. Click <save-icon> and enter an optional note describing the change.\n32. Click **Save**. Your workflow is now ready to be run.\n\n### Scattering and step conditions\n\nIf a step is [scattered](doc:about-parallelizing-tool-executions) and there is a condition set, the scatter jobs are created first and the condition is evaluated separately for each scattered job. \n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/fe943c4-scatter.png\",\n        \"scatter.png\",\n        514,\n        606,\n        \"#f1f2ef\"\n      ]\n    }\n  ]\n}\n[/block]\nFor example, scatter is set for _Tool A_, and a list of four input values, e.g. `[1,2,3,4]` is provided in _Input A_. The following Run Condition is set for _Tool A_:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"${ if (inputs.a > 3) {return true} else {return false} }\",\n      \"language\": \"javascript\"\n    }\n  ]\n}\n[/block]\nAs scatter is enabled, four instances of _Tool A_(jobs) will be run, labelled as A, B, C and D in the workflow diagram above. Each job will take one value from the list provided on _Inputs A_, replace `inputs.a` in the expression with the value and evaluate the expression. As the **Run Condition** in the expression is `inputs.a > 3`, this means that out of the four jobs that were created as the result of scattering, only the last one will return a value as it satisfies the condition of input value being greater than 3, while the others will return `null`. Therefore the final output of _Tool A_ will be `[null, null, null, 4]`. \n\nDownstream, _Tool B_ needs to be set up to work with the list of values it receives from _Tool A_, precisely from the 4 parallel jobs that resulted from enabling scattering on _Tool A_. To make sure _Tool B_ gets an actual value to work with instead of using `null` values, you need to set the **Pick Value Method** of _Tool B_ to one of the available options: **First non null**, **The only non null** or **All non null**. In this case, **First non null** and **The only non null** options will result in selecting the value `4`, while **All non null** will result in a list containing a single item - `[4]`.","updates":[],"order":999,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"609926e7fe11da00ec4e6ea2","createdAt":"2021-05-10T12:28:23.228Z","user":"5767bc73bb15f40e00a28777","category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"BRING YOUR TOOLS","slug":"rabix-overview","order":15,"from_sync":false,"reference":false,"_id":"5c41ae1c33592700190a291e","project":"55faf11ba62ba1170021a9a7","version":"55faf11ba62ba1170021a9aa","createdAt":"2019-01-18T10:44:44.495Z","__v":1},"version":{"version":"1.0","version_clean":"1.0.0","codename":"","is_stable":true,"is_beta":true,"is_hidden":false,"is_deprecated":false,"categories":["55faf11ca62ba1170021a9ab","55faf8f4d0e22017005b8272","55faf91aa62ba1170021a9b5","55faf929a8a7770d00c2c0bd","55faf932a8a7770d00c2c0bf","55faf94b17b9d00d00969f47","55faf958d0e22017005b8274","55faf95fa8a7770d00c2c0c0","55faf96917b9d00d00969f48","55faf970a8a7770d00c2c0c1","55faf98c825d5f19001fa3a6","55faf99aa62ba1170021a9b8","55faf99fa62ba1170021a9b9","55faf9aa17b9d00d00969f49","55faf9b6a8a7770d00c2c0c3","55faf9bda62ba1170021a9ba","5604570090ee490d00440551","5637e8b2fbe1c50d008cb078","5649bb624fa1460d00780add","5671974d1b6b730d008b4823","5671979d60c8e70d006c9760","568e8eef70ca1f0d0035808e","56d0a2081ecc471500f1795e","56d4a0adde40c70b00823ea3","56d96b03dd90610b00270849","56fbb83d8f21c817002af880","573c811bee2b3b2200422be1","576bc92afb62dd20001cda85","5771811e27a5c20e00030dcd","5785191af3a10c0e009b75b0","57bdf84d5d48411900cd8dc0","57ff5c5dc135231700aed806","5804caf792398f0f00e77521","58458b4fba4f1c0f009692bb","586d3c287c6b5b2300c05055","58ef66d88646742f009a0216","58f5d52d7891630f00fe4e77","59a555bccdbd85001bfb1442","5a2a81f688574d001e9934f5","5b080c8d7833b20003ddbb6f","5c222bed4bc358002f21459a","5c22412594a2a5005cc9e919","5c41ae1c33592700190a291e","5c8a525e2ba7b2003f9b153c","5cbf14d58c79c700ef2b502e","5db6f03a6e187c006f667fa4","5f894c7d3b0894006477ca01"],"_id":"55faf11ba62ba1170021a9aa","releaseDate":"2015-09-17T16:58:03.490Z","createdAt":"2015-09-17T16:58:03.490Z","project":"55faf11ba62ba1170021a9a7","__v":47},"project":"55faf11ba62ba1170021a9a7","__v":0}

CWL v1.2 conditional execution


## Overview Starting with CWL version v1.2 workflow steps can be skipped if a specified condition is met. The condition that defines whether a step will be executed or not is set through an expression entered in the **Run Condition** setting of a step input. The **Run Condition** expression is then mapped to the [when](https://www.commonwl.org/v1.2/Workflow.html#Conditional_execution_(Optional)) CWL field in the underlying CWL code. A step that is not executed is "skipped" and produces null for all output parameters. Conditional step outputs are then managed using the **Pick Value Method** ([PickValueMethod](https://www.commonwl.org/v1.2/Workflow.html#PickValueMethod) in CWL) on downstream workflow step inputs or workflow outputs. To understand how the flow works, please take a look at the following workflow diagram: [block:image] { "images": [ { "image": [ "https://files.readme.io/b59263f-conditionals-diagram.png", "conditionals-diagram.png", 948, 515, "#f2f4f3" ] } ] } [/block] You can see that one output of _Tool A_ is connected both to _Tool B_ and _Output 2_. If we are trying to set up that, for example,_Tool B_ is executed only if a certain condition is met, an appropriate conditional expression is entered in _Tool B_'s **Run Condition** settings in the workflow editor. This results in _Tool B_ either returning some values on its outputs if it is executed, or returning null if the condition is not met and the tool is "skipped" during workflow execution. One of _Tool B_'s outputs is also connected to _Output 2_ through _Link 1_, meaning that _Output 2_ will need a way to select a value to return as the result since it has two inbound data connections (_Link 1_ and _Link 2_). Therefore, _Output 2_ has **Pick Value Method** set so it could select the appropriate value from the two inbound connections. In this case, **Pick Value Method** is configured on a workflow output port, but it can also be configured on a tool input port, if we were to send the output of _Tool A_and _Tool B_ to another tool for further downstream processing instead of presenting it as a workflow output. Learn more about available [Pick Value](#section-managing-conditional-step-outputs-with-pickvalue) options and how to [implement conditionals in real scenarios](#section-implementing-conditionals-in-real-scenarios). ## Setting a condition for step execution To set a condition for step execution: 1. Navigate to a project. 2. On the main menu bar select **Apps**. The apps list opens. 3. Click the name of the app you want to edit. 4. In the top-right corner click **Edit**. The workflow editor opens. 5. While on the **Visual Editor** tab, double-click the step in the workflow diagram that you want to edit. 6. In the object inspector on the right, click the **Step** tab.  7. Scroll down to the **Run Condition** section and click **Set expression**. 8. Click **</>** to open the expression editor and enter your expression, then click **Save**. 9. Click <save-icon> and enter an optional note describing the change. 10. Click **Save**. ## Managing conditional step outputs with pickValue When the condition for running a step returns false, the step is skipped and it returns null on all outputs. The downstream tools most likely don’t need that null, but want a real value. For this reason **Pick Value Method** was introduced on step inputs to help with correcting null values in a desired manner, depending on the workflow configuration. To deal with returned null values, **Pick Value Method** uses the following methods: * `first_non_null` - Picks the first non-null value in the list of returned values. Returns an error if there isn't a non-null value. * `the_only_non_null` - Picks the only non-null value in the list of returned values. Returns an error if there is more than one non-nul value. * `all_non_null` - Picks all non-null values from the list if returned values. If all values are null, the result is an empty list. Learn more about [pickValue](https://www.commonwl.org/v1.2/Workflow.html#PickValueMethod) and [how it picks values among inbound data](https://www.commonwl.org/v1.2/Workflow.html#Picking_non-null_values_among_inbound_data_links). ## Implementing conditionals in real scenarios Combinations of **Run Condition** and **Pick Value Method** allow for a lot of flexibility when specifying a workflow logic. Here we’ll show common patterns on a few real examples. ### Optional step This example will show how to create a workflow input that will serve as a switch and enable you to select whether to run or skip a tool (step) during workflow execution. To demonstrate this, we will be creating a new workflow using**BWA Mem Bundle** and the CWL 1.0 version of **Picard MarkDuplicates**. 1. Navigate to a project. 2. On the main menu bar select **Apps**. The apps list opens. 3. In the top-right corner click **Add app**. 4. Select the **Create New App** tab. 5. Click **Create a Worfklow**. 6. Name the workflow. Make sure that the selected CWL version is **v1.2**. 7. Click **Create**. The workflow editor opens. 8. In the pane on the left, select the **Public Apps** tab. 9. Search for **BWA MEM Bundle**. 10. Drag and drop the **BWA MEM Bundle** app to the canvas on the right. 11. Back on the **Public Apps** tab search for **Picard MarkDuplicates** CWL 1.0. 12. Drag and drop the app from the apps list to the canvas on the right. 13. Click and drag the input and output nodes on both tools to create workflow inputs, outputs and tool connections as shown below: [block:image] { "images": [ { "image": [ "https://files.readme.io/80acd7e-optional-step-example-1.png", "optional-step-example-1.png", 950, 558, "#f2f4f4" ] } ] } [/block] 14. Double-click **Picard MarkDuplicates**. Object inspector opens. 15. In the object inspector on the right, select the **Inputs** tab and scroll down to the bottom of the list. 16. Click **Add new input**. A new input port named **custom_input** is created. 17. Change the input type from **Default** to **Port**. The new input port shows up on **Picard MarkDuplicates**. 18. Click and drag the **custom_input** input port to the left to create a new workflow input. 19. Double-click the newly-created input port and change its **ID** to **run_mark_duplicates**. Note that this input port will still be referred to as **custom_input** when used in the code later on. Your workflow should now look like this: [block:image] { "images": [ { "image": [ "https://files.readme.io/a71c172-optional-step-example-2.png", "optional-step-example-2.png", 834, 511, "#f2f4f4" ] } ] } [/block] 20. Double-click **Picard MarkDuplicates**. Object inspector opens. 21. In the object inspector on the right, select the **Step** tab and scroll down to the bottom of the list. 22. In the **Run Condition** section click **Set expression**. 23. Click **</>** to open the expression editor and enter the following expression: [block:code] { "codes": [ { "code": "$(inputs.custom_input)", "language": "javascript" } ] } [/block] 24. Click **Save**. 25. Now double-click the **Deduped BAM** workflow output. 26. In the object inspector on the right, scroll down to the bottom of the list. 27. In the **Pick Value Method** dropdown, select **First non null**. This means that the value returned on this output will be the first non-null item it gets through its inbound links. So, when running this workflow, if the user selects to skip **Picard MarkDuplicates**, the output of the tool output will be null. Therefore, the first non-null item received by the **Deduped BAM** output is the file returned through the second inbound link, from **BWA MEM Bundle**. 28. Click <i class="fa fa-floppy-o" aria-hidden="true"></i> and enter an optional note describing the change. 29. Click **Save**. Your workflow is now ready to be run. This is what a draft task with configured parameters looks like: [block:image] { "images": [ { "image": [ "https://files.readme.io/208dc49-optional-step-example-4.png", "optional-step-example-4.png", 1070, 604, "#f8f9fa" ] } ] } [/block] When using the **First non null** option for **Pick Value Method**, note that the order of inbound connections is very important as it determines which inbound data will be evaluated first. In the example above, the **Deduped BAM** output has two inbound connections, the one from **Picard MarkDuplicates** and the one from **BWA MEM Bundle**. As the logic is to use the file produced by **Picard MarkDuplicates** if it exists, or use the file produced by **BWA MEM Bundle** otherwise, **Pick Value Method** should first check the output of **Picard MarkDuplicates**. If this output is null, then the one produced by **BWA MEM Bundle** is the first non-null value, and is selected by the **Pick Value Method**. To check the order of inbound connections, see the **Connections** section for the tool input port or workflow output port you are setting **Pick Value Method** for: [block:image] { "images": [ { "image": [ "https://files.readme.io/c27ebb8-optional-step-example-3.png", "optional-step-example-3.png", 777, 561, "#f4f4f3" ] } ] } [/block] If you need to change the order of connections, this is done directly in the CWL code, which is accessed by clicking the **Code** tab in the editor. For a workflow output, you need to change the order of items in `outputSource`, within the `outputs` section of the workflow CWL code. For a step input, you need to change the order of items in the `in.source` property of the specific workflow step. ### Multiple choice This example will deal with the situation of having multiple variant callers perform variant calling on an input file. We will add a new boolean input to each variant caller, and this input will act as a switch that allows users to enable or disable the use of the specific variant caller in the workflow. This is achieved by setting each variant caller's **Run Condition** to evaluate whether the "switch" input is set to true or false. Finally, outputs of each variant caller will be linked to a single input of a consensus calling app, whose **Pick Value Method** will be set up to use **all non null** inputs. [block:callout] { "type": "info", "title": "", "body": "Note that the tools that are a part of the workflow are not actual tools, but generic placeholders for any variant calling tool. Also, the number of variant callers in the example is three, but you can use the procedure below to configure a different number (2 or more) of tools to be used, by following the setup described in the example below." } [/block] To set up a multiple-choice variant calling workflow follow the steps below: 1. Navigate to a project. 2. On the main menu bar select **Apps**. The apps list opens. 3. In the top-right corner click **Add app**. 4. Select the **Create New App** tab. 5. Click **Create a Worfklow**. 6. Name the workflow. Make sure that the selected CWL version is **v1.2**. 7. Click **Create**. The workflow editor opens. 8. In the pane on the left, select the **Public Apps** tab. 9. Search for the variant callers and consensus callers you want to add to your workflow. 10. Drag and drop each app from the apps list to the canvas on the right. 11. Click and drag the input and output nodes on all tools to create workflow inputs, outputs and tool connections as shown below: [block:image] { "images": [ { "image": [ "https://files.readme.io/707ac24-multiple-choice-1.png", "multiple-choice-1.png", 813, 508, "#f0f3f3" ] } ] } [/block] 12. Double-click one of the variant calling tools. Object inspector opens. 13. In the object inspector on the right, select the **Inputs** tab and scroll down to the bottom of the list. 14. Click **Add new input**. A new input port named **custom_input** is created. 15. Change the input type from **Default** to **Port**. The new input port shows up on the tool. 16. Click and drag the **custom_input** input port to the left to create a new workflow input. 17. Double-click the newly-created input port and change its **ID** to e.g. **run_variant_caller_1**. Note that this input port will still be referred to as **custom_input** when used in the code later on. Your workflow should now look like this: [block:image] { "images": [ { "image": [ "https://files.readme.io/8a49469-multiple-choice-2.png", "multiple-choice-2.png", 776, 567, "#eff2f2" ] } ] } [/block] 18. Double-click the variant calling tool you were editing. Object inspector opens. 19. In the object inspector on the right, select the **Step** tab and scroll down to the bottom of the list. 20. In the **Run Condition** section click **Set expression**. 21. Click **</>** to open the expression editor and enter the following expression: [block:code] { "codes": [ { "code": "$(inputs.custom_input)", "language": "javascript" } ] } [/block] 22. Click **Save**. 23. Repeat steps 12 to 22 for the other variant callers in the workflow. 24. Now double-click the consensus calling tool. 25. In the object inspector on the right, scroll down to the bottom of the list. 26. In the **Pick Value Method** dropdown, select **All non null**. This means that the values used by this tool will be all non-null items it gets through its inbound links. 27. In the object inspector select the **Step** tab. 28. In the **Run Condition** section click **Set expression**. 29. Click **</>** to open the expression editor and enter the following expression, making sure to replace `in_file` with the name of the input where the tool receives input files from variant callers: [block:code] { "codes": [ { "code": "$(inputs.in_file.length > 0)", "language": "javascript" } ] } [/block] 30. Click **Save**. 31. Click <save-icon> and enter an optional note describing the change. 32. Click **Save**. Your workflow is now ready to be run. ### Scattering and step conditions If a step is [scattered](doc:about-parallelizing-tool-executions) and there is a condition set, the scatter jobs are created first and the condition is evaluated separately for each scattered job.  [block:image] { "images": [ { "image": [ "https://files.readme.io/fe943c4-scatter.png", "scatter.png", 514, 606, "#f1f2ef" ] } ] } [/block] For example, scatter is set for _Tool A_, and a list of four input values, e.g. `[1,2,3,4]` is provided in _Input A_. The following Run Condition is set for _Tool A_: [block:code] { "codes": [ { "code": "${ if (inputs.a > 3) {return true} else {return false} }", "language": "javascript" } ] } [/block] As scatter is enabled, four instances of _Tool A_(jobs) will be run, labelled as A, B, C and D in the workflow diagram above. Each job will take one value from the list provided on _Inputs A_, replace `inputs.a` in the expression with the value and evaluate the expression. As the **Run Condition** in the expression is `inputs.a > 3`, this means that out of the four jobs that were created as the result of scattering, only the last one will return a value as it satisfies the condition of input value being greater than 3, while the others will return `null`. Therefore the final output of _Tool A_ will be `[null, null, null, 4]`.  Downstream, _Tool B_ needs to be set up to work with the list of values it receives from _Tool A_, precisely from the 4 parallel jobs that resulted from enabling scattering on _Tool A_. To make sure _Tool B_ gets an actual value to work with instead of using `null` values, you need to set the **Pick Value Method** of _Tool B_ to one of the available options: **First non null**, **The only non null** or **All non null**. In this case, **First non null** and **The only non null** options will result in selecting the value `4`, while **All non null** will result in a list containing a single item - `[4]`.