-
Notifications
You must be signed in to change notification settings - Fork 594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Workflow definition & composition [RFC] #1276
Comments
Awesome! DSL 2 is excellent and this just helps clarify things further. |
@mes5k it took some time, but it's turning out awesome 😎 |
Hi, I don't know if I should submit a bug report for this but I noticed some inconsistencies with identifiers under nextflow.preview.dsl = 2
process sayHello {
output: stdout()
shell: "echo Hello world"
}
process greet {
input: val person
output: val greeting
exec:
greeting = "Hi, ${person}."
}
workflow foo {
emit: sayHello | view
}
workflow bar {
emit: foo
}
workflow greet1 {
get: data
emit: greet(data)
}
workflow greet2 {
get: data
emit: data | greet
}
workflow {
greet1(Channel.from("Alice", "Bob")) | view
greet2(Channel.from("Alice", "Bob")) | view
foo | view
}
|
Thank for trying this out! I've spotted a couple of problems in your script:
I'm copying below the working script for your convenience. nextflow.preview.dsl = 2
process sayHello {
output: stdout()
shell: "echo Hello world"
}
process greet {
input: val person
output: val greeting
exec:
greeting = "Hi, ${person}."
}
workflow foo {
emit: sayHello | view
}
workflow bar {
emit: foo.out
}
workflow greet1 {
get: data
main: greet(data)
emit: greet.out
}
workflow greet2 {
get: data
emit: data | greet
}
workflow {
greet1(Channel.from("Alice", "Bob")) | view
greet2(Channel.from("Alice", "Bob")) | view
foo | view
} |
Thanks for the script, @pditommaso. Now that I think about it, using One thing about the script you posted is that I still have to explicitly execute workflow bar {
foo() // Need this line, bar.out emits null without it
emit: foo.out
} I'm bugging you about this because I think it's a lot more succint, being able On an unrelated note, is there a particular reason why you picked workflow foo {
input: data
output: result
exec:
/* data processing steps */
} |
Sorry for the late reply. |
Could you use |
Yes, also @evanfloden was proposing this. Next edge release will use |
Hi there! I've been looking at using multiple related workflows defined in the same package using DSL2. What I'd like to be able to do is define multiple Here's a contrived example: nextflow.preview.dsl = 2
process greet {
input:
val person
output:
path "greeting_${person}.txt"
script:
"""
echo "Hi, ${person}." > "greeting_${person}.txt"
"""
}
process reply {
input:
val person1
val person2
path "in.txt"
output:
path "reply_${person1}_${person2}.txt"
script:
"""
echo "Oh hey ${person2}." | cat in.txt - > "reply_${person1}_${person2}.txt"
"""
}
workflow greet1 {
get: data
main: greet(data)
emit: greet.out
}
workflow greet2 {
get:
data1
data2
main:
greet(data1)
reply(data1, data2, greet.out)
emit: reply.out
}
workflow alternate {
main:
greet2(Channel.from("Darcy", "Paolo"), Channel.from("Alice", "Bob"))
}
workflow {
main:
greet1(Channel.from("Alice", "Bob"))
greet2(Channel.from("Alice", "Bob"), Channel.from("Darcy", "Paolo"))
publish:
greet1.out to: "results"
greet2.out to: "results"
} Running What do you imagine would be the best way to do this in dsl2? Thanks Darcy. PS. Really loving DSL2 so far. |
That's expected. The idea of sub-workflow is to make them composable and therefore not bound to any result path. You should create a separate script with its own main workflow and include modularised sub-workflow. |
Workflow components
This feature adds the support for workflow component definition. It allows the definition of a sequence of processes (and other workflows) as a reusable and composable component with its own inputs and outputs.
Workflow definition
The
workflow
keyword allows the definition of sub-workflow components that enclose theinvocation of one or more processes, operators and other workflows. For example:
Once defined it can be invoked from another (sub)workflow component definition as any other function or process.
Workflow parameters
A workflow component can access any variable and parameter defined in the outer scope:
Workflow inputs
A workflow component can declare one or more input channels using the
get
keyword. For example:WARN: When the
get
is used the beginning of the workflow body needs to be identified with themain
keyword.Then, the input can be specified a argument on the workflow invocation statement:
NOTE: Workflow inputs are by definition channel data structure. If a basic data type is provided instead, ie. number, string, list, etc. it's implicitly converted to a channel value (ie. non-consumable).
Workflow outputs
A workflow component can declare one or more out channels using the
emit
keyword. For example:Then, the result of the
my_pipeline
execution can be accessed using theout
property ie.my_pipeline.out
. When is declared more than one output channels, use the array bracket notation to access each output component as described for theprocess
.Alternatively, the output channel can be accessed using the identifier name to which it's assigned in the
emit
declaration:Then, the result of the above snippet can be accessed using the
my_pipeline.out.my_data
.Implicit workflow
A workflow definition which does not define any name is assumed to be the main workflow and it's implicitly executed. Therefore it's the entry point of the workflow application.
Example
An example script is available at this link and here.
Request for comments
This feature is available as experimental in the latest snapshot
19.08.0-SNAPSHOT build 5148
.Any feedback and comment are welcome.
The text was updated successfully, but these errors were encountered: