

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# WDL 工作流程定义细节
<a name="workflow-languages-wdl"></a>

以下主题提供了有关可用于 WDL 工作流定义的类型和指令的 HealthOmics详细信息。

**Topics**
+ [宽松的 WDL 中的隐式类型转换](#workflow-wdl-type-conversion)
+ [input.json 中的命名空间定义](#workflow-wdl-namespace-defn)
+ [WDL 中的原始类型](#workflow-wdl-primitive-types)
+ [WDL 中的复杂类型](#workflow-wdl-complex-types)
+ [WDL 中的指令](#workflow-wdl-directives)
+ [WDL 中的任务元数据](#workflow-wdl-task-metadata)
+ [WDL 工作流程定义示例](#wdl-example)

## 宽松的 WDL 中的隐式类型转换
<a name="workflow-wdl-type-conversion"></a>

HealthOmics 支持 input.json 文件和工作流程定义中的隐式类型转换。要使用隐式类型转换，请在创建工作流时将工作流引擎指定为 WDL 宽松。WDL lenient 旨在处理从 Cromwell 迁移的工作流程。它支持客户的 Cromwell 指令和一些不合规的逻辑。

[WDL lenient 支持 WDL 有限例外列表中以下项目的类型转换：](https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-limited-exceptions)
+ Float 到 Int，其中强制转换不会导致精度损失（例如 1.0 映射到 1）。
+ 字符串到 Int/Float，其中强制转换不会导致精度损失。
+ 将 [W, X] 映射到数组 [Pair [Y, Z]]，如果 W 可以强制转换为 Y，X 可以强制到 Z。
+ 数组 [将 [W, X]] 与 Map [Y, Z] 配对，前提是 W 可以强制转换为 Y，X 可以强制转换为 Z（例如 1.0 映射到 1）。

要使用隐式类型转换，请在创建工作流或工作流版本时将工作流引擎指定为 WDL\$1LENIENT。

在控制台中，工作流引擎参数名为 “**语言**”。在 API 中，工作流引擎参数名为 en **g** ine。有关更多信息，请参阅 [创建私有工作流程](create-private-workflow.md)或 [创建工作流程版本](workflows-version-create.md)。

## input.json 中的命名空间定义
<a name="workflow-wdl-namespace-defn"></a>

HealthOmics 支持 input.json 中的完全限定变量。例如，如果您在工作流程中声明了两个名为 number1 和 number2 的输入变量：**SumWorkflow**

```
workflow SumWorkflow {
  input {
    Int number1
    Int number2
  }
}
```

 你可以在 input.json 中将它们用作完全限定变量：

```
{
    "SumWorkflow.number1": 15,
    "SumWorkflow.number2": 27
}
```

## WDL 中的原始类型
<a name="workflow-wdl-primitive-types"></a>

下表显示了 WDL 中的输入如何映射到匹配的基元类型。 HealthOmics 对类型强制的支持有限，因此我们建议您设置显式类型。


**原始类型**  

| WDL 类型 | JSON 类型 | 示例 WDL | JSON 密钥和值示例 | 注意 | 
| --- | --- | --- | --- | --- | 
| Boolean | boolean | Boolean b | "b": true | 该值必须为小写且不带引号。 | 
| Int | integer | Int i | "i": 7 | 必须不加引号。 | 
| Float | number | Float f | "f": 42.2 | 必须不加引号。 | 
| String | string | String s | "s": "characters" | 作为 URI 的 JSON 字符串必须映射到要导入的 WDL 文件。 | 
| File | string | File f | "f": "s3://amzn-s3-demo-bucket1/path/to/file" | 只要为工作流程提供 URIs 的 IAM 角色具有对这些对象的读取权限，就会导入 Amazon S3 和 HealthOmics 存储。不支持其他 URI 方案（例如file://https://、和ftp://）。URI 必须指定一个对象。它不能是目录，这意味着它不能以结尾/。 | 
| Directory | string | Directory d | "d": "s3://bucket/path/" | 该Directory类型不包含在 WDL 1.0 或 1.1 中，因此您需要将该类型添加version development到 WDL 文件的标题中。URI 必须是 Amazon S3 URI，且前缀必须以 “/” 结尾。该目录的所有内容将以递归方式复制到工作流程中，一次下载即可。Directory应仅包含与工作流程相关的文件。 | 

## WDL 中的复杂类型
<a name="workflow-wdl-complex-types"></a>

下表显示了 WDL 中的输入如何映射到匹配的复杂 JSON 类型。WDL 中的复杂类型是由原始类型组成的数据结构。诸如列表之类的数据结构将转换为数组。


**复杂类型**  

| WDL 类型 | JSON 类型 | 示例 WDL | JSON 密钥和值示例 | 注意 | 
| --- | --- | --- | --- | --- | 
| Array | array | Array[Int] nums | “nums": [1, 2, 3] | 数组的成员必须遵循 WDL 数组类型的格式。 | 
| Pair | object | Pair[String, Int] str\$1to\$1i | “str\$1to\$1i": \$1"left": "0", "right": 1\$1 | 该对的每个值都必须使用其匹配的 WDL 类型的 JSON 格式。 | 
| Map | object | Map[Int, String] int\$1to\$1string | "int\$1to\$1string": \$1 2: "hello", 1: "goodbye" \$1 | 地图中的每个条目都必须使用其匹配的 WDL 类型的 JSON 格式。 | 
| Struct | object | <pre>struct SampleBamAndIndex { <br />  String sample_name <br />  File bam <br />  File bam_index <br />} SampleBamAndIndex b_and_i</pre>  |  <pre>"b_and_i": { <br />   "sample_name": "NA12878", <br />   "bam": "s3://amzn-s3-demo-bucket1/NA12878.bam", <br />   "bam_index": "s3://amzn-s3-demo-bucket1/NA12878.bam.bai" <br />}           </pre>  | 结构成员的名称必须与 JSON 对象键的名称完全匹配。每个值都必须使用匹配的 WDL 类型的 JSON 格式。 | 
| Object | 不适用 | 不适用 | 不适用 | WDL Object 类型已过时，Struct在所有情况下都应替换为。 | 

## WDL 中的指令
<a name="workflow-wdl-directives"></a>

HealthOmics 在所有支持的 WDL 版本中都 HealthOmics 支持以下指令。

### 配置 GPU 资源
<a name="workflow-wdl-directive-gpu"></a>

HealthOmics 支持运行时属**acceleratorType**性和**acceleratorCount**所有支持的 [GPU 实例](https://docs.aws.amazon.com/omics/latest/dev/task-accelerators.html)。 HealthOmics 还支持名为**gpuType**和的别名**gpuCount**，这些别名与加速器对应的别名具有相同的功能。如果 WDL 定义包含这两个指令，则 HealthOmics 使用加速器值。

以下示例说明如何使用这些指令：

```
runtime {
    gpuCount: 2
    gpuType: "nvidia-tesla-t4"
}
```

### 为服务错误配置任务重试
<a name="workflow-wdl-task-retry"></a>

HealthOmics 对于因服务错误而失败的任务（5XX HTTP 状态代码），最多支持两次重试。您可以配置最大重试次数（1 或 2），也可以针对服务错误选择不重试。默认情况下，最多 HealthOmics 尝试两次重试。

以下示例设置`preemptible`为因服务错误而选择不重试：

```
{
  preemptible: 0 
}
```

有关中任务重试次数的更多信息 HealthOmics，请参阅[任务重试次数](monitoring-runs.md#run-status-task-retries)。

### 为内存不足配置任务重试
<a name="workflow-wdl-retries"></a>

HealthOmics 支持重试因内存不足而失败的任务（容器退出代码 137，4XX HTTP 状态码）。 HealthOmics 将每次重试尝试的内存量增加一倍。

默认情况下，对于此类失败， HealthOmics 不会重试。使用该`maxRetries`指令指定最大重试次数。

以下示例设置`maxRetries`为 3，因此最多 HealthOmics 尝试四次尝试完成任务（初次尝试加上三次重试）：

```
runtime {
    maxRetries: 3
}
```

**注意**  
内存不足时重试任务需要 GNU findutils 4.2.3\$1。默认 HealthOmics 图像容器包含此包。如果您在 WDL 定义中指定了自定义映像，请确保该图像包含 GNU findutils 4.2.3\$1。

### 配置返回码
<a name="workflow-wdl-directive-returnCodes"></a>

R **eturnCodes** 属性提供了一种机制，用于指定表示任务成功执行的返回码或一组返回码。WDL 引擎使用您在 WDL 定义的**运行时**部分中指定的返回码，并相应地设置任务状态。

```
runtime {
    returnCodes: 1
}
```

HealthOmics 还支持名为 C **continueOnReturnode** 的别名，该别名与 **ReturnC** odes 具有相同的功能。如果您同时指定了这两个属性，则 HealthOmics 使用 **returnCodes 值**。

## WDL 中的任务元数据
<a name="workflow-wdl-task-metadata"></a>

HealthOmics 支持 WDL 任务的以下元数据选项。

### 使用 volatile 属性禁用任务级缓存
<a name="workflow-wdl-volatile-attribute"></a>

v **olatil** e 属性允许您禁用 WDL 工作流程中特定任务的呼叫缓存。当任务被标记为 volatile 时，即使为运行启用了缓存，它也将始终执行并且永远不会使用缓存的结果。

将 v **olatil** e 属性添加到任务定义的**元数据**部分：

```
task my_volatile_task {
    meta {
        volatile: true
    }
    
    input {
        String input_file
    }
    
    command {
        echo "Processing ${input_file}" > output.txt
    }
    
    output {
        File result = "output.txt"
    }
}
```

## WDL 工作流程定义示例
<a name="wdl-example"></a>

以下示例显示了在 WDL `BAM` 中从`CRAM`转换为的私有工作流程定义。t `CRAM` o `BAM` 工作流定义了两个任务并使用`genomes-in-the-cloud`容器中的工具，该工具如示例所示，并且已公开发布。

以下示例说明如何将 Amazon ECR 容器作为参数包括在内。这 HealthOmics 允许在容器开始运行之前验证其访问权限。

```
{
   ...
   "gotc_docker":"<account_id>.dkr.ecr.<region>.amazonaws.com/genomes-in-the-cloud:2.4.7-1603303710"
}
```

以下示例说明当文件位于 Amazon S3 存储桶中时，如何指定要在运行中使用哪些文件。

```
{
    "input_cram": "s3://amzn-s3-demo-bucket1/inputs/NA12878.cram",
    "ref_dict": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.dict",
    "ref_fasta": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.fasta",
    "ref_fasta_index": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.fasta.fai",
    "sample_name": "NA12878"
}
```

如果要指定序列存储中的文件，请使用序列存储的 URI 进行指示，如以下示例所示。

```
{
    "input_cram": "omics://429915189008.storage.us-west-2.amazonaws.com/111122223333/readSet/4500843795/source1",
    "ref_dict": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.dict",
    "ref_fasta": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.fasta",
    "ref_fasta_index": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.fasta.fai",
    "sample_name": "NA12878"
}
```

然后，您可以在 WDL 中定义您的工作流程，如以下示例所示。

```
 version 1.0
workflow CramToBamFlow {
    input {
        File ref_fasta
        File ref_fasta_index
        File ref_dict
        File input_cram
        String sample_name
        String gotc_docker = "<account>.dkr.ecr.us-west-2.amazonaws.com/genomes-in-the-
cloud:latest"
    }
    #Converts CRAM to SAM to BAM and makes BAI.
    call CramToBamTask{
         input:
            ref_fasta = ref_fasta,
            ref_fasta_index = ref_fasta_index,
            ref_dict = ref_dict,
            input_cram = input_cram,
            sample_name = sample_name,
            docker_image = gotc_docker,
     }
     #Validates Bam.
     call ValidateSamFile{
        input:
           input_bam = CramToBamTask.outputBam,
           docker_image = gotc_docker,
     }
     #Outputs Bam, Bai, and validation report to the FireCloud data model.
     output {
         File outputBam = CramToBamTask.outputBam
         File outputBai = CramToBamTask.outputBai
         File validation_report = ValidateSamFile.report
      }
}
#Task definitions.
task CramToBamTask {
    input {
       # Command parameters
       File ref_fasta
       File ref_fasta_index
       File ref_dict
       File input_cram
       String sample_name
       # Runtime parameters
       String docker_image
    }
   #Calls samtools view to do the conversion.
   command {
       set -eo pipefail

       samtools view -h -T ~{ref_fasta} ~{input_cram} |
       samtools view -b -o ~{sample_name}.bam -
       samtools index -b ~{sample_name}.bam
       mv ~{sample_name}.bam.bai ~{sample_name}.bai
    }
    
    #Runtime attributes:
    runtime {
        docker: docker_image
    }

    #Outputs a BAM and BAI with the same sample name
     output {
         File outputBam = "~{sample_name}.bam"
         File outputBai = "~{sample_name}.bai"
    }
}

#Validates BAM output to ensure it wasn't corrupted during the file conversion.
task ValidateSamFile {
   input {
      File input_bam
      Int machine_mem_size = 4
      String docker_image
   }
   String output_name = basename(input_bam, ".bam") + ".validation_report"
   Int command_mem_size = machine_mem_size - 1
   command {
       java -Xmx~{command_mem_size}G -jar /usr/gitc/picard.jar \
       ValidateSamFile \
       INPUT=~{input_bam} \
       OUTPUT=~{output_name} \
       MODE=SUMMARY \
       IS_BISULFITE_SEQUENCED=false
    }
    runtime {
    docker: docker_image
    }
   #A text file is generated that lists errors or warnings that apply.
    output {
        File report = "~{output_name}"
    }
}
```