Say I have a task that has different behavior depending on the setting of optional parameters. Is there a null
or undefined
value in WDL that will cause the defined
function to evaluate to false
that I can use to effectively hide some of these parameters in the workflow section rather than basically have nearly the exact same task defined twice in my WDL?
In the below example I have a preprocess step that only runs if unprocessed_file
is defined and processed_file
is undefined. Many correlations use categorical data, and may have a preprocess step to convert continuous data into categorical data via binning.
Additionally, there is result_archive
, a zip file that is passed from task to task, with all outputs added to it, until it is finally attached as an attribute to the entity the method configuration was run on.
Because opt_preprocess
is optional, the initialization of result_archive
can occur either there, or in process
, thus requiring a more flexible implementation of process
. I do this by having two optional inputs (a File
and a String
), only one of which should ever be defined.
It would be really useful if there is a way to force the input result_archive
to be undefined
in the call process as process_alt
block below, and the same for result_archive_name
in the call process
block. Then there would not be as much potential for accidentally breaking things in the Method Config, as my_workflow.process.result_archive_name
and my_workflow.process_alt.result_archive
would not be accessible to it.
I'm using conditionals in my workflow definition, and as you can see, the code would be a lot cleaner if else
statements were available rather than having to test for the opposite state.
task opt_preprocess {
File unprocessed_file
String result_archive_name
String result_archive="${result_archive_name}.zip"
command {
preprocess ${unprocessed_file} > preprocessed.dat
zip -r ${result_archive_name} . -x \
"fc-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]/*" \
lost+found/\* \
"tmp.[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]/*" \
exec.sh
}
output {
File preprocessed_file="preprocessed.dat"
File result_archive_pkg=result_archive
}
...
}
task process {
File input_file
File? result_archive
String? result_archive_name
command {
process ${input_file} > processed.dat
result_archive_name=${if defined(result_archive) then basename(result_archive) else result_archive_name}
${defined(result_archive)} && mv ${result_archive} .
zip -r $result_archive_name . -x \
"fc-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]/*" \
lost+found/\* \
"tmp.[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]/*" \
exec.sh
}
output {
File processed_file="processed.dat"
File result_archive_pkg="${if defined(result_archive) then basename(result_archive) else result_archive_name}"
}
...
}
task postprocess {
File in_file
File result_archive
String result_archive_name=basename(result_archive)
command {
postprocess ${in_file}
mv ${result_archive} .
zip -r $result_archive_name . -x \
"fc-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]/*" \
lost+found/\* \
"tmp.[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]/*" \
exec.sh
}
output {
File result_archive_pkg="${result_archive_name}"
}
...
}
workflow my_workflow {
File? preprocessed_file
File? unprocessed_file
String result_archive_name="my_workflow"
if (defined(preprocessed_file)) {
call process as process_alt {
input: input_file=preprocessed_file,
result_archive_name=result_archive_name
}
}
if (!defined(preprocessed_file) && defined(unprocessed_file)) {
call opt_preprocess {
input: unprocessed_file=unprocessed_file
}
call process {
input: input_file=opt_preprocess.preprocessed_file,
result_archive=opt_preprocess.result_archive_pkg
}
}
post_file="${if defined(process.out_file) then process.out_file else process_alt.out_file}"
result_archive="${if defined(process.result_archive_pkg) then process.result_archive_pkg else process_alt.result_archive_pkg}"
call postprocess {
input: in_file=post_file,
result_archive=result_archive
}
output {
postprocess.result_archive_pkg
}
}