美文网首页
Common Workflow Language [三]

Common Workflow Language [三]

作者: 生信师姐 | 来源:发表于2020-06-30 18:13 被阅读0次

    十一 Advanced Inputs

    如何描述哪些参数必须和不必须使用?
    学习如何使用记录来描述输入之间的关系。

    有时候一个工具几个参数必须一起使用(相互依赖) ,或者几个参数不能一起使用(排他)。 可以使用记录和类型联合将参数组合在一起来描述这两种情况。

    record.cwl

    #!/usr/bin/env cwl-runner
    
    cwlVersion: v1.0
    class: CommandLineTool
    inputs:
      dependent_parameters: ******
        type:
          type: record
          name: dependent_parameters
          fields:
            itemA:
              type: string
              inputBinding:
                prefix: -A
            itemB:
              type: string
              inputBinding:
                prefix: -B
      exclusive_parameters: ******
        type:
          - type: record
            name: itemC
            fields:
              itemC:
                type: string
                inputBinding:
                  prefix: -C
          - type: record
            name: itemD
            fields:
              itemD:
                type: string
                inputBinding:
                  prefix: -D
    outputs:
      example_out:
        type: stdout
    stdout: output.txt
    baseCommand: echo
    
    

    record-job1.yml

    dependent_parameters:
      itemA: one
    exclusive_parameters:
      itemC: three
    
    
    $ cwl-runner record.cwl record-job1.yml
    Workflow error, try again with --debug for more information:
    Invalid job input record:
    record-job1.yml:1:1: the `dependent_parameters` field is not valid because
                           missing required field `itemB`
    
    

    在第一个例子中,你不能只使用itemA而不使用itemB

    record-job2.yml

    dependent_parameters:
      itemA: one
      itemB: two
    exclusive_parameters:
      itemC: three
      itemD: four
    
    
    $ cwl-runner record.cwl record-job2.yml
    record-job2.yml:6:3: invalid field `itemD`, expected one of: 'itemC'
    [job record.cwl] /home/example$ echo \
        -A \
        one \
        -B \
        two \
        -C \
        three > /home/example/output.txt
    [job record.cwl] completed success
    {
        "example_out": {
            "location": "file:///home/example/11-records/output.txt",
            "basename": "output.txt",
            "class": "File",
            "checksum": "sha1$329fe3b598fed0dfd40f511522eaf386edb2d077",
            "size": 23,
            "path": "/home/example/output.txt"
        }
    }
    Final process status is success
    $ cat output.txt
    -A one -B two -C three
    
    

    在第二个示例中,itemCitemD是排他的,因此只有itemC被添加到命令行,itemD被忽略。

    record-job3.yml

    dependent_parameters:
      itemA: one
      itemB: two
    exclusive_parameters:
      itemD: four
    
    
    $ cwl-runner record.cwl record-job3.yml
    [job record.cwl] /home/example$ echo \
        -A \
        one \
        -B \
        two \
        -D \
        four > /home/example/output.txt
    [job record.cwl] completed success
    {
        "example_out": {
            "location": "file:///home/example/output.txt",
            "basename": "output.txt",
            "class": "File",
            "checksum": "sha1$77f572b28e441240a5e30eb14f1d300bcc13a3b4",
            "size": 22,
            "path": "/home/example/output.txt"
        }
    }
    Final process status is success
    $ cat output.txt
    -A one -B two -D four
    
    

    在第三个示例中,只提供了itemD ,因此它出现在命令行上。

    总结

    • 使用record字段将参数组在一起。
    • 同一参数中的多个record被视为排他的。

    十二 环境变量

    工具在受限制的环境中运行,并且不从父进程继承大多数环境变量。 可以使用EnvVarRequirement为工具设置环境变量。

    env.cwl

    #!/usr/bin/env cwl-runner
    
    cwlVersion: v1.0
    class: CommandLineTool
    baseCommand: env
    requirements:            ******
      EnvVarRequirement:
        envDef:
          HELLO: $(inputs.message)
    inputs:
      message: string
    outputs:
      example_out:
        type: stdout
    stdout: output.txt
    
    

    echo-job.yml

    message: Hello world!
    
    $ cwl-runner env.cwl echo-job.yml
    [job env.cwl] /home/example$ env > /home/example/output.txt
    [job env.cwl] completed success
    {
        "example_out": {
            "location": "file:///home/example/output.txt",
            "basename": "output.txt",
            "class": "File",
            "checksum": "sha1$1ca16a840b14807b2fd3323022c476b06a150e2f",
            "size": 94,
            "path": "/home/example/output.txt"
        }
    }
    Final process status is success
    $ cat output.txt
    HELLO=Hello world!
    PATH=/bin:/usr/bin:/usr/local/bin
    HOME=/home/example
    TMPDIR=/tmp/tmp63Obpk
    

    总结

    • T工具在一个受限制的环境中运行,只有一组最小的环境变量。
    • 使用EnvVarRequirement字段在工具的环境中设置环境变量。

    十三 JavaScript Expressions

    • 如果我想动态创建值,而 cwl 没有提供内置的方法,我该怎么做。

    • Learn how to insert JavaScript expressions into a CWL description.学习如何在CWL描述中插入JavaScript表达式。

    如果你需要操纵输入参数,包括InlineJavascriptRequirement,然后在任何参数引用是合法的地方,你都可以提供一个 javascript 片段,这个片段将由 CWL runner 进行评估。

    注意: javascript 表达式只能在绝对必要的时候使用。 在操作文件名、扩展名、路径等时,考虑是否可以使用内置的文件属性,如 basename、 nameroot、 nameext 等。

    expression.cwl

    #!/usr/bin/env cwl-runner
    
    cwlVersion: v1.0
    class: CommandLineTool
    baseCommand: echo
    
    requirements:
      InlineJavascriptRequirement: {}
    
    inputs: []
    outputs:
      example_out:
        type: stdout
    stdout: output.txt
    arguments:
      - prefix: -A
        valueFrom: $(1+1)
      - prefix: -B
        valueFrom: $("/foo/bar/baz".split('/').slice(-1)[0])
      - prefix: -C
        valueFrom: |
          ${
            var r = [];
            for (var i = 10; i >= 1; i--) {
              r.push(i);
            }
            return r;
          }
    
    

    因为这个工具不需要任何inputs ,我们可以用一个(几乎)空的文件运行它:

    empty.yml

    {}
    
    

    empty.yml’包含一个空 json 对象的描述。 Json 对象描述包含在大括号 {}中,因此空对象仅由一组空括号表示。

    运行expression.cwl:

    $ cwl-runner expression.cwl empty.yml
    [job expression.cwl] /home/example$ echo \
        -A \
        2 \
        -B \
        baz \
        -C \
        10 \
        9 \
        8 \
        7 \
        6 \
        5 \
        4 \
        3 \
        2 \
        1 > /home/example/output.txt
    [job expression.cwl] completed success
    {
        "example_out": {
            "location": "file:///home/example/output.txt",
            "basename": "output.txt",
            "class": "File",
            "checksum": "sha1$a739a6ff72d660d32111265e508ed2fc91f01a7c",
            "size": 36,
            "path": "/home/example/output.txt"
        }
    }
    Final process status is success
    $ cat output.txt
    -A 2 -B baz -C 10 9 8 7 6 5 4 3 2 1
    
    

    注意:需求必须以数组的形式提供,每个条目(在这种情况下,只有class: InlineJavascriptRequirement)) 通过-标记。 使用相同的语法来描述附加的命令行参数。

    Where are JavaScript expressions allowed?

    Just like parameter references, you can use JavaScript Expressions only in certain fields. These are:

    总结

    • 如果指定了使用InlineJavascriptRequirement,你可以包含 Javascript 表达式,这些表达式将被 cwl runner评估.
    • 表达式只在特定的字段中有效。
    • 表达式应该只在没有内置的 CWL 解决方案存在时使用。

    十四 Creating Files at Runtime

    Questions

    • 我是否在运行时从输入参数创建所需的输入文件?
    • 我如何调用脚本而不仅仅是一个简单的命令行?
    • 除了inputBinding,我还能如何向工具传递参数?

    Objectives

    • 学习如何在运行中动态地创建文件
    • 学习如何在 bash 脚本中使用表达式。

    有时候,需要动态地根据输入参数创建一个文件,例如一个工具,希望从文件而不是命令行参数读取输入配置,或者需要一个小型的wrapper shell 脚本。

    要生成这样的文件,我们可以使用InitialWorkDirRequirement

    createfile.cwl

    class: CommandLineTool
    cwlVersion: v1.0
    baseCommand: ["sh", "example.sh"]
    
    requirements:
      InitialWorkDirRequirement:           ******
        listing:
          - entryname: example.sh
            entry: |-
              PREFIX='Message is:'
              MSG="\${PREFIX} $(inputs.message)"
              echo \${MSG}
    
    inputs:
      message: string
    outputs:
      example_out:
        type: stdout
    stdout: output.txt
    
    

    在创建文件之前,任何表达式(比如$(inputs.message)都会被 CWL引擎展开; 这里在 inputmessage处插入value值。

    Tip

    CWL表达式独立于命令行工具调用期间后面使用的任何 shell 变量。 例如上面的 \${PREFIX}扩展为 ${PREFIX} ,由 shell 脚本而不是 cwl 引擎进行计算。

    为了测试上面的CWL工具,使用这个作业提供 input的value值message:

    echo-job.yml

    message: Hello world!
    
    

    在我们开始之前,让我们看看每一步的细节。命令 baseCommand: ["sh", "example.sh"]将执行命令sh example.sh。 这将运行我们在 shell 中创建的文件。

    InitialWorkDirRequirement需要一个listing。由于listing是一个YAML数组,我们需要在数组的每个元素的第一行上有一个-。在本例中,我们只有一个元素。entryname:可以有任何value值,但必须与baseCommand中指定的值匹配。最后一部分是entry:,后面跟着是|-,这是YAML引用语法,意味着使用的是多行字符串(没有它,我们需要在一行上编写整个脚本)。

    $ cwl-runner createfile.cwl echo-job.yml
    [job createfile.cwl] /private/tmp/docker_tmphrqxxcdl$ sh \
        example.sh > /private/tmp/docker_tmphrqxxcdl/output.txt
    Could not collect memory usage, job ended before monitoring began.
    [job createfile.cwl] completed success
    {
        "example_out": {
            "location": "file:///home/example/output.txt",
            "basename": "output.txt",
            "class": "File",
            "checksum": "sha1$9045abe4bd04dd8ccfe50c6ff61820b784b64aa7",
            "size": 25,
            "path": "/home/example/output.txt"
        }
    }
    Final process status is success
    $ cat output.txt
    Message is: Hello world!
    
    

    总结

    • 使用InitialWorkDirRequirement来指定在工具运行时需要创建的输入文件。

    十五 暂存输入文件

    问题

    • 如果工具需要将输出写入到其输入文件存储的目录,该怎么办?

    通常,输入文件位于与输出目录分开的只读目录中。如果底层工具希望将其输出文件与输入文件一起写入同一目录,则会出现问题。使用InitialWorkDirRequirement将输入文件暂存到输出目录中。在本例中,我们使用一个JavaScript表达式从其主目录路径中提取输入文件的base name。

    linkfile.cwl

    #!/usr/bin/env cwl-runner
    
    cwlVersion: v1.0
    class: CommandLineTool
    hints:
      DockerRequirement:
        dockerPull: openjdk:9.0.1-11-slim
    baseCommand: javac
    
    requirements:
      InitialWorkDirRequirement:
        listing:
          - $(inputs.src)
    
    inputs:
      src:
        type: File
        inputBinding:
          position: 1
          valueFrom: $(self.basename)
    
    outputs:
      classfile:
        type: File
        outputBinding:
          glob: "*.class"
    
    

    arguments-job.yml

    src:
      class: File
      path: Hello.java
    
    
    $ cwl-runner linkfile.cwl arguments-job.yml
    [job 139928309171664] /home/example$ docker run -i --volume=/home/example/Hello.java:/var/lib/cwl/job557617295_examples/Hello.java:ro --volume=/home/example:/var/spool/cwl:rw --volume=/tmp/tmpmNbApw:/tmp:rw --workdir=/var/spool/cwl --read-only=true --net=none --user=1001 --rm --env=TMPDIR=/tmp java:7 javac Hello.java
    Final process status is success
    {
    "classfile": {
      "size": 416,
      "location": "/home/example/Hello.class",
      "checksum": "sha1$2f7ac33c1f3aac3f1fec7b936b6562422c85b38a",
      "class": "File"
      }
    }
    
    

    总结

    • 输入文件通常保存在只读目录中。
    • 使用InitialWorkDirRequirement将输入文件暂存到工作目录中。

    相关文章

      网友评论

          本文标题:Common Workflow Language [三]

          本文链接:https://www.haomeiwen.com/subject/bmaxqktx.html