예제 #1
0
    def test_1(self):
        import janis_core as j

        class FileWithSec(j.File):
            def __init__(self, optional=False):
                super().__init__(optional=optional, extension=".txt")

            def secondary_files(self):
                return [".sec"]

        Tool = j.CommandToolBuilder(
            tool="ls",
            base_command=["ls"],
            inputs=[
                j.ToolInput("inp",
                            FileWithSec,
                            secondaries_present_as={".sec": "^.sec"})
            ],
            outputs=[
                j.ToolOutput("std", j.Stdout),
                j.ToolOutput(
                    "out",
                    FileWithSec,
                    secondaries_present_as={".sec": "^.sec"},
                    glob=j.InputSelector("inp"),
                ),
            ],
            container="ubuntu:latest",
            version="v0.1.0",
        )

        Tool.translate("wdl")
예제 #2
0
    def parse_command_tool_input(self, inp: WDL.Decl):
        default = None
        if inp.expr:
            default = self.translate_expr(inp.expr)

        # explicitly skip "runtime_*" inputs because they're from janis
        if inp.name.startswith("runtime_"):
            return None

        return j.ToolInput(inp.name,
                           self.parse_wdl_type(inp.type),
                           default=default)
예제 #3
0
 def get_inputs(self, names: List[NamedArgument]) -> List[janis.ToolInput]:
     ret = []
     for arg in names:
         assert arg.name != "", arg
         ret.append(
             janis.ToolInput(
                 tag="in_" + arg.name,
                 input_type=self.arg_to_janis_type(arg.arg),
                 position=arg.arg.position if isinstance(
                     arg.arg, Positional) else None,
                 prefix=arg.arg.longest_synonym if isinstance(
                     arg.arg, Flag) else None,
                 doc=arg.arg.description,
             ))
     return ret
예제 #4
0
    def ingest_command_tool_input(self, inp):
        inpBinding = inp.inputBinding

        if inpBinding and inpBinding.valueFrom:
            j.Logger.warn(
                f"Won't translate the expression for input {inp.id}: {inpBinding.valueFrom}"
            )

        inp_type = self.ingest_cwl_type(inp.type,
                                        secondary_files=inp.secondaryFiles)

        return j.ToolInput(
            tag=self.get_tag_from_identifier(inp.id),
            input_type=inp_type,
            position=inpBinding.position if inpBinding else None,
            prefix=inpBinding.prefix if inpBinding else None,
            separate_value_from_prefix=inpBinding.separate
            if inpBinding else None,
            separator=inpBinding.itemSeparator if inpBinding else None,
            shell_quote=inpBinding.shellQuote if inpBinding else None,
            default=inp.default,
        )
예제 #5
0
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
How to create an empty directory, using the value of an input
"""

import janis_core as j

CLT = j.CommandToolBuilder(
    tool="create_initial_stuff",
    base_command=["ls", "*"],
    version="dev",
    container="ubuntu:latest",
    inputs=[
        j.ToolInput("name_of_output_folder",
                    j.String(optional=True),
                    default="some-string")
    ],
    outputs=[j.ToolOutput("out_dir", j.Directory, selector="some-string")],
    directories_to_create=[j.InputSelector("name_of_output_folder")],
    files_to_create=[(
        j.StringFormatter("{dir}/file.txt",
                          dir=j.InputSelector("name_of_output_folder")),
        "contents of file",
    )],
)

if __name__ == "__main__":
    CLT().translate("cwl")
예제 #6
0
class MyDataTypeWithSecondaries(j.File):
    def __init__(self, optional=False):
        super().__init__(optional=optional)

    @staticmethod
    def secondary_files():
        return [".csv"]


ToolWithSecondaryFiles = j.CommandToolBuilder(
    tool="secondary_files",
    version="v0.1.0",
    container="ubuntu:latest",
    base_command="echo",
    inputs=[j.ToolInput("inp", MyDataTypeWithSecondaries, position=0)],
    outputs=[
        j.ToolOutput(
            "out",
            MyDataTypeWithSecondaries,
            selector="file.txt",
        )
    ],
)

WorkflowWithSecondaries = j.WorkflowBuilder("workflow_with_secondaries")

inner_dt = MyDataTypeWithSecondaries
scatter = None

# helper method to show how scatters / not scatters work
예제 #7
0
 def ingest_expression_tool_input(self, inp):
     inp_type = self.ingest_cwl_type(inp.type,
                                     secondary_files=inp.secondaryFiles)
     return j.ToolInput(tag=self.get_tag_from_identifier(inp.id),
                        input_type=inp_type)
예제 #8
0
 def inputs(self) -> List[j.ToolInput]:
     return [
         j.ToolInput("truthVCF", Vcf(), position=1),
         j.ToolInput("compareVCF", Vcf(), position=2),
         j.ToolInput(
             "reportPrefix",
             j.Filename(),
             prefix="--report-prefix",
             doc="(-o)  Filename prefix for report output.",
         ),
         j.ToolInput(
             "reference",
             FastaWithDict(),
             prefix="--reference",
             doc="(-r)  Specify a reference file.",
         ),
         j.ToolInput(
             "intervals",
             Bed(optional=True),
             prefix="--target-regions",
             doc=
             "(-T)  Restrict analysis to given (dense) regions (using -T in bcftools).",
         ),
         j.ToolInput(
             "version",
             j.Boolean(optional=True),
             prefix="--version",
             doc="(-v) Show version number and exit.",
         ),
         j.ToolInput(
             "scratchPrefix",
             j.String(optional=True),
             prefix="--scratch-prefix",
             doc="Directory for scratch files.",
         ),
         j.ToolInput(
             "keepScratch",
             j.String(optional=True),
             prefix="--keep-scratch",
             doc=
             "Filename prefix for scratch report output. Annotation format in input VCF file.",
         ),
         j.ToolInput(
             "falsePositives",
             Bed(optional=True),
             prefix="--false-positives",
             doc=
             "(-f)  False positive / confident call regions (.bed or .bed.gz). "
             "Calls outside these regions will be labelled as UNK.",
         ),
         j.ToolInput(
             "stratification",
             Tsv(optional=True),
             prefix="--stratification",
             doc=
             " Stratification file list (TSV format -- first column is region name, "
             "second column is file name).",
         ),
         j.ToolInput(
             "stratificationRegion",
             j.String(optional=True),
             prefix="--stratification-region",
             doc=
             "Add single stratification region, e.g. --stratification-region TEST:test.bed",
         ),
         j.ToolInput(
             "stratificationFixchr",
             j.String(optional=True),
             prefix="--stratification-fixchr",
             doc=" Add chr prefix to stratification files if necessary",
         ),
         j.ToolInput(
             "writeVcf",
             j.Boolean(optional=True),
             prefix="--write-vcf",
             doc="(-V) Write an annotated VCF.",
         ),
         j.ToolInput(
             "writeCounts",
             j.Boolean(optional=True),
             prefix="--write-counts",
             doc="(-X) Write advanced counts and metrics.",
         ),
         j.ToolInput(
             "noWriteCounts",
             j.Boolean(optional=True),
             prefix="--no-write-counts",
             doc="Do not write advanced counts and metrics.",
         ),
         j.ToolInput(
             "outputVtc",
             j.Boolean(optional=True),
             prefix="--output-vtc",
             doc=
             "Write VTC field in the final VCF which gives the counts each position has contributed to.",
         ),
         j.ToolInput(
             "preserveInfo",
             j.Boolean(optional=True),
             prefix="--preserve-info",
             doc=
             "When using XCMP, preserve and merge the INFO fields in truth and query. "
             "Useful for ROC computation.",
         ),
         j.ToolInput(
             "roc",
             j.String(optional=True),
             prefix="--roc",
             doc=
             "Select a feature to produce a ROC on (INFO feature, QUAL, GQX, ...).",
         ),
         j.ToolInput(
             "noRoc",
             j.Boolean(optional=True),
             prefix="--no-roc",
             doc=
             "Disable ROC computation and only output summary statistics for more concise output.",
         ),
         j.ToolInput(
             "rocRegions",
             j.String(optional=True),
             prefix="--roc-regions",
             doc=" Select a list of regions to compute ROCs in. By default, "
             "only the '*' region will produce ROC output (aggregate variant counts).",
         ),
         j.ToolInput(
             "rocFilter",
             j.String(optional=True),
             prefix="--roc-filter",
             doc=" Select a filter to ignore when making ROCs.",
         ),
         j.ToolInput(
             "rocDelta",
             j.Int(optional=True),
             prefix="--roc-delta",
             doc=" Minimum spacing between ROC QQ levels.",
         ),
         j.ToolInput(
             "ciAlpha",
             j.Int(optional=True),
             prefix="--ci-alpha",
             doc=
             "Confidence level for Jeffrey's CI for recall, precision and fraction of non-assessed calls.",
         ),
         j.ToolInput(
             "noJson",
             j.Boolean(optional=True),
             prefix="--no-json",
             doc="Disable JSON file output.",
         ),
         # j.ToolInput("location", Array(j.String(), optional=True), prefix="--location", separator=",",
         #           doc="(-l)  Comma-separated list of locations [use naming after preprocessing], "
         #               "when not specified will use whole VCF."),
         j.ToolInput(
             "passOnly",
             j.Boolean(optional=True),
             prefix="--pass-only",
             doc="Keep only PASS variants.",
         ),
         # j.ToolInput("filtersOnly", Array(j.String(), optional=True), prefix="--filters-only", separator=",",
         #           doc=" Specify a comma-separated list of filters to apply "
         #               "(by default all filters are ignored / passed on."),
         j.ToolInput(
             "restrictRegions",
             j.Boolean(optional=True),
             prefix="--restrict-regions",
             doc=
             "(-R)  Restrict analysis to given (sparse) regions (using -R in bcftools).",
         ),
         j.ToolInput(
             "leftshift",
             j.Boolean(optional=True),
             prefix="--leftshift",
             doc="(-L) Left-shift variants safely.",
         ),
         j.ToolInput(
             "noLeftshift",
             j.Boolean(optional=True),
             prefix="--no-leftshift",
             doc="Do not left-shift variants safely.",
         ),
         j.ToolInput(
             "decompose",
             j.Boolean(optional=True),
             prefix="--decompose",
             doc=
             "Decompose variants into primitives. This results in more granular counts.",
         ),
         j.ToolInput(
             "noDecompose",
             j.Boolean(optional=True),
             prefix="--no-decompose",
             doc="(-D) Do not decompose variants into primitives.",
         ),
         j.ToolInput(
             "bcftoolsNorm",
             j.Boolean(optional=True),
             prefix="--bcftools-norm",
             doc="Enable preprocessing through bcftools norm -c x -D "
             "(requires external preprocessing to be switched on).",
         ),
         j.ToolInput(
             "fixchr",
             j.Boolean(optional=True),
             prefix="--fixchr",
             doc=
             "Add chr prefix to VCF records where necessary (default: auto, attempt to match reference).",
         ),
         j.ToolInput(
             "noFixchr",
             j.Boolean(optional=True),
             prefix="--no-fixchr",
             doc=
             "Do not add chr prefix to VCF records (default: auto, attempt to match reference).",
         ),
         j.ToolInput(
             "bcf",
             j.Boolean(optional=True),
             prefix="--bcf",
             doc=
             "Use BCF internally. This is the default when the input file is in BCF format already. "
             "Using BCF can speed up temp file access, but may fail for VCF files that have broken "
             "headers or records that don't comply with the header.",
         ),
         j.ToolInput(
             "somatic",
             j.Boolean(optional=True),
             prefix="--somatic",
             doc=
             "Assume the input file is a somatic call file and squash all columns into one, "
             "putting all FORMATs into INFO + use half genotypes (see also --set-gt). "
             "This will replace all sample columns and replace them with a single one. "
             "This is used to treat Strelka somatic files Possible values for this parameter: "
             "half / hemi / het / hom / half to assign one of the following genotypes to the "
             "resulting sample: 1 | 0/1 | 1/1 | ./1. This will replace all sample columns and "
             "replace them with a single one.",
         ),
         j.ToolInput(
             "setGT",
             j.Boolean(optional=True),
             prefix="--set-gt",
             doc=
             "This is used to treat Strelka somatic files Possible values for this parameter: "
             "half / hemi / het / hom / half to assign one of the following genotypes to the resulting "
             "sample: 1 | 0/1 | 1/1 | ./1. "
             "This will replace all sample columns and replace them with a single one.",
         ),
         j.ToolInput(
             "gender",
             j.String(optional=True),
             prefix="--gender",
             doc=
             "({male,female,auto,none})  Specify gender. This determines how haploid calls on chrX "
             "get treated: for male samples, all non-ref calls (in the truthset only when "
             "running through hap.py) are given a 1/1 genotype.",
         ),
         j.ToolInput(
             "preprocessTruth",
             j.Boolean(optional=True),
             prefix="--preprocess-truth",
             doc="Preprocess truth file with same settings as query "
             "(default is to accept truth in original format).",
         ),
         j.ToolInput(
             "usefilteredTruth",
             j.Boolean(optional=True),
             prefix="--usefiltered-truth",
             doc="Use filtered variant calls in truth file "
             "(by default, only PASS calls in the truth file are used)",
         ),
         j.ToolInput(
             "preprocessingWindowSize",
             j.Boolean(optional=True),
             prefix="--preprocessing-window-size",
             doc=" Preprocessing window size (variants further apart than "
             "that size are not expected to interfere).",
         ),
         j.ToolInput(
             "adjustConfRegions",
             j.Boolean(optional=True),
             prefix="--adjust-conf-regions",
             doc=
             " Adjust confident regions to include variant locations. Note this will only include "
             "variants that are included in the CONF regions already when viewing with bcftools; "
             "this option only makes sure insertions are padded correctly in the CONF regions (to "
             "capture these, both the base before and after must be contained in the bed file).",
         ),
         j.ToolInput(
             "noAdjustConfRegions",
             j.Boolean(optional=True),
             prefix="--no-adjust-conf-regions",
             doc=" Do not adjust confident regions for insertions.",
         ),
         j.ToolInput(
             "noHaplotypeComparison",
             j.Boolean(optional=True),
             prefix="--no-haplotype-comparison",
             doc=
             "(--unhappy)  Disable haplotype comparison (only count direct GT matches as TP).",
         ),
         j.ToolInput(
             "windowSize",
             j.Int(optional=True),
             prefix="--window-size",
             doc=
             "(-w)  Minimum distance between variants such that they fall into the same superlocus.",
         ),
         j.ToolInput(
             "xcmpEnumerationThreshold",
             j.Int(optional=True),
             prefix="--xcmp-enumeration-threshold",
             doc=
             " Enumeration threshold / maximum number of sequences to enumerate per block.",
         ),
         j.ToolInput(
             "xcmpExpandHapblocks",
             j.String(optional=True),
             prefix="--xcmp-expand-hapblocks",
             doc=
             " Expand haplotype blocks by this many basepairs left and right.",
         ),
         j.ToolInput(
             "threads",
             j.Int(optional=True),
             prefix="--threads",
             default=j.CpuSelector(),
             doc="Number of threads to use. Comparison engine to use.",
         ),
         # j.ToolInput("engineVcfevalPath", j.String(optional=True), prefix="--engine-vcfeval-path",
         #           doc=" This parameter should give the path to the \"rtg\" executable. "
         #               "The default is /opt/hap.py/lib/python27/Haplo/../../../libexec/rtg- tools-install/rtg"),
         j.ToolInput(
             "engine",
             j.String(optional=True),
             prefix="--engine",
             doc=
             " {xcmp,vcfeval,scmp-somatic,scmp-distance} Comparison engine to use.",
         ),
         j.ToolInput(
             "engineVcfevalTemplate",
             j.String(optional=True),
             prefix="--engine-vcfeval-template",
             doc=
             " Vcfeval needs the reference sequence formatted in its own file format (SDF -- run rtg "
             "format -o ref.SDF ref.fa). You can specify this here to save time when running hap.py "
             "with vcfeval. If no SDF folder is specified, hap.py will create a temporary one.",
         ),
         j.ToolInput(
             "scmpDistance",
             j.Int(optional=True),
             prefix="--scmp-distance",
             doc=
             " For distance-based matching, this is the distance between variants to use.",
         ),
         j.ToolInput(
             "logfile",
             j.Filename(suffix="-log", extension=".txt"),
             prefix="--logfile",
             doc="Write logging information into file rather than to stderr",
         ),
         j.ToolInput(
             "verbose",
             j.Boolean(optional=True),
             prefix="--verbose",
             doc="Raise logging level from warning to info.",
         ),
         j.ToolInput(
             "quiet",
             j.Boolean(optional=True),
             prefix="--quiet",
             doc="Set logging level to output errors only.",
         ),
     ]
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import janis_core as j

HelloWorldTool = j.CommandToolBuilder(
    tool="HelloWorldTool",
    container=None,
    version="development",
    base_command="echo",
    inputs=[j.ToolInput("inp", j.String, position=0, default="Hello, World!")],
    outputs=[
        j.ToolOutput("out",
                     j.String,
                     selector=j.standard.ReadContents(j.Stdout()))
    ],
)

# as there is no container, you need to provide "allow_empty_containers=True" to the translate method:
HelloWorldTool.translate("wdl", allow_empty_container=True)

# OR (bash):
# $ janis translate --allow-empty-container hello wdl
예제 #10
0
However, in WDL, we have do this slightly differently:
    File? out = if length(glob("*.txt")) > 0 then glob("*.txt")[0] else None

NB: Although WDL supports optional files, some backends of Cromwell do not.
"""

import janis_core as j

ToolWithOptionalWildcardOutput = j.CommandToolBuilder(
    tool="optional_wildcard_output_tool",
    version="v0.1.0",
    container="ubuntu:latest",
    base_command=None,
    # write '1' to a file called 'out.csv'
    arguments=[j.ToolArgument("echo 1 > out.csv", shell_quote=False)],
    inputs=[j.ToolInput("inp", j.File, localise_file=True)],
    outputs=[
        j.ToolOutput("out_csv_files",
                     j.Array(j.File),
                     selector=j.WildcardSelector("*.csv")),
        # the next two are functionally equivalent
        j.ToolOutput("out_single_csv_file_1",
                     j.Array(j.File),
                     selector=j.WildcardSelector("*.csv", select_first=True)),
        j.ToolOutput("out_single_csv_file_2",
                     j.Array(j.File),
                     selector=j.WildcardSelector("*.csv")[0]),

        # OPTIONAL glob outputs
        # capture all files with *.txt pattern (but select the first if possible)
        j.ToolOutput("out_optional_glob",
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import janis_core as j

CommandLineThatBindsArrays = j.CommandToolBuilder(
    tool="CommandLineThatBindsArrays",
    container="ubuntu:latest",
    version="development",
    base_command="echo",
    inputs=[
        # NO prefix, joined by space (' ')  [DEFAULT]
        #   need a position to ensure it binds onto the command line
        j.ToolInput("array1", j.Array(j.String), position=0),
        #
        # No prefix, joined by commans (',')
        j.ToolInput("array2", j.Array(j.String), separator=",", position=1),
        #
        # Single prefix, then joined by space (' ')
        j.ToolInput("array3", j.Array(j.String), prefix="--prefix"),
        #
        # Single prefix, then joined by commas (',')
        j.ToolInput("array4",
                    j.Array(j.String),
                    prefix="--prefix",
                    separator=","),
        #
        # Prefix applies to each element
        j.ToolInput(
예제 #12
0
import janis_core as j
from janis_unix.tools import Cat

# Declare a new subclass of j.File and write a new tool to accept it


class SubFile(j.File):
    @staticmethod
    def name():
        return "SubFile"


ToolThatAcceptsSubFile = j.CommandToolBuilder(
    tool="acceptingSubFile",
    base_command="cat",
    inputs=[j.ToolInput("inp", SubFile)],
    outputs=[j.ToolOutput("out", j.Stdout(SubFile))],
    version="test",
    container="ubuntu:latest",
)

# Declare workflow we're we'll use the type alias

w = j.WorkflowBuilder("aliasing")
w.input("inp", SubFile)
w.step("stp1", Cat(file=w.inp))

# This line would cause the following critical message to be logged:
#   [CRITICAL]: Mismatch of types when joining 'stp1.out' to 'stp2.inp': stdout<File> -/→ SubFile
# w.step("stp2", ToolThatAcceptsSubFile(inp=w.stp1.out))
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
NB: Although WDL supports optional files, some backends of Cromwell do not.
"""

import janis_core as j

ToolWithOptionalOutput = j.CommandToolBuilder(
    tool="optional_output_tool",
    version="v0.1.0",
    container="ubuntu:latest",
    base_command=[],
    arguments=[j.ToolArgument("echo 1 > ", shell_quote=False)],
    inputs=[
        j.ToolInput("outputFilename",
                    j.String(optional=True),
                    default="out.csv",
                    position=1)
    ],
    outputs=[
        j.ToolOutput("out",
                     j.File(optional=True),
                     selector=j.InputSelector("outputFilename"))
    ],
)

if __name__ == "__main__":
    ToolWithOptionalOutput().translate("wdl")
예제 #14
0
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""
We'll use Janis to _try_ and collect a SINGLE file with the extension '.txt',
but one won't exist. CWL will automatically coerce the empty File[0] to File? (null).

However, in WDL, we have do this slightly differently:
    File? out = if length(glob("*.txt")) > 0 then glob("*.txt")[0] else None

NB: Although WDL supports optional files, some backends of Cromwell do not.
"""

import janis_core as j

ToolWithDynamicGlob = j.CommandToolBuilder(
    tool="tool_with_dynamic_glob",
    version="v0.1.0",
    container="ubuntu:latest",
    base_command=None,
    # write '1' to a file called 'out.csv'
    arguments=[j.ToolArgument("echo 1 > out.csv", shell_quote=False)],
    inputs=[j.ToolInput("extension", str)],
    outputs=[
        j.ToolOutput("out_csv_files", j.Array(j.File), selector=j.WildcardSelector("*" + j.InputSelector("extension"))),
    ],
)

if __name__ == "__main__":
    ToolWithDynamicGlob().translate("cwl")