

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# WDL 工作流程定義詳細資訊
<a name="workflow-languages-wdl"></a>

下列主題提供有關 HealthOmics 中 WDL 工作流程定義可用的類型和指令的詳細資訊。

**Topics**
+ [WDL lenient 中的隱含類型轉換](#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 lenient 中的隱含類型轉換
<a name="workflow-wdl-type-conversion"></a>

HealthOmics 支援 input.json 檔案和工作流程定義的隱含類型轉換。若要使用隱含類型轉換，請在建立工作流程時將工作流程引擎指定為 WDL lenient。WDL lenient 旨在處理從 Cromwell 遷移的工作流程。它支援客戶 Cromwell 指令和一些不符合的邏輯。

WDL lenient 支援 WDL [有限例外](https://github.com/openwdl/wdl/blob/wdl-1.2/SPEC.md#-limited-exceptions)清單中下列項目的類型轉換：
+ 浮動至 Int，其中強制不會導致精確度損失 （例如 1.0 映射至 1)。
+ Int/Float 字串，其中強制不會導致精確度損失。
+ Map【W， X】 到 Array【Pair【Y， Z】】，如果 W 可強制 Y，X 可強制 Z。
+ Array【Pair【W， X】】 到 Map【Y， Z】，如果 W 可強制 Y，X 可強制 Z （例如 1.0 映射至 1)。

若要使用隱含類型轉換，請在建立工作流程或工作流程版本時，將工作流程引擎指定為 WDL\$1LENIENT。

在 主控台中，工作流程引擎參數名為**語言**。在 API 中，工作流程引擎參數名為**引擎**。如需詳細資訊，請參閱 [建立私有工作流程](create-private-workflow.md) 或 [建立工作流程版本](workflows-version-create.md) 。

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

HealthOmics 在 input.json 中支援完整變數。例如，如果您在工作流程 **SumWorkflow** 中宣告兩個名為 number1 和 number2 的輸入變數：

```
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" | 只要為工作流程提供的 IAM 角色具有這些物件的讀取存取權，Amazon S3 和 HealthOmics 儲存 URIs 就會匯入。不支援其他 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 | N/A | N/A | N/A | WDL Object類型已過期，Struct應該在所有情況下取代為 。 | 

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

HealthOmics 在 HealthOmics 支援的所有 WDL 版本中支援下列指令。

### 設定 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>

**returnCodes** 屬性提供指定傳回碼或一組傳回碼的機制，表示任務成功執行。WDL 引擎會遵守您在 WDL 定義**執行時間**區段中指定的傳回代碼，並相應地設定任務狀態。

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

HealthOmics 也支援名為 **continueOnReturnCode** 的別名，其功能與 **returnCodes** 相同。如果您指定這兩個屬性，HealthOmics 會使用 **returnCodes** 值。

## WDL 中的任務中繼資料
<a name="workflow-wdl-task-metadata"></a>

HealthOmics 支援 WDL 任務的下列中繼資料選項。

### 使用揮發性屬性停用任務層級快取
<a name="workflow-wdl-volatile-attribute"></a>

**揮發**性屬性可讓您停用 WDL 工作流程中特定任務的呼叫快取。當任務標示為揮發性時，即使為執行啟用快取，也會一律執行且永遠不會使用快取的結果。

將**揮發性**屬性新增至任務定義的**中繼**區段：

```
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 `CRAM``BAM`中從 轉換為 的私有工作流程定義。`CRAM` 工作流程的 `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}"
    }
}
```