From 63946c7f0bf3aec2e14006cc4c6b32b8e61d82bc Mon Sep 17 00:00:00 2001 From: Jake Fennick Date: Thu, 21 Mar 2024 06:26:05 -1000 Subject: [PATCH] test case for python api subworkflow support --- workflows/bbbc_sub.py | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 workflows/bbbc_sub.py diff --git a/workflows/bbbc_sub.py b/workflows/bbbc_sub.py new file mode 100644 index 0000000..6b6f102 --- /dev/null +++ b/workflows/bbbc_sub.py @@ -0,0 +1,78 @@ +from pathlib import Path + +from wic import plugins +from wic.api import pythonapi +from wic.api.pythonapi import Step, Workflow + +def workflow() -> Workflow: + bbbcdownload = Step(clt_path='cwl_adapters/bbbcdownload.cwl') + # NOTE: object fields monkey patched at runtime from *.cwl file + bbbcdownload.name = 'BBBC001' + bbbcdownload.outDir = Path('bbbcdownload.outDir') + + subdirectory = Step(clt_path='../workflow-inference-compiler/cwl_adapters/subdirectory.cwl') + subdirectory.directory = bbbcdownload.outDir + subdirectory.glob_pattern = 'bbbcdownload.outDir/BBBC/BBBC001/raw/Images/human_ht29_colon_cancer_1_images/' + subdirectory.subdirectory = Path('subdirectory.subdirectory') + + filerenaming = Step(clt_path='cwl_adapters/file-renaming.cwl') + # NOTE: FilePattern {} syntax shadows python f-string {} syntax + filerenaming.filePattern = '.*_{row:c}{col:dd}f{f:dd}d{channel:d}.tif' + filerenaming.inpDir = subdirectory.subdirectory + filerenaming.outDir = Path('file-renaming.outDir') + filerenaming.outFilePattern = 'x{row:dd}_y{col:dd}_p{f:dd}_c{channel:d}.tif' + + # Trivially wrap the subdirectory step in a subworkflow. + # But notice that we are still linking the individual Steps above, + # which defeats the whole purpose of having reusable black boxes. + steps = [bbbcdownload, + Workflow([subdirectory], 'bbbc_sub_sub_py'), + filerenaming] + filename = 'bbbc_sub_py' # .yml + return Workflow(steps, filename) + + +def workflow2() -> Workflow: + bbbcdownload = Step(clt_path='cwl_adapters/bbbcdownload.cwl') + # NOTE: object fields monkey patched at runtime from *.cwl file + bbbcdownload.name = 'BBBC001' + bbbcdownload.outDir = Path('bbbcdownload.outDir') + + subdirectory = Step(clt_path='../workflow-inference-compiler/cwl_adapters/subdirectory.cwl') + subworkflow = Workflow([subdirectory], 'bbbc_sub_sub_py') # fails validation, due to + # https://workflow-inference-compiler.readthedocs.io/en/latest/dev/algorithms.html#deferred-satisfaction + + # First link all inputs within the subworkflow to the explicit inputs: tag. + # i.e. This is the API for the subworkflow. + subworkflow.steps[0].directory = subworkflow.directory + subworkflow.steps[0].glob_pattern = subworkflow.glob_pattern + subworkflow.steps[0].subdirectory = Path('subdirectory.subdirectory') + + # Then apply arguments at the call site. + # Notice how the caller does not need to know about the internal details of the subworkflow + # (For example, that the subdirectory step is index 0) + subworkflow.directory = bbbcdownload.outDir + subworkflow.glob_pattern = 'bbbcdownload.outDir/BBBC/BBBC001/raw/Images/human_ht29_colon_cancer_1_images/' + + filerenaming = Step(clt_path='cwl_adapters/file-renaming.cwl') + # NOTE: FilePattern {} syntax shadows python f-string {} syntax + filerenaming.filePattern = '.*_{row:c}{col:dd}f{f:dd}d{channel:d}.tif' + filerenaming.inpDir = subworkflow.steps[0].subdirectory # TODO: workflow outputs: tag + filerenaming.outDir = Path('file-renaming.outDir') + filerenaming.outFilePattern = 'x{row:dd}_y{col:dd}_p{f:dd}_c{channel:d}.tif' + + steps = [bbbcdownload, + subworkflow, + filerenaming] + filename = 'bbbc_sub_py' # .yml + return Workflow(steps, filename) + + +# viz = workflow() +# viz.compile() # Do NOT .run() here + +if __name__ == '__main__': + pythonapi.global_config = plugins.get_tools_cwl(str(Path().home())) # Use path fallback + + viz = workflow2() + viz.run() # .run() here, inside main