Repository: DiamondLightSource/httomo (language: python)

Issue:
Refactor yaml
Yaml generator modified to allow more recent yaml structure. 
Yaml templates updated.


Discussion / hints:

Fix patch:
diff --git a/httomo/data/hdf/loaders.py b/httomo/data/hdf/loaders.py
index d39c36858..0168161c5 100644
--- a/httomo/data/hdf/loaders.py
+++ b/httomo/data/hdf/loaders.py
@@ -11,6 +11,10 @@
 from httomo.utils import Colour, _parse_preview, log_once, log_rank
 
 
+__all__ = [
+    "standard_tomo",
+]
+
 @dataclass
 class LoaderData:
     data: ndarray
diff --git a/httomo/ui_layer.py b/httomo/ui_layer.py
new file mode 100644
index 000000000..a037fde50
--- /dev/null
+++ b/httomo/ui_layer.py
@@ -0,0 +1,105 @@
+import yaml
+from typing import Any, Dict, List, Protocol, TypeAlias
+from importlib import import_module, util
+import os
+import re
+
+from mpi4py import MPI
+from mpi4py.MPI import Comm
+
+from httomo.methods_database.query import MethodDatabaseRepository
+from httomo.runner.pipeline import Pipeline
+
+from httomo.runner.backend_wrapper import make_backend_wrapper
+from httomo.runner.loader import make_loader
+from httomo.runner.output_ref import OutputRef
+
+class UiLayer:
+    """A common user interface for different front-ends in httomo.
+    We currently support YAML and Python interfaces, but in future
+    different UI's can be added based on other data formats, e.g. JSON. 
+    """
+    
+    def __init__(
+        self,
+        tasks_file_path: str,
+        in_data_file_path: str,
+        comm: Comm,
+    ):   
+        
+        self.repo = MethodDatabaseRepository()
+        self.tasks_file_path = tasks_file_path
+        self.in_data_file = in_data_file_path
+        self.comm = comm
+        
+        root, ext = os.path.splitext(self.tasks_file_path)
+        if ext in ['.yaml', '.yaml'.upper()]:
+            # loading yaml file with tasks provided
+            self.PipelineStageConfig = _yaml_loader(self.tasks_file_path)[0]
+        elif ext in ['.py', '.py'.upper()]:
+            # loading python file with tasks provided
+            self.PipelineStageConfig = _python_tasks_loader(self.tasks_file_path)
+        else:
+            raise ValueError(
+                f"The extension {ext} of the file {root} with tasks is unknown."
+            )
+
+    def build_pipeline(self) -> Pipeline:
+        side_outputs_collect: list = [] # saves [task_no, id, side_outputs] for tasks with side_outputs
+        methods_list: list = []
+        for task_no, task_conf in enumerate(self.PipelineStageConfig):
+            if "loaders" in task_conf['module_path']:
+                task_conf['parameters']['in_file'] = self.in_data_file
+                # unpack params and initiate a loader
+                loader =  make_loader(
+                        self.repo,
+                        task_conf['module_path'],
+                        task_conf['method'],
+                        self.comm,
+                        **task_conf['parameters'],
+                        )
+            else:
+                if "parameters" not in task_conf:
+                    task_conf['parameters'] = {}
+                if "side_outputs" not in task_conf:
+                    task_conf['side_outputs'] = {}
+                else:
+                    side_outputs_collect.append([task_no, task_conf['id'], task_conf['side_outputs']])
+                # check if there is a reference to side_outputs to cross-link
+                for key, value in task_conf['parameters'].items():
+                    if isinstance(value, str) and value is not None:
+                        if value.find('${{') != -1:                            
+                            result_extr = re.search(r"\{([A-Za-z0-9_.]+)\}", value)
+                            internal_expression = result_extr.group(1)
+                            (ref_id, side_str, ref_arg) = internal_expression.split(".")
+                            # lets find the referred id in "side_outputs_collect"
+                            for items in side_outputs_collect:
+                                if items[1] == ref_id:
+                                    # refer to methods_list[items[0]-1]
+                                    task_conf['parameters'][key] = OutputRef(methods_list[items[0]-1], ref_arg)
+                # unpack params of a method and append to a list of methods
+                method = make_backend_wrapper(
+                    self.repo,
+                    task_conf['module_path'],
+                    task_conf['method'],
+                    self.comm,
+                    task_conf['side_outputs'],
+                    **task_conf['parameters'],
+                )
+                methods_list.append(method)
+        return Pipeline(
+            loader=loader,
+            methods=methods_list,
+        )
+
+def _yaml_loader(file_path: str) -> list:
+    with open(file_path, "r") as f:
+        tasks_list = list(yaml.load_all(f, Loader=yaml.FullLoader))
+    return tasks_list
+
+def _python_tasks_loader(file_path: str) -> list:
+    module_spec = util.spec_from_file_location("methods_to_list", file_path)
+    foo = util.module_from_spec(module_spec)
+    module_spec.loader.exec_module(foo)
+    tasks_list = list(foo.methods_to_list())
+    return tasks_list
\ No newline at end of file
diff --git a/samples/loader_configs/diad.yaml b/samples/loader_configs/diad.yaml
index c42ffd25a..25093c1b9 100644
--- a/samples/loader_configs/diad.yaml
+++ b/samples/loader_configs/diad.yaml
@@ -1,15 +1,17 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry/imaging/data
-      image_key_path: /entry/instrument/imaging/image_key
-      rotation_angles:
-        data_path: /entry/imaging_sum/gts_theta_value
-      dimension: 1
-      preview:
-        -
-        - start: 5
-          stop: 7
-        -
-      pad: 0
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/k11_diad/k11-18014.nxs
+    data_path: /entry/imaging/data
+    image_key_path: /entry/instrument/imaging/image_key
+    rotation_angles:
+      data_path: /entry/imaging_sum/gts_theta_value
+    dimension: 1
+    preview:
+      -
+      - start: 5
+        stop: 7
+      -
+    pad: 0
diff --git a/samples/loader_configs/ebic.yaml b/samples/loader_configs/ebic.yaml
index 313cc7fe8..115242004 100644
--- a/samples/loader_configs/ebic.yaml
+++ b/samples/loader_configs/ebic.yaml
@@ -1,15 +1,17 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /exchange/data
-      rotation_angles:
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: # /path/to/data_file/
+    data_path: /exchange/data
+    rotation_angles:
         data_path: /exchange/theta
-      darks:
+    darks:
         file: # /path/to/file/containing/darks
         data_path: /exchange/data_dark
-      flats:
+    flats:
         file: # /path/to/file/containing/flats
         data_path: /exchange/data_white_post
-      dimension: 1
-      preview: [null, null, null]
-      pad: 0
+    dimension: 1
+    preview: [None, None, None]
+    pad: 0
\ No newline at end of file
diff --git a/samples/loader_configs/standard_tomo.yaml b/samples/loader_configs/standard_tomo.yaml
index f5aaeca9c..82d835376 100644
--- a/samples/loader_configs/standard_tomo.yaml
+++ b/samples/loader_configs/standard_tomo.yaml
@@ -1,13 +1,17 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      preview:
-        - 
-        - start: 0
-          stop: 3
-        - 
-      pad: 0
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      - start: 0
+        stop: 3
+      -
+    pad: 0
\ No newline at end of file
diff --git a/samples/pipeline_template_examples/01_basic_cpu_pipeline_tomo_standard.py b/samples/pipeline_template_examples/01_basic_cpu_pipeline_tomo_standard.py
index 5fbdf84d3..c72c2e1a3 100644
--- a/samples/pipeline_template_examples/01_basic_cpu_pipeline_tomo_standard.py
+++ b/samples/pipeline_template_examples/01_basic_cpu_pipeline_tomo_standard.py
@@ -53,14 +53,14 @@ def build_pipeline(in_file: str, comm: MPI.Comm):
         step=0.25,
         ratio=0.5,
         drop=20,
-        output_mapping={"cor": "center_value"},
+        output_mapping={"cor": "centre_of_rotation"},
     )
     m_recon = make_backend_wrapper(
         repo,
         module_path="tomopy.recon.algorithm",
         method_name="recon",
         comm=comm,
-        center=OutputRef(m_center, "center_value"),
+        center=OutputRef(m_center, "centre_of_rotation"),
         sinogram_order=False,
         algorithm="gridrec",
         init_recon=None,
@@ -71,7 +71,7 @@ def build_pipeline(in_file: str, comm: MPI.Comm):
         method_name="save_to_images",
         comm=comm,
         subfolder_name="images",
-        axis=0,
+        axis=1,
         file_format="tif",
         bits=8,
         perc_range_min=0.0,
diff --git a/samples/pipeline_template_examples/01_basic_cpu_pipeline_tomo_standard.yaml b/samples/pipeline_template_examples/01_basic_cpu_pipeline_tomo_standard.yaml
index 3cc118b26..f80be579c 100644
--- a/samples/pipeline_template_examples/01_basic_cpu_pipeline_tomo_standard.yaml
+++ b/samples/pipeline_template_examples/01_basic_cpu_pipeline_tomo_standard.yaml
@@ -1,6 +1,8 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
+- method: standard_tomo
+  module_name: httomo.data.hdf.loaders
+  parameters:
       name: tomo
+      in_file: tests/test_data/tomo_standard.nxs
       data_path: entry1/tomo_entry/data/data
       image_key_path: entry1/tomo_entry/instrument/detector/image_key
       dimension: 1
@@ -9,42 +11,43 @@
         - 
         - 
       pad: 0
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
-      #additional parameters': AVAILABLE
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 0
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    #additional parameters: AVAILABLE
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: null
diff --git a/samples/pipeline_template_examples/02_basic_cpu_pipeline_tomo_standard.yaml b/samples/pipeline_template_examples/02_basic_cpu_pipeline_tomo_standard.yaml
index 8616f2d76..ffd36785a 100644
--- a/samples/pipeline_template_examples/02_basic_cpu_pipeline_tomo_standard.yaml
+++ b/samples/pipeline_template_examples/02_basic_cpu_pipeline_tomo_standard.yaml
@@ -1,69 +1,71 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      preview:
-        - 
-        - start: 30
-          stop: 60
-        - 
-      pad: 0
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+        data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      - start: 30
+        stop: 60
+      -
+    pad: 0
 --- # pre-normalisation / pre-processing
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
 --- # main processing
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-      averaging: mean
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
-- tomopy.prep.stripe:
-    remove_stripe_fw:
-      data_in: tomo
-      data_out: tomo
-      level: null
-      wname: db5
-      sigma: 2
-      pad: true
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
-      #additional parameters': AVAILABLE
-- tomopy.misc.corr:
-    median_filter:
-      data_in: tomo
-      data_out: tomo
-      size: 3
-      axis: 0
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 0
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    #additional parameters: AVAILABLE
+- method: median_filter
+  module_path: tomopy.misc.corr
+  parameters:
+    size: 3
+    axis: 0
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: true
\ No newline at end of file
diff --git a/samples/pipeline_template_examples/03_basic_gpu_pipeline_tomo_standard.yaml b/samples/pipeline_template_examples/03_basic_gpu_pipeline_tomo_standard.yaml
index ae7365f28..7d260ca32 100644
--- a/samples/pipeline_template_examples/03_basic_gpu_pipeline_tomo_standard.yaml
+++ b/samples/pipeline_template_examples/03_basic_gpu_pipeline_tomo_standard.yaml
@@ -1,60 +1,64 @@
 --- # Loading stage
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      preview:
-        - 
-        - 
-        - 
-      pad: 0
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      -
+      -
+    pad: 0
 --- # Pre-normalisation / pre-processing stage
-- httomolibgpu.misc.corr:
-    remove_outlier3d:
-      kernel_size: 3
-      dif: 0.1
-- httomolibgpu.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6.0
-      step: 0.25
-      ratio: 0.5
-      drop: 20
+- method: remove_outlier3d
+  module_path: tomopy.misc.corr
+  parameters:
+    dif: 0.1
+    size: 3
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
 --- # Main processing stage
-- httomolibgpu.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: 10.0
-      minus_log: true
-      nonnegativity: false
-- httomolibgpu.prep.stripe:
-    remove_stripe_based_sorting:
-      data_in: tomo
-      data_out: tomo
-      size: 11
-      dim: 1
-- httomolibgpu.recon.algorithm:
-    FBP:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      recon_size: null
-      recon_mask_radius: null
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 1
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
-      glob_stats: true
+- method: normalize
+  module_path: httomolibgpu.prep.normalize
+  parameters:
+    cutoff: 10.0
+    minus_log: true
+    nonnegativity: false
+    remove_nans: false
+- method: remove_stripe_based_sorting
+  module_path: httomolibgpu.prep.stripe
+  parameters:
+    size: 11
+    dim: 1
+- method: FBP
+  module_path: httomolibgpu.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    objsize: null
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 1
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: true
\ No newline at end of file
diff --git a/samples/pipeline_template_examples/DLS/01_diad_pipeline.yaml b/samples/pipeline_template_examples/DLS/01_diad_pipeline.yaml
index b22f9b729..e3536b90f 100644
--- a/samples/pipeline_template_examples/DLS/01_diad_pipeline.yaml
+++ b/samples/pipeline_template_examples/DLS/01_diad_pipeline.yaml
@@ -1,61 +1,63 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry/imaging/data
-      image_key_path: /entry/instrument/imaging/image_key
-      rotation_angles:
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/k11_diad/k11-18014.nxs
+    data_path: /entry/imaging/data
+    image_key_path: /entry/instrument/imaging/image_key
+    rotation_angles:
         data_path: /entry/imaging_sum/gts_theta_value
-      dimension: 1
-      preview:
-        - 
-        - start: 0
-          stop: 20
-        - 
-      pad: 0
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20      
-- tomopy.prep.stripe:
-    remove_all_stripe:
-      data_in: tomo
-      data_out: tomo
-      snr: 3
-      la_size: 61
-      sm_size: 21
-      dim: 1
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
-      #additional parameters': AVAILABLE
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 0
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
\ No newline at end of file
+    dimension: 1
+    preview:
+      -
+      - start: 0
+        stop: 20
+      -
+    pad: 0
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+- method: remove_all_stripe
+  module_path: tomopy.prep.stripe
+  parameters:
+    snr: 3
+    la_size: 61
+    sm_size: 21
+    dim: 1
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    #additional parameters': AVAILABLE
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: null
\ No newline at end of file
diff --git a/samples/pipeline_template_examples/DLS/02_i12_360scan_pipeline.yaml b/samples/pipeline_template_examples/DLS/02_i12_360scan_pipeline.yaml
index cacd60618..c2dd38a25 100644
--- a/samples/pipeline_template_examples/DLS/02_i12_360scan_pipeline.yaml
+++ b/samples/pipeline_template_examples/DLS/02_i12_360scan_pipeline.yaml
@@ -1,63 +1,70 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      preview:
-        - 
-        - start: 30
-          stop: 60
-        - 
-      pad: 0
-- httomolibgpu.misc.corr:
-    remove_outlier3d:
-      data_in_multi: [tomo, flats, darks]
-      data_out_multi: [tomo, flats, darks]
-      kernel_size: 3
-      dif: 0.1      
-- httomolibgpu.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: 10.0
-      minus_log: true
-      nonnegativity: false 
-- httomolibgpu.recon.rotation:
-    find_center_360:
-      data_in: tomo
-      data_out: [cor, overlap, side, overlap_position]
-      ind: mid
-      win_width: 10
-      side: null
-      denoise: true
-      norm: false
-      use_overlap: true
-- httomolibgpu.prep.stripe:
-    remove_stripe_based_sorting:
-      data_in: tomo
-      data_out: tomo
-      size: 11
-      dim: 1
-- httomolibgpu.misc.morph:
-    sino_360_to_180:
-      data_in: tomo
-      data_out: tomo
-      overlap: overlap
-      rotation: right 
-- httomolibgpu.recon.algorithm:
-     reconstruct_tomobar:
-       data_in: tomo
-       data_out: tomo
-       center: cor
-       objsize: null
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 0
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: # /path/to/data_file/
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+        data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      - start: 30
+        stop: 60
+      -
+    pad: 0
+- method: remove_outlier3d
+  module_path: httomolibgpu.misc.corr
+  parameters:
+    kernel_size: 3
+    dif: 0.1
+    #data_in_multi: [tomo, flats, darks]
+    #data_out_multi: [tomo, flats, darks]
+- method: normalize
+  module_path: httomolibgpu.prep.normalize
+  parameters:
+    cutoff: 10.0
+    minus_log: true
+    nonnegativity: false
+- method: find_center_360
+  module_path: httomolibgpu.recon.rotation
+  parameters:
+    ind: mid
+    win_width: 10
+    side: null
+    denoise: true
+    norm: false
+    use_overlap: true
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+    overlap: overlap
+    side: side
+    overlap_position: overlap_position
+- method: remove_stripe_based_sorting
+  module_path: httomolibgpu.prep.stripe
+  parameters:
+    size: 11
+    dim: 1
+- method: sino_360_to_180
+  module_path: httomolibgpu.misc.morph
+  parameters:
+    overlap: ${{centering.side_outputs.overlap}}
+    rotation: right
+- method: reconstruct_tomobar # method not present?
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    objsize: null
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: null
diff --git a/samples/pipeline_template_examples/DLS/03_i12_separate_darks_flats.yaml b/samples/pipeline_template_examples/DLS/03_i12_separate_darks_flats.yaml
index 1a2b43dff..49be5a6a6 100644
--- a/samples/pipeline_template_examples/DLS/03_i12_separate_darks_flats.yaml
+++ b/samples/pipeline_template_examples/DLS/03_i12_separate_darks_flats.yaml
@@ -1,18 +1,20 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /1-TempPlugin-tomo/data
-      rotation_angles:
-        user_defined:
-          start_angle: 0
-          stop_angle: 180
-          angles_total: 724
-      dimension: 1
-      preview: [null, null, null]
-      pad: 0
-      darks:
-        file: tests/test_data/i12/separate_flats_darks/dark_field.h5
-        data_path: /1-NoProcessPlugin-tomo/data
-      flats:
-        file: tests/test_data/i12/separate_flats_darks/flat_field.h5
-        data_path: /1-NoProcessPlugin-tomo/data
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/i12/separate_flats_darks/i12_dynamic_start_stop180.nxs
+    data_path: /1-TempPlugin-tomo/data
+    rotation_angles:
+      user_defined:
+        start_angle: 0
+        stop_angle: 180
+        angles_total: 724
+    dimension: 1
+    preview: [None, None, None]
+    pad: 0
+    darks:
+      file: tests/test_data/i12/separate_flats_darks/dark_field.h5
+      data_path: /1-NoProcessPlugin-tomo/data
+    flats:
+      file: tests/test_data/i12/separate_flats_darks/flat_field.h5
+      data_path: /1-NoProcessPlugin-tomo/data
diff --git a/samples/pipeline_template_examples/DLS/04_i12_ignore_darks_flats.yaml b/samples/pipeline_template_examples/DLS/04_i12_ignore_darks_flats.yaml
index bc5e6de9d..8ca2dedeb 100644
--- a/samples/pipeline_template_examples/DLS/04_i12_ignore_darks_flats.yaml
+++ b/samples/pipeline_template_examples/DLS/04_i12_ignore_darks_flats.yaml
@@ -1,24 +1,26 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /1-TempPlugin-tomo/data
-      rotation_angles:
-        user_defined:
-          start_angle: 0
-          stop_angle: 180
-          angles_total: 724
-      dimension: 1
-      preview: [null, null, null]
-      pad: 0
-      darks:
-        file: tests/test_data/i12/separate_flats_darks/dark_field.h5
-        data_path: /1-NoProcessPlugin-tomo/data
-      ignore_darks:
-        individual: [0, 5, 8, 10, 15]
-      flats:
-        file: tests/test_data/i12/separate_flats_darks/flat_field.h5
-        data_path: /1-NoProcessPlugin-tomo/data
-      ignore_flats:
-        batch:
-          - start: 0
-            stop: 5
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/i12/separate_flats_darks/i12_dynamic_start_stop180.nxs
+    data_path: /1-TempPlugin-tomo/data
+    rotation_angles:
+      user_defined:
+        start_angle: 0
+        stop_angle: 180
+        angles_total: 724
+    dimension: 1
+    preview: [None, None, None]
+    pad: 0
+    darks:
+      file: tests/test_data/i12/separate_flats_darks/dark_field.h5
+      data_path: /1-NoProcessPlugin-tomo/data
+    ignore_darks:
+      individual: [0, 5, 8, 10, 15]
+    flats:
+      file: tests/test_data/i12/separate_flats_darks/flat_field.h5
+      data_path: /1-NoProcessPlugin-tomo/data
+    ignore_flats:
+      batch:
+        - start: 0
+          stop: 5
diff --git a/samples/pipeline_template_examples/parameter_sweeps/01_recon_cor_range_sweep.yaml b/samples/pipeline_template_examples/parameter_sweeps/01_recon_cor_range_sweep.yaml
index e84805f2c..65efd95ac 100644
--- a/samples/pipeline_template_examples/parameter_sweeps/01_recon_cor_range_sweep.yaml
+++ b/samples/pipeline_template_examples/parameter_sweeps/01_recon_cor_range_sweep.yaml
@@ -1,18 +1,23 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry1/tomo_entry/data/data
-      image_key_path: /entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      pad: 0
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: !SweepRange
-        start: 10
-        stop: 50
-        step: 10
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: /entry1/tomo_entry/data/data
+    image_key_path: /entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+        data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview: [None, None, None]
+    pad: 0
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: !SweepRange
+      start: 10
+      stop: 50
+      step: 10
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    #additional parameters: AVAILABLE
diff --git a/samples/pipeline_template_examples/parameter_sweeps/02_median_filter_kernel_sweep.yaml b/samples/pipeline_template_examples/parameter_sweeps/02_median_filter_kernel_sweep.yaml
index 8e6dfe6d4..3d66ffc48 100644
--- a/samples/pipeline_template_examples/parameter_sweeps/02_median_filter_kernel_sweep.yaml
+++ b/samples/pipeline_template_examples/parameter_sweeps/02_median_filter_kernel_sweep.yaml
@@ -1,29 +1,35 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry1/tomo_entry/data/data
-      image_key_path: /entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      pad: 0
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+        data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview: [None, None, None]
+    pad: 0
 --- # pre-normalisation / pre-processing
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
 --- # main processing
-- tomopy.misc.corr:
-    median_filter:
-      data_in: tomo
-      data_out: tomo
-      size: !Sweep
-        - 3
-        - 5
-      axis: 0
+- method: median_filter
+  module_path: tomopy.misc.corr
+  parameters:
+    size: !Sweep
+      - 3
+      - 5
+    axis: 0
diff --git a/samples/pipeline_template_examples/parameter_sweeps/03_median_filter_image_saver.yaml b/samples/pipeline_template_examples/parameter_sweeps/03_median_filter_image_saver.yaml
index 186a27f79..6dca7c853 100644
--- a/samples/pipeline_template_examples/parameter_sweeps/03_median_filter_image_saver.yaml
+++ b/samples/pipeline_template_examples/parameter_sweeps/03_median_filter_image_saver.yaml
@@ -1,29 +1,33 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      preview:
-        - 
-        - 
-        - 
-      pad: 0
-- httomolib.misc.corr:
-    median_filter3d:
-      data_in: tomo
-      data_out: tomo
-      kernel_size: !Sweep
-        - 3
-        - 5
-      dif: 0.0
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 0
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      -
+      -
+    pad: 0
+- method: median_filter3d
+  module_path: tomopy.misc.corr
+  parameters:
+    size: !Sweep
+      - 3
+      - 5
+    # dif: 0.0 should this be replaced?
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: null
diff --git a/samples/pipeline_template_examples/parameter_sweeps/04_phase_retrieve_image_saver.yaml b/samples/pipeline_template_examples/parameter_sweeps/04_phase_retrieve_image_saver.yaml
index 3741160d5..19952dddf 100644
--- a/samples/pipeline_template_examples/parameter_sweeps/04_phase_retrieve_image_saver.yaml
+++ b/samples/pipeline_template_examples/parameter_sweeps/04_phase_retrieve_image_saver.yaml
@@ -1,63 +1,67 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry1/tomo_entry/data/data
-      image_key_path: /entry1/tomo_entry/instrument/detector/image_key
-      preview:
-        - 
-        - start: 30
-          stop: 60
-        -      
-      dimension: 1
-      pad: 0
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
-- tomopy.prep.phase:
-   retrieve_phase:
-     data_in: tomo
-     data_out: tomo
-     pixel_size: 0.0001
-     dist: 50
-     energy: 20
-     alpha: !SweepRange
-        start: 0.001
-        stop: 0.01
-        step: 0.001
-     pad: true
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20      
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
-      #additional parameters': AVAILABLE
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 0
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
\ No newline at end of file
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      - start: 30
+        stop: 60
+      -
+    pad: 0
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
+- method: retrieve_phase
+  module_path: tomopy.prep.phase
+  parameters:
+    pixel_size: 0.0001
+    dist: 50
+    energy: 20
+    alpha: !SweepRange
+      start: 0.001
+      stop: 0.01
+      step: 0.001
+    pad: true
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    #additional parameters: AVAILABLE
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: null
diff --git a/samples/pipeline_template_examples/pipeline_cpu1.yaml b/samples/pipeline_template_examples/pipeline_cpu1.yaml
new file mode 100644
index 000000000..22aa3a295
--- /dev/null
+++ b/samples/pipeline_template_examples/pipeline_cpu1.yaml
@@ -0,0 +1,53 @@
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters: 
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      - 
+      - 
+      - 
+    pad: 0
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: null
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor : centre_of_rotation
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: 'gridrec'
+    init_recon: null
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 1
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
diff --git a/samples/pipeline_template_examples/pipeline_cpu2.yaml b/samples/pipeline_template_examples/pipeline_cpu2.yaml
new file mode 100644
index 000000000..973e2e4e2
--- /dev/null
+++ b/samples/pipeline_template_examples/pipeline_cpu2.yaml
@@ -0,0 +1,75 @@
+--- # loading
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+        data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      - start: 30
+        stop: 60
+      -
+    pad: 0
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+- method: remove_outlier
+  module_path: tomopy.misc.corr
+  parameters:
+    dif: 0.1
+    size: 3
+    axis: 0
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    #additional parameters: AVAILABLE
+- method: median_filter
+  module_path: tomopy.misc.corr
+  parameters:
+    size: 3
+    axis: 0
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: true
\ No newline at end of file
diff --git a/samples/pipeline_template_examples/pipeline_gpu1.yaml b/samples/pipeline_template_examples/pipeline_gpu1.yaml
new file mode 100644
index 000000000..6ba65edbc
--- /dev/null
+++ b/samples/pipeline_template_examples/pipeline_gpu1.yaml
@@ -0,0 +1,62 @@
+--- # Loading stage
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      -
+      -
+    pad: 0
+- method: find_center_vo
+  module_path: httomolibgpu.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+- method: remove_outlier3d
+  module_path: httomolibgpu.misc.corr
+  parameters:
+    dif: 0.1
+    kernel_size: 3
+- method: normalize
+  module_path: httomolibgpu.prep.normalize
+  parameters:
+    cutoff: 10.0
+    minus_log: true
+    nonnegativity: false
+    remove_nans: false
+- method: remove_stripe_based_sorting
+  module_path: httomolibgpu.prep.stripe
+  parameters:
+    size: 11
+    dim: 1
+- method: FBP
+  module_path: httomolibgpu.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    recon_size: null
+    recon_mask_radius: null
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 1
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
\ No newline at end of file
diff --git a/samples/python_templates/__init__.py b/samples/python_templates/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/python_templates/pipeline_cpu1.py b/samples/python_templates/pipeline_cpu1.py
new file mode 100644
index 000000000..b1b2c44f3
--- /dev/null
+++ b/samples/python_templates/pipeline_cpu1.py
@@ -0,0 +1,91 @@
+from typing import Any, Dict, List, TypeAlias
+
+MethodConfig: TypeAlias = Dict[str, Dict[str, Any]]
+PipelineStageConfig: TypeAlias = List[MethodConfig]
+PipelineConfig: TypeAlias = List[PipelineStageConfig]
+
+# NOTE: when creating a Pythonic pipeline, please use
+# the function's name "methods_to_list" so it will be 
+# found by the loader
+
+def methods_to_list() -> PipelineConfig:
+    """Pythonic way to build a list of tasks
+    from which Pipeline can be generated in Httomo.
+    This accompaniments the YAML interface.
+
+    Returns:
+        PipelineConfig: A list of tasks in "full_pipeline_list" that can be executed in Httomo.
+    """
+    full_pipeline_list = []
+    loader = {
+        'method': "standard_tomo",
+        'module_path': "httomo.data.hdf.loaders",
+        'parameters' : {
+                     'name': 'tomo',
+                     'data_path': 'entry1/tomo_entry/data/data',
+                     'image_key_path': 'entry1/tomo_entry/instrument/detector/image_key',
+                     'rotation_angles': {"data_path": "/entry1/tomo_entry/data/rotation_angle"},
+                     'dimension': 1,
+                     'preview': [dict(), dict(), dict()],
+                     'pad': 0,
+                       },
+                    }
+    full_pipeline_list.append(loader)
+    method1 = {
+        'method': "normalize",
+        'module_path': "tomopy.prep.normalize",
+        'parameters' : {
+                     'cutoff': None,
+                       },
+                    }
+    full_pipeline_list.append(method1)
+    method2 = {
+        'method': "minus_log",
+        'module_path': "tomopy.prep.normalize",
+        'parameters' : {},
+                    }
+    full_pipeline_list.append(method2)
+    method3 = {
+        'method': "find_center_vo",
+        'module_path': "tomopy.recon.rotation",
+        'id': "centering",
+        'parameters' : {
+                     'ind': "mid",
+                     'smin': -50,
+                     'smax': 50,
+                     'srad': 6,
+                     'step': 0.25,
+                     'ratio': 0.5,
+                     'drop': 20,
+                       },
+        'side_outputs': {"cor": "centre_of_rotation"},
+                    }
+    full_pipeline_list.append(method3)
+    method4 = {
+        'method': "recon",
+        'module_path': "tomopy.recon.algorithm",
+        'parameters' : {
+                     'center': "${{centering.side_outputs.centre_of_rotation}}",
+                     'sinogram_order': False,
+                     'algorithm': "gridrec",
+                     'init_recon': None,
+                       },
+                    }
+    full_pipeline_list.append(method4)
+    method5 = {
+        'method': "save_to_images",
+        'module_path': "httomolib.misc.images",
+        'parameters' : {
+                     'subfolder_name': "images",
+                     'axis': 1,
+                     'file_format': "tif",
+                     'bits': 8,
+                     'perc_range_min': 0.0,
+                     'perc_range_max': 100.0,
+                     'jpeg_quality': 95,
+                       },
+                    }
+    full_pipeline_list.append(method5)
+
+    return full_pipeline_list
+    
\ No newline at end of file
diff --git a/samples/python_templates/pipeline_cpu2.py b/samples/python_templates/pipeline_cpu2.py
new file mode 100644
index 000000000..b1e1a884d
--- /dev/null
+++ b/samples/python_templates/pipeline_cpu2.py
@@ -0,0 +1,121 @@
+from typing import Any, Dict, List, TypeAlias
+
+MethodConfig: TypeAlias = Dict[str, Dict[str, Any]]
+PipelineStageConfig: TypeAlias = List[MethodConfig]
+PipelineConfig: TypeAlias = List[PipelineStageConfig]
+
+# NOTE: when creating a Pythonic pipeline, please use
+# the function's name "methods_to_list" so it will be 
+# found by the loader
+
+def methods_to_list() -> PipelineConfig:
+    """Pythonic way to build a list of tasks
+    from which Pipeline can be generated in Httomo.
+    This accompaniments the YAML interface.
+
+    Returns:
+        PipelineConfig: A list of tasks in "full_pipeline_list" that can be executed in Httomo.
+    """
+    full_pipeline_list = []
+    loader = {
+        'method': "standard_tomo",
+        'module_path': "httomo.data.hdf.loaders",
+        'parameters' : {
+                     'name': 'tomo',
+                     'data_path': 'entry1/tomo_entry/data/data',
+                     'image_key_path': 'entry1/tomo_entry/instrument/detector/image_key',
+                     'rotation_angles': {"data_path": "/entry1/tomo_entry/data/rotation_angle"},
+                     'dimension': 1,
+                     'preview': [None, {'start': 30, 'stop': 60}, None],
+                     'pad': 0,
+                       },
+                    }
+    full_pipeline_list.append(loader)
+    method1 = {
+        'method': "find_center_vo",
+        'module_path': "tomopy.recon.rotation",
+        'id': "centering",
+        'parameters' : {
+                     'ind': "mid",
+                     'smin': -50,
+                     'smax': 50,
+                     'srad': 6,
+                     'step': 0.25,
+                     'ratio': 0.5,
+                     'drop': 20,
+                       },
+        'side_outputs': {"cor": "centre_of_rotation"},
+                    }
+    full_pipeline_list.append(method1)
+    method2 = {
+        'method': "remove_outlier",
+        'module_path': "tomopy.misc.corr",
+        'parameters' : {
+                        'dif': 0.1,
+                        'size': 3,
+                        'axis': 0,
+                       },
+                    }
+    full_pipeline_list.append(method2)    
+    method3 = {
+        'method': "normalize",
+        'module_path': "tomopy.prep.normalize",
+        'parameters' : {
+                     'cutoff': None,
+                       },
+                    }
+    full_pipeline_list.append(method3)
+    method4 = {
+        'method': "minus_log",
+        'module_path': "tomopy.prep.normalize",
+        'parameters' : {},
+                    }
+    full_pipeline_list.append(method4)
+    method5 = {
+        'method': "remove_stripe_fw",
+        'module_path': "tomopy.prep.stripe",
+        'parameters' : {
+                     'level': None,
+                     'wname': "db5",
+                     'sigma': 2,
+                     'pad': True,
+                       },
+                    }
+    full_pipeline_list.append(method5)
+    method6 = {
+        'method': "recon",
+        'module_path': "tomopy.recon.algorithm",
+        'parameters' : {
+                     'center': "${{centering.side_outputs.centre_of_rotation}}",
+                     'sinogram_order': False,
+                     'algorithm': "gridrec",
+                     'init_recon': None,
+                       },
+                    }
+    full_pipeline_list.append(method6)
+    method7 = {
+        'method': "median_filter",
+        'module_path': "tomopy.misc.corr",
+        'parameters' : {
+                        'size': 3,
+                        'axis': 0,
+                       },
+                    }
+    full_pipeline_list.append(method7)
+    method8 = {
+        'method': "save_to_images",
+        'module_path': "httomolib.misc.images",
+        'parameters' : {
+                     'subfolder_name': "images",
+                     'axis': 1,
+                     'file_format': "tif",
+                     'bits': 8,
+                     'perc_range_min': 0.0,
+                     'perc_range_max': 100.0,
+                     'jpeg_quality': 95,
+                       },
+                    }
+    full_pipeline_list.append(method8)
+
+    return full_pipeline_list
+    
\ No newline at end of file
diff --git a/samples/python_templates/pipeline_gpu1.py b/samples/python_templates/pipeline_gpu1.py
new file mode 100644
index 000000000..9c1de016c
--- /dev/null
+++ b/samples/python_templates/pipeline_gpu1.py
@@ -0,0 +1,105 @@
+from typing import Any, Dict, List, TypeAlias
+
+MethodConfig: TypeAlias = Dict[str, Dict[str, Any]]
+PipelineStageConfig: TypeAlias = List[MethodConfig]
+PipelineConfig: TypeAlias = List[PipelineStageConfig]
+
+# NOTE: when creating a Pythonic pipeline, please use
+# the function's name "methods_to_list" so it will be 
+# found by the loader
+
+def methods_to_list() -> PipelineConfig:
+    """Pythonic way to build a list of tasks
+    from which Pipeline can be generated in Httomo.
+    This accompaniments the YAML interface.
+
+    Returns:
+        PipelineConfig: A list of tasks in "full_pipeline_list" that can be executed in Httomo.
+    """
+    full_pipeline_list = []
+    loader = {
+        'method': "standard_tomo",
+        'module_path': "httomo.data.hdf.loaders",
+        'parameters' : {
+                     'name': 'tomo',
+                     'data_path': 'entry1/tomo_entry/data/data',
+                     'image_key_path': 'entry1/tomo_entry/instrument/detector/image_key',
+                     'rotation_angles': {"data_path": "/entry1/tomo_entry/data/rotation_angle"},
+                     'dimension': 1,
+                     'preview': [None, None, None],
+                     'pad': 0,
+                       },
+                    }
+    full_pipeline_list.append(loader)
+    method1 = {
+        'method': "find_center_vo",
+        'module_path': "httomolibgpu.recon.rotation",
+        'id': "centering",
+        'parameters' : {
+                     'ind': "mid",
+                     'smin': -50,
+                     'smax': 50,
+                     'srad': 6,
+                     'step': 0.25,
+                     'ratio': 0.5,
+                     'drop': 20,
+                       },
+        'side_outputs': {"cor": "centre_of_rotation"},
+                    }
+    full_pipeline_list.append(method1)
+    method2 = {
+        'method': "remove_outlier3d",
+        'module_path': "httomolibgpu.misc.corr",
+        'parameters' : {
+                        'dif': 0.1,
+                        'kernel_size': 3,
+                       },
+                    }
+    full_pipeline_list.append(method2)    
+    method3 = {
+        'method': "normalize",
+        'module_path': "httomolibgpu.prep.normalize",
+        'parameters' : {
+                     'cutoff': 10.0,
+                     'minus_log': True,
+                     'nonnegativity': False,
+                     'remove_nans': False,
+                       },
+                    }
+    full_pipeline_list.append(method3)
+    method4 = {
+        'method': "remove_stripe_based_sorting",
+        'module_path': "httomolibgpu.prep.stripe",
+        'parameters' : {
+                     'size': 11,
+                     'dim': 1,
+                       },
+                    }
+    full_pipeline_list.append(method4)
+    method5 = {
+        'method': "FBP",
+        'module_path': "httomolibgpu.recon.algorithm",
+        'parameters' : {
+                     'center': "${{centering.side_outputs.centre_of_rotation}}",
+                     'recon_size': None,
+                     'recon_mask_radius': None,
+                       },
+                    }
+    full_pipeline_list.append(method5)
+    method6 = {
+        'method': "save_to_images",
+        'module_path': "httomolib.misc.images",
+        'parameters' : {
+                     'subfolder_name': "images",
+                     'axis': 1,
+                     'file_format': "tif",
+                     'bits': 8,
+                     'perc_range_min': 0.0,
+                     'perc_range_max': 100.0,
+                     'jpeg_quality': 95,
+                       },
+                    }
+    full_pipeline_list.append(method6)
+
+    return full_pipeline_list
+    
\ No newline at end of file
diff --git a/templates/httomo/1.2/httomo.data.hdf.loaders/standard_tomo.yaml b/templates/httomo/1.2/httomo.data.hdf.loaders/standard_tomo.yaml
new file mode 100644
index 000000000..b735274d7
--- /dev/null
+++ b/templates/httomo/1.2/httomo.data.hdf.loaders/standard_tomo.yaml
@@ -0,0 +1,14 @@
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: REQUIRED
+    in_file: REQUIRED
+    data_path: REQUIRED
+    dimension: REQUIRED
+    preview: REQUIRED
+    pad: REQUIRED
+    image_key_path: null
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    ignore_darks: false
+    ignore_flats: false
diff --git a/templates/httomo/httomo.data.hdf.loaders/standard_tomo.yaml b/templates/httomo/httomo.data.hdf.loaders/standard_tomo.yaml
deleted file mode 100644
index 4f184f551..000000000
--- a/templates/httomo/httomo.data.hdf.loaders/standard_tomo.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detector/image_key
-      angles_path: /entry1/tomo_entry/data/rotation_angle
-      dimension: 1
-      preview: [None, None, None]
-      pad: 0
diff --git a/templates/httomo/httomo_modules.yaml b/templates/httomo/httomo_modules.yaml
new file mode 100644
index 000000000..728b63989
--- /dev/null
+++ b/templates/httomo/httomo_modules.yaml
@@ -0,0 +1,1 @@
+- httomo.data.hdf.loaders
\ No newline at end of file
diff --git a/templates/httomolib/1.2/httomolib.misc.corr/inpainting_filter3d.yaml b/templates/httomolib/1.2/httomolib.misc.corr/inpainting_filter3d.yaml
index e7c720505..08d1d1f0f 100644
--- a/templates/httomolib/1.2/httomolib.misc.corr/inpainting_filter3d.yaml
+++ b/templates/httomolib/1.2/httomolib.misc.corr/inpainting_filter3d.yaml
@@ -1,8 +1,7 @@
-- httomolib.misc.corr:
-    inpainting_filter3d:
-      data_in: tomo
-      data_out: tomo
-      mask: REQUIRED
-      iter: 3
-      windowsize_half: 5
-      method_type: random
+- method: inpainting_filter3d
+  module_path: httomolib.misc.corr
+  parameters:
+    mask: REQUIRED
+    iter: 3
+    windowsize_half: 5
+    method_type: random
diff --git a/templates/httomolib/1.2/httomolib.misc.images/save_to_images.yaml b/templates/httomolib/1.2/httomolib.misc.images/save_to_images.yaml
index 9792e3f8d..519cdf739 100644
--- a/templates/httomolib/1.2/httomolib.misc.images/save_to_images.yaml
+++ b/templates/httomolib/1.2/httomolib.misc.images/save_to_images.yaml
@@ -1,11 +1,11 @@
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 1
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
-      glob_stats: null
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 1
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: null
diff --git a/templates/httomolib/1.2/httomolib.misc.segm/binary_thresholding.yaml b/templates/httomolib/1.2/httomolib.misc.segm/binary_thresholding.yaml
index 8ed1120fc..459aca568 100644
--- a/templates/httomolib/1.2/httomolib.misc.segm/binary_thresholding.yaml
+++ b/templates/httomolib/1.2/httomolib.misc.segm/binary_thresholding.yaml
@@ -1,8 +1,7 @@
-- httomolib.misc.segm:
-    binary_thresholding:
-      data_in: tomo
-      data_out: tomo
-      val_intensity: 0.1
-      otsu: false
-      foreground: true
-      axis: 1
+- method: binary_thresholding
+  module_path: httomolib.misc.segm
+  parameters:
+    val_intensity: 0.1
+    otsu: false
+    foreground: true
+    axis: 1
diff --git a/templates/httomolib/1.2/httomolib.prep.phase/paganin_filter.yaml b/templates/httomolib/1.2/httomolib.prep.phase/paganin_filter.yaml
index e03279fc0..63da87de0 100644
--- a/templates/httomolib/1.2/httomolib.prep.phase/paganin_filter.yaml
+++ b/templates/httomolib/1.2/httomolib.prep.phase/paganin_filter.yaml
@@ -1,8 +1,7 @@
-- httomolib.prep.phase:
-    paganin_filter:
-      data_in: tomo
-      data_out: tomo
-      pixel_size: 0.0001
-      dist: 50.0
-      energy: 53.0
-      alpha: 0.001
+- method: paganin_filter
+  module_path: httomolib.prep.phase
+  parameters:
+    pixel_size: 0.0001
+    dist: 50.0
+    energy: 53.0
+    alpha: 0.001
diff --git a/templates/httomolib/httomolib_modules.yaml b/templates/httomolib/httomolib_modules.yaml
index 55230a207..8fe8d7016 100644
--- a/templates/httomolib/httomolib_modules.yaml
+++ b/templates/httomolib/httomolib_modules.yaml
@@ -1,4 +1,4 @@
 - httomolib.misc.corr
 - httomolib.misc.images
 - httomolib.misc.segm
-- httomolib.prep.phase
\ No newline at end of file
+- httomolib.prep.phase
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.misc.corr/median_filter3d.yaml b/templates/httomolibgpu/1.2/httomolibgpu.misc.corr/median_filter3d.yaml
index 1e2e5a441..3e44f87f3 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.misc.corr/median_filter3d.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.misc.corr/median_filter3d.yaml
@@ -1,6 +1,5 @@
-- httomolibgpu.misc.corr:
-    median_filter3d:
-      data_in: tomo
-      data_out: tomo
-      kernel_size: 3
-      dif: 0.0
+- method: median_filter3d
+  module_path: httomolibgpu.misc.corr
+  parameters:
+    kernel_size: 3
+    dif: 0.0
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.misc.corr/remove_outlier3d.yaml b/templates/httomolibgpu/1.2/httomolibgpu.misc.corr/remove_outlier3d.yaml
index 3306b96d6..066225b95 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.misc.corr/remove_outlier3d.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.misc.corr/remove_outlier3d.yaml
@@ -1,6 +1,5 @@
-- httomolibgpu.misc.corr:
-    remove_outlier3d:
-      data_in: tomo
-      data_out: tomo
-      kernel_size: 3
-      dif: 0.1
+- method: remove_outlier3d
+  module_path: httomolibgpu.misc.corr
+  parameters:
+    kernel_size: 3
+    dif: 0.1
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.misc.morph/sino_360_to_180.yaml b/templates/httomolibgpu/1.2/httomolibgpu.misc.morph/sino_360_to_180.yaml
index b3d2bfd72..fd228b338 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.misc.morph/sino_360_to_180.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.misc.morph/sino_360_to_180.yaml
@@ -1,6 +1,5 @@
-- httomolibgpu.misc.morph:
-    sino_360_to_180:
-      data_in: tomo
-      data_out: tomo
-      overlap: 0
-      rotation: left
+- method: sino_360_to_180
+  module_path: httomolibgpu.misc.morph
+  parameters:
+    overlap: 0
+    rotation: left
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.alignment/distortion_correction_proj.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.alignment/distortion_correction_proj.yaml
new file mode 100644
index 000000000..869ee8c53
--- /dev/null
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.alignment/distortion_correction_proj.yaml
@@ -0,0 +1,9 @@
+- method: distortion_correction_proj
+  module_path: httomolibgpu.prep.alignment
+  parameters:
+    metadata_path: REQUIRED
+    preview: REQUIRED
+    center_from_left: null
+    center_from_top: null
+    polynomial_coeffs: null
+    crop: 0
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.alignment/distortion_correction_proj_discorpy.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.alignment/distortion_correction_proj_discorpy.yaml
index c81fef45f..5e31d25e1 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.prep.alignment/distortion_correction_proj_discorpy.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.alignment/distortion_correction_proj_discorpy.yaml
@@ -1,8 +1,7 @@
-- httomolibgpu.prep.alignment:
-    distortion_correction_proj_discorpy:
-      data_in: tomo
-      data_out: tomo
-      metadata_path: REQUIRED
-      preview: REQUIRED
-      order: 1
-      mode: reflect
+- method: distortion_correction_proj_discorpy
+  module_path: httomolibgpu.prep.alignment
+  parameters:
+    metadata_path: REQUIRED
+    preview: REQUIRED
+    order: 1
+    mode: reflect
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.normalize/normalize.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.normalize/normalize.yaml
index a53981cdc..66609c793 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.prep.normalize/normalize.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.normalize/normalize.yaml
@@ -1,8 +1,7 @@
-- httomolibgpu.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: 10.0
-      minus_log: false
-      nonnegativity: false
-      remove_nans: false
+- method: normalize
+  module_path: httomolibgpu.prep.normalize
+  parameters:
+    cutoff: 10.0
+    minus_log: false
+    nonnegativity: false
+    remove_nans: false
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/fresnel_filter.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/fresnel_filter.yaml
new file mode 100644
index 000000000..437bc9e61
--- /dev/null
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/fresnel_filter.yaml
@@ -0,0 +1,7 @@
+- method: fresnel_filter
+  module_path: httomolibgpu.prep.phase
+  parameters:
+    mat: REQUIRED
+    pattern: REQUIRED
+    ratio: REQUIRED
+    apply_log: true
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter.yaml
new file mode 100644
index 000000000..ef65be0e5
--- /dev/null
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter.yaml
@@ -0,0 +1,11 @@
+- method: paganin_filter
+  module_path: httomolibgpu.prep.phase
+  parameters:
+    ratio: 250.0
+    energy: 53.0
+    distance: 1.0
+    resolution: 1.28
+    pad_y: 100
+    pad_x: 100
+    pad_method: edge
+    increment: 0.0
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter2.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter2.yaml
new file mode 100644
index 000000000..cffc728f6
--- /dev/null
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter2.yaml
@@ -0,0 +1,7 @@
+- method: paganin_filter2
+  module_path: httomolibgpu.prep.phase
+  parameters:
+    pixel_size: 0.0001
+    dist: 50.0
+    energy: 53.0
+    alpha: 0.001
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter_savu.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter_savu.yaml
index 02ca3dd30..1d7a5027a 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter_savu.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter_savu.yaml
@@ -1,12 +1,11 @@
-- httomolibgpu.prep.phase:
-    paganin_filter_savu:
-      data_in: tomo
-      data_out: tomo
-      ratio: 250.0
-      energy: 53.0
-      distance: 1.0
-      resolution: 1.28
-      pad_y: 100
-      pad_x: 100
-      pad_method: edge
-      increment: 0.0
+- method: paganin_filter_savu
+  module_path: httomolibgpu.prep.phase
+  parameters:
+    ratio: 250.0
+    energy: 53.0
+    distance: 1.0
+    resolution: 1.28
+    pad_y: 100
+    pad_x: 100
+    pad_method: edge
+    increment: 0.0
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter_tomopy.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter_tomopy.yaml
index fd877370c..7752f1e7f 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter_tomopy.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.phase/paganin_filter_tomopy.yaml
@@ -1,8 +1,7 @@
-- httomolibgpu.prep.phase:
-    paganin_filter_tomopy:
-      data_in: tomo
-      data_out: tomo
-      pixel_size: 0.0001
-      dist: 50.0
-      energy: 53.0
-      alpha: 0.001
+- method: paganin_filter_tomopy
+  module_path: httomolibgpu.prep.phase
+  parameters:
+    pixel_size: 0.0001
+    dist: 50.0
+    energy: 53.0
+    alpha: 0.001
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_all_stripe.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_all_stripe.yaml
new file mode 100644
index 000000000..5cfa82c1e
--- /dev/null
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_all_stripe.yaml
@@ -0,0 +1,7 @@
+- method: remove_all_stripe
+  module_path: httomolibgpu.prep.stripe
+  parameters:
+    snr: 3.0
+    la_size: 61
+    sm_size: 21
+    dim: 1
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_stripe_based_sorting.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_stripe_based_sorting.yaml
index 5650e47d3..a113f74f8 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_stripe_based_sorting.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_stripe_based_sorting.yaml
@@ -1,6 +1,5 @@
-- httomolibgpu.prep.stripe:
-    remove_stripe_based_sorting:
-      data_in: tomo
-      data_out: tomo
-      size: 11
-      dim: 1
+- method: remove_stripe_based_sorting
+  module_path: httomolibgpu.prep.stripe
+  parameters:
+    size: 11
+    dim: 1
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_stripe_ti.yaml b/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_stripe_ti.yaml
index 390abeda3..71332c0dc 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_stripe_ti.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.prep.stripe/remove_stripe_ti.yaml
@@ -1,5 +1,4 @@
-- httomolibgpu.prep.stripe:
-    remove_stripe_ti:
-      data_in: tomo
-      data_out: tomo
-      beta: 0.1
+- method: remove_stripe_ti
+  module_path: httomolibgpu.prep.stripe
+  parameters:
+    beta: 0.1
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/CGLS.yaml b/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/CGLS.yaml
index ba20726b8..b87272e6b 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/CGLS.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/CGLS.yaml
@@ -1,9 +1,7 @@
-- httomolibgpu.recon.algorithm:
-    CGLS:
-      data_in: tomo
-      data_out: tomo
-      center: null
-      recon_size: null
-      iterations: 20
-      nonnegativity: true
-      recon_mask_radius: null
+- method: CGLS
+  module_path: httomolibgpu.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    recon_size: null
+    iterations: 20
+    nonnegativity: true
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/FBP.yaml b/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/FBP.yaml
index 2ade9ed06..6798cfcc3 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/FBP.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/FBP.yaml
@@ -1,7 +1,6 @@
-- httomolibgpu.recon.algorithm:
-    FBP:
-      data_in: tomo
-      data_out: tomo
-      center: null
-      recon_size: null
-      recon_mask_radius: null
+- method: FBP
+  module_path: httomolibgpu.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    recon_size: null
+    recon_mask_radius: null
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/SIRT.yaml b/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/SIRT.yaml
index 00d57e811..ada743094 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/SIRT.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.recon.algorithm/SIRT.yaml
@@ -1,9 +1,7 @@
-- httomolibgpu.recon.algorithm:
-    SIRT:
-      data_in: tomo
-      data_out: tomo
-      center: null
-      recon_size: null
-      iterations: 300
-      nonnegativity: true
-      recon_mask_radius: null
+- method: SIRT
+  module_path: httomolibgpu.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    recon_size: null
+    iterations: 300
+    nonnegativity: true
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.recon.rotation/find_center_360.yaml b/templates/httomolibgpu/1.2/httomolibgpu.recon.rotation/find_center_360.yaml
index 3fade9970..bdc3f15d4 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.recon.rotation/find_center_360.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.recon.rotation/find_center_360.yaml
@@ -1,14 +1,15 @@
-- httomolibgpu.recon.rotation:
-    find_center_360:
-      data_in: tomo
-      data_out:
-      - cor
-      - overlap
-      - side
-      - overlap_position
-      ind: null
-      win_width: 10
-      side: null
-      denoise: true
-      norm: false
-      use_overlap: false
+- method: find_center_360
+  module_path: httomolibgpu.recon.rotation
+  parameters:
+    ind: null
+    win_width: 10
+    side: null
+    denoise: true
+    norm: false
+    use_overlap: false
+  id: centering
+  side_outputs:
+    centre_of_rotation: cor
+    overlap: overlap
+    side: side
+    overlap_position: overlap_position
diff --git a/templates/httomolibgpu/1.2/httomolibgpu.recon.rotation/find_center_vo.yaml b/templates/httomolibgpu/1.2/httomolibgpu.recon.rotation/find_center_vo.yaml
index dcdfd9660..fc5739790 100644
--- a/templates/httomolibgpu/1.2/httomolibgpu.recon.rotation/find_center_vo.yaml
+++ b/templates/httomolibgpu/1.2/httomolibgpu.recon.rotation/find_center_vo.yaml
@@ -1,11 +1,13 @@
-- httomolibgpu.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: null
-      smin: -50
-      smax: 50
-      srad: 6.0
-      step: 0.25
-      ratio: 0.5
-      drop: 20
+- method: find_center_vo
+  module_path: httomolibgpu.recon.rotation
+  parameters:
+    ind: null
+    smin: -50
+    smax: 50
+    srad: 6.0
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/adjust_range.yaml b/templates/tomopy/1.14/tomopy.misc.corr/adjust_range.yaml
index be4321123..f02934fbc 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/adjust_range.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/adjust_range.yaml
@@ -1,6 +1,5 @@
-- tomopy.misc.corr:
-    adjust_range:
-      data_in: tomo
-      data_out: tomo
-      dmin: null
-      dmax: null
+- method: adjust_range
+  module_path: tomopy.misc.corr
+  parameters:
+    dmin: null
+    dmax: null
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/circ_mask.yaml b/templates/tomopy/1.14/tomopy.misc.corr/circ_mask.yaml
index ab7778311..401836769 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/circ_mask.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/circ_mask.yaml
@@ -1,7 +1,6 @@
-- tomopy.misc.corr:
-    circ_mask:
-      data_in: tomo
-      data_out: tomo
-      axis: REQUIRED
-      ratio: 1
-      val: 0.0
+- method: circ_mask
+  module_path: tomopy.misc.corr
+  parameters:
+    axis: REQUIRED
+    ratio: 1
+    val: 0.0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/enhance_projs_aps_1id.yaml b/templates/tomopy/1.14/tomopy.misc.corr/enhance_projs_aps_1id.yaml
new file mode 100644
index 000000000..5a1ca23c6
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.misc.corr/enhance_projs_aps_1id.yaml
@@ -0,0 +1,5 @@
+- method: enhance_projs_aps_1id
+  module_path: tomopy.misc.corr
+  parameters:
+    imgstack: REQUIRED
+    median_ks: 5
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/gaussian_filter.yaml b/templates/tomopy/1.14/tomopy.misc.corr/gaussian_filter.yaml
index e48937914..25189f57d 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/gaussian_filter.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/gaussian_filter.yaml
@@ -1,7 +1,6 @@
-- tomopy.misc.corr:
-    gaussian_filter:
-      data_in: tomo
-      data_out: tomo
-      sigma: 3
-      order: 0
-      axis: 0
+- method: gaussian_filter
+  module_path: tomopy.misc.corr
+  parameters:
+    sigma: 3
+    order: 0
+    axis: 0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/median_filter.yaml b/templates/tomopy/1.14/tomopy.misc.corr/median_filter.yaml
index 40ff893f4..4fa945a0d 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/median_filter.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/median_filter.yaml
@@ -1,6 +1,5 @@
-- tomopy.misc.corr:
-    median_filter:
-      data_in: tomo
-      data_out: tomo
-      size: 3
-      axis: 0
+- method: median_filter
+  module_path: tomopy.misc.corr
+  parameters:
+    size: 3
+    axis: 0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/median_filter3d.yaml b/templates/tomopy/1.14/tomopy.misc.corr/median_filter3d.yaml
index 510892112..a469bac13 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/median_filter3d.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/median_filter3d.yaml
@@ -1,5 +1,4 @@
-- tomopy.misc.corr:
-    median_filter3d:
-      data_in: tomo
-      data_out: tomo
-      size: 3
+- method: median_filter3d
+  module_path: tomopy.misc.corr
+  parameters:
+    size: 3
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/median_filter_cuda.yaml b/templates/tomopy/1.14/tomopy.misc.corr/median_filter_cuda.yaml
new file mode 100644
index 000000000..b24512c35
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.misc.corr/median_filter_cuda.yaml
@@ -0,0 +1,5 @@
+- method: median_filter_cuda
+  module_path: tomopy.misc.corr
+  parameters:
+    size: 3
+    axis: 0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/median_filter_nonfinite.yaml b/templates/tomopy/1.14/tomopy.misc.corr/median_filter_nonfinite.yaml
index 04bf2a79d..6afcf75f6 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/median_filter_nonfinite.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/median_filter_nonfinite.yaml
@@ -1,6 +1,5 @@
-- tomopy.misc.corr:
-    median_filter_nonfinite:
-      data_in: tomo
-      data_out: tomo
-      size: 3
-      callback: null
+- method: median_filter_nonfinite
+  module_path: tomopy.misc.corr
+  parameters:
+    size: 3
+    callback: null
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/remove_nan.yaml b/templates/tomopy/1.14/tomopy.misc.corr/remove_nan.yaml
index 6d20f8042..ed802d399 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/remove_nan.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/remove_nan.yaml
@@ -1,5 +1,4 @@
-- tomopy.misc.corr:
-    remove_nan:
-      data_in: tomo
-      data_out: tomo
-      val: 0.0
+- method: remove_nan
+  module_path: tomopy.misc.corr
+  parameters:
+    val: 0.0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/remove_neg.yaml b/templates/tomopy/1.14/tomopy.misc.corr/remove_neg.yaml
index ac58d55fc..10fb6d5b6 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/remove_neg.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/remove_neg.yaml
@@ -1,5 +1,4 @@
-- tomopy.misc.corr:
-    remove_neg:
-      data_in: tomo
-      data_out: tomo
-      val: 0.0
+- method: remove_neg
+  module_path: tomopy.misc.corr
+  parameters:
+    val: 0.0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier.yaml b/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier.yaml
index f092d6d7a..bcc85c2ad 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier.yaml
@@ -1,7 +1,6 @@
-- tomopy.misc.corr:
-    remove_outlier:
-      data_in: tomo
-      data_out: tomo
-      dif: REQUIRED
-      size: 3
-      axis: 0
+- method: remove_outlier
+  module_path: tomopy.misc.corr
+  parameters:
+    dif: REQUIRED
+    size: 3
+    axis: 0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier1d.yaml b/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier1d.yaml
index 4e961e1de..2606001c3 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier1d.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier1d.yaml
@@ -1,7 +1,6 @@
-- tomopy.misc.corr:
-    remove_outlier1d:
-      data_in: tomo
-      data_out: tomo
-      dif: REQUIRED
-      size: 3
-      axis: 0
+- method: remove_outlier1d
+  module_path: tomopy.misc.corr
+  parameters:
+    dif: REQUIRED
+    size: 3
+    axis: 0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier3d.yaml b/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier3d.yaml
index 748f4fa1c..4123734fd 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier3d.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier3d.yaml
@@ -1,6 +1,5 @@
-- tomopy.misc.corr:
-    remove_outlier3d:
-      data_in: tomo
-      data_out: tomo
-      dif: REQUIRED
-      size: 3
+- method: remove_outlier3d
+  module_path: tomopy.misc.corr
+  parameters:
+    dif: REQUIRED
+    size: 3
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier_cuda.yaml b/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier_cuda.yaml
new file mode 100644
index 000000000..4658d8f37
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.misc.corr/remove_outlier_cuda.yaml
@@ -0,0 +1,6 @@
+- method: remove_outlier_cuda
+  module_path: tomopy.misc.corr
+  parameters:
+    dif: REQUIRED
+    size: 3
+    axis: 0
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/remove_ring.yaml b/templates/tomopy/1.14/tomopy.misc.corr/remove_ring.yaml
index 6ec0ef981..107c63552 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/remove_ring.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/remove_ring.yaml
@@ -1,13 +1,12 @@
-- tomopy.misc.corr:
-    remove_ring:
-      data_in: tomo
-      data_out: tomo
-      rec: REQUIRED
-      center_x: null
-      center_y: null
-      thresh: 300.0
-      thresh_max: 300.0
-      thresh_min: -100.0
-      theta_min: 30
-      rwidth: 30
-      int_mode: WRAP
+- method: remove_ring
+  module_path: tomopy.misc.corr
+  parameters:
+    rec: REQUIRED
+    center_x: null
+    center_y: null
+    thresh: 300.0
+    thresh_max: 300.0
+    thresh_min: -100.0
+    theta_min: 30
+    rwidth: 30
+    int_mode: WRAP
diff --git a/templates/tomopy/1.14/tomopy.misc.corr/sobel_filter.yaml b/templates/tomopy/1.14/tomopy.misc.corr/sobel_filter.yaml
index 05425d850..286bc165a 100644
--- a/templates/tomopy/1.14/tomopy.misc.corr/sobel_filter.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.corr/sobel_filter.yaml
@@ -1,5 +1,4 @@
-- tomopy.misc.corr:
-    sobel_filter:
-      data_in: tomo
-      data_out: tomo
-      axis: 0
+- method: sobel_filter
+  module_path: tomopy.misc.corr
+  parameters:
+    axis: 0
diff --git a/templates/tomopy/1.14/tomopy.misc.morph/downsample.yaml b/templates/tomopy/1.14/tomopy.misc.morph/downsample.yaml
index bf62ebb65..596b18ad7 100644
--- a/templates/tomopy/1.14/tomopy.misc.morph/downsample.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.morph/downsample.yaml
@@ -1,6 +1,5 @@
-- tomopy.misc.morph:
-    downsample:
-      data_in: tomo
-      data_out: tomo
-      level: 1
-      axis: 2
+- method: downsample
+  module_path: tomopy.misc.morph
+  parameters:
+    level: 1
+    axis: 2
diff --git a/templates/tomopy/1.14/tomopy.misc.morph/pad.yaml b/templates/tomopy/1.14/tomopy.misc.morph/pad.yaml
index 222b0281b..44572c480 100644
--- a/templates/tomopy/1.14/tomopy.misc.morph/pad.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.morph/pad.yaml
@@ -1,8 +1,7 @@
-- tomopy.misc.morph:
-    pad:
-      data_in: tomo
-      data_out: tomo
-      axis: REQUIRED
-      npad: null
-      mode: constant
-      '#additional parameters': AVAILABLE
+- method: pad
+  module_path: tomopy.misc.morph
+  parameters:
+    axis: REQUIRED
+    npad: null
+    mode: constant
+    '#additional parameters': AVAILABLE
diff --git a/templates/tomopy/1.14/tomopy.misc.morph/sino_360_t0_180.yaml b/templates/tomopy/1.14/tomopy.misc.morph/sino_360_t0_180.yaml
new file mode 100644
index 000000000..ff5b71be7
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.misc.morph/sino_360_t0_180.yaml
@@ -0,0 +1,5 @@
+- method: sino_360_t0_180
+  module_path: tomopy.misc.morph
+  parameters:
+    overlap: 0
+    rotation: left
diff --git a/templates/tomopy/1.14/tomopy.misc.morph/sino_360_to_180.yaml b/templates/tomopy/1.14/tomopy.misc.morph/sino_360_to_180.yaml
index 5c4969ef4..14f6e9f26 100644
--- a/templates/tomopy/1.14/tomopy.misc.morph/sino_360_to_180.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.morph/sino_360_to_180.yaml
@@ -1,6 +1,5 @@
-- tomopy.misc.morph:
-    sino_360_to_180:
-      data_in: tomo
-      data_out: tomo
-      overlap: 0
-      rotation: left
+- method: sino_360_to_180
+  module_path: tomopy.misc.morph
+  parameters:
+    overlap: 0
+    rotation: left
diff --git a/templates/tomopy/1.14/tomopy.misc.morph/trim_sinogram.yaml b/templates/tomopy/1.14/tomopy.misc.morph/trim_sinogram.yaml
index 4312773ec..f020e2ec3 100644
--- a/templates/tomopy/1.14/tomopy.misc.morph/trim_sinogram.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.morph/trim_sinogram.yaml
@@ -1,8 +1,7 @@
-- tomopy.misc.morph:
-    trim_sinogram:
-      data_in: tomo
-      data_out: tomo
-      center: REQUIRED
-      x: REQUIRED
-      y: REQUIRED
-      diameter: REQUIRED
+- method: trim_sinogram
+  module_path: tomopy.misc.morph
+  parameters:
+    center: REQUIRED
+    x: REQUIRED
+    y: REQUIRED
+    diameter: REQUIRED
diff --git a/templates/tomopy/1.14/tomopy.misc.morph/upsample.yaml b/templates/tomopy/1.14/tomopy.misc.morph/upsample.yaml
index 92afa4af2..b27b19f24 100644
--- a/templates/tomopy/1.14/tomopy.misc.morph/upsample.yaml
+++ b/templates/tomopy/1.14/tomopy.misc.morph/upsample.yaml
@@ -1,6 +1,5 @@
-- tomopy.misc.morph:
-    upsample:
-      data_in: tomo
-      data_out: tomo
-      level: 1
-      axis: 2
+- method: upsample
+  module_path: tomopy.misc.morph
+  parameters:
+    level: 1
+    axis: 2
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/add_jitter.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/add_jitter.yaml
index c43ff4a9e..f7b9821e6 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/add_jitter.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/add_jitter.yaml
@@ -1,6 +1,5 @@
-- tomopy.prep.alignment:
-    add_jitter:
-      data_in: tomo
-      data_out: tomo
-      low: 0
-      high: 1
+- method: add_jitter
+  module_path: tomopy.prep.alignment
+  parameters:
+    low: 0
+    high: 1
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/add_noise.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/add_noise.yaml
index c7b6a4f77..350e13c9f 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/add_noise.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/add_noise.yaml
@@ -1,5 +1,4 @@
-- tomopy.prep.alignment:
-    add_noise:
-      data_in: tomo
-      data_out: tomo
-      ratio: 0.05
+- method: add_noise
+  module_path: tomopy.prep.alignment
+  parameters:
+    ratio: 0.05
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/align_joint.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/align_joint.yaml
index 21bb95bdd..35d8f51f4 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/align_joint.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/align_joint.yaml
@@ -1,17 +1,16 @@
-- tomopy.prep.alignment:
-    align_joint:
-      data_in: tomo
-      data_out: tomo
-      fdir: .
-      iters: 10
-      pad: !!python/tuple
-      - 0
-      - 0
-      blur: true
-      center: null
-      algorithm: sirt
-      upsample_factor: 10
-      rin: 0.5
-      rout: 0.8
-      save: false
-      debug: true
+- method: align_joint
+  module_path: tomopy.prep.alignment
+  parameters:
+    fdir: ./
+    iters: 10
+    pad: !!python/tuple
+    - 0
+    - 0
+    blur: true
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    algorithm: sirt
+    upsample_factor: 10
+    rin: 0.5
+    rout: 0.8
+    save: false
+    debug: true
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/align_seq.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/align_seq.yaml
index 4b05842da..8c4d11c8c 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/align_seq.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/align_seq.yaml
@@ -1,17 +1,16 @@
-- tomopy.prep.alignment:
-    align_seq:
-      data_in: tomo
-      data_out: tomo
-      fdir: .
-      iters: 10
-      pad: !!python/tuple
-      - 0
-      - 0
-      blur: true
-      center: null
-      algorithm: sirt
-      upsample_factor: 10
-      rin: 0.5
-      rout: 0.8
-      save: false
-      debug: true
+- method: align_seq
+  module_path: tomopy.prep.alignment
+  parameters:
+    fdir: .
+    iters: 10
+    pad: !!python/tuple
+    - 0
+    - 0
+    blur: true
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    algorithm: sirt
+    upsample_factor: 10
+    rin: 0.5
+    rout: 0.8
+    save: false
+    debug: true
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/blur_edges.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/blur_edges.yaml
index a4919fabe..57b2ace2b 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/blur_edges.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/blur_edges.yaml
@@ -1,6 +1,5 @@
-- tomopy.prep.alignment:
-    blur_edges:
-      data_in: tomo
-      data_out: tomo
-      low: 0
-      high: 0.8
+- method: blur_edges
+  module_path: tomopy.prep.alignment
+  parameters:
+    low: 0
+    high: 0.8
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/calc_slit_box_aps_1id.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/calc_slit_box_aps_1id.yaml
new file mode 100644
index 000000000..41b84453a
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/calc_slit_box_aps_1id.yaml
@@ -0,0 +1,9 @@
+- method: calc_slit_box_aps_1id
+  module_path: tomopy.prep.alignment
+  parameters:
+    slit_box_corners: REQUIRED
+    inclip: !!python/tuple
+    - 1
+    - 10
+    - 1
+    - 10
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/distortion_correction_proj.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/distortion_correction_proj.yaml
index 86b1b4d58..6dec583e4 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/distortion_correction_proj.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/distortion_correction_proj.yaml
@@ -1,7 +1,6 @@
-- tomopy.prep.alignment:
-    distortion_correction_proj:
-      data_in: tomo
-      data_out: tomo
-      xcenter: REQUIRED
-      ycenter: REQUIRED
-      list_fact: REQUIRED
+- method: distortion_correction_proj
+  module_path: tomopy.prep.alignment
+  parameters:
+    xcenter: REQUIRED
+    ycenter: REQUIRED
+    list_fact: REQUIRED
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/distortion_correction_sino.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/distortion_correction_sino.yaml
index 562db24d2..d8a4ae49f 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/distortion_correction_sino.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/distortion_correction_sino.yaml
@@ -1,8 +1,7 @@
-- tomopy.prep.alignment:
-    distortion_correction_sino:
-      data_in: tomo
-      data_out: tomo
-      ind: REQUIRED
-      xcenter: REQUIRED
-      ycenter: REQUIRED
-      list_fact: REQUIRED
+- method: distortion_correction_sino
+  module_path: tomopy.prep.alignment
+  parameters:
+    ind: REQUIRED
+    xcenter: REQUIRED
+    ycenter: REQUIRED
+    list_fact: REQUIRED
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/find_slits_corners_aps_1id.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/find_slits_corners_aps_1id.yaml
new file mode 100644
index 000000000..437baa475
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/find_slits_corners_aps_1id.yaml
@@ -0,0 +1,7 @@
+- method: find_slits_corners_aps_1id
+  module_path: tomopy.prep.alignment
+  parameters:
+    img: REQUIRED
+    method: quadrant+
+    medfilt2_kernel_size: 3
+    medfilt_kernel_size: 23
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/load_distortion_coefs.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/load_distortion_coefs.yaml
new file mode 100644
index 000000000..b5fa275b1
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/load_distortion_coefs.yaml
@@ -0,0 +1,4 @@
+- method: load_distortion_coefs
+  module_path: tomopy.prep.alignment
+  parameters:
+    file_path: REQUIRED
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/remove_slits_aps_1id.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/remove_slits_aps_1id.yaml
new file mode 100644
index 000000000..73f25487f
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/remove_slits_aps_1id.yaml
@@ -0,0 +1,10 @@
+- method: remove_slits_aps_1id
+  module_path: tomopy.prep.alignment
+  parameters:
+    imgstacks: REQUIRED
+    slit_box_corners: REQUIRED
+    inclip: !!python/tuple
+    - 1
+    - 10
+    - 1
+    - 10
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/scale.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/scale.yaml
index 4f650fe43..7a628485b 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/scale.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/scale.yaml
@@ -1,4 +1,3 @@
-- tomopy.prep.alignment:
-    scale:
-      data_in: tomo
-      data_out: tomo
+- method: scale
+  module_path: tomopy.prep.alignment
+  parameters: {}
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/shift_images.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/shift_images.yaml
index f03cac861..8ed8fc2f6 100644
--- a/templates/tomopy/1.14/tomopy.prep.alignment/shift_images.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/shift_images.yaml
@@ -1,6 +1,5 @@
-- tomopy.prep.alignment:
-    shift_images:
-      data_in: tomo
-      data_out: tomo
-      sx: REQUIRED
-      sy: REQUIRED
+- method: shift_images
+  module_path: tomopy.prep.alignment
+  parameters:
+    sx: REQUIRED
+    sy: REQUIRED
diff --git a/templates/tomopy/1.14/tomopy.prep.alignment/tilt.yaml b/templates/tomopy/1.14/tomopy.prep.alignment/tilt.yaml
new file mode 100644
index 000000000..42aa746b8
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.prep.alignment/tilt.yaml
@@ -0,0 +1,6 @@
+- method: tilt
+  module_path: tomopy.prep.alignment
+  parameters:
+    obj: REQUIRED
+    rad: 0
+    phi: 0
diff --git a/templates/tomopy/1.14/tomopy.prep.normalize/minus_log.yaml b/templates/tomopy/1.14/tomopy.prep.normalize/minus_log.yaml
index 1d2429c22..6d9558919 100644
--- a/templates/tomopy/1.14/tomopy.prep.normalize/minus_log.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.normalize/minus_log.yaml
@@ -1,4 +1,3 @@
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
diff --git a/templates/tomopy/1.14/tomopy.prep.normalize/normalize.yaml b/templates/tomopy/1.14/tomopy.prep.normalize/normalize.yaml
index d2bcd5123..f917f4f94 100644
--- a/templates/tomopy/1.14/tomopy.prep.normalize/normalize.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.normalize/normalize.yaml
@@ -1,6 +1,5 @@
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-      averaging: mean
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
diff --git a/templates/tomopy/1.14/tomopy.prep.normalize/normalize_bg.yaml b/templates/tomopy/1.14/tomopy.prep.normalize/normalize_bg.yaml
index e80daa709..28088716e 100644
--- a/templates/tomopy/1.14/tomopy.prep.normalize/normalize_bg.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.normalize/normalize_bg.yaml
@@ -1,5 +1,4 @@
-- tomopy.prep.normalize:
-    normalize_bg:
-      data_in: tomo
-      data_out: tomo
-      air: 1
+- method: normalize_bg
+  module_path: tomopy.prep.normalize
+  parameters:
+    air: 1
diff --git a/templates/tomopy/1.14/tomopy.prep.normalize/normalize_nf.yaml b/templates/tomopy/1.14/tomopy.prep.normalize/normalize_nf.yaml
index 9bda58233..987749f86 100644
--- a/templates/tomopy/1.14/tomopy.prep.normalize/normalize_nf.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.normalize/normalize_nf.yaml
@@ -1,7 +1,6 @@
-- tomopy.prep.normalize:
-    normalize_nf:
-      data_in: tomo
-      data_out: tomo
-      flat_loc: REQUIRED
-      cutoff: null
-      averaging: mean
+- method: normalize_nf
+  module_path: tomopy.prep.normalize
+  parameters:
+    flat_loc: REQUIRED
+    cutoff: null
+    averaging: mean
diff --git a/templates/tomopy/1.14/tomopy.prep.normalize/normalize_roi.yaml b/templates/tomopy/1.14/tomopy.prep.normalize/normalize_roi.yaml
index 22a48026c..eae28603c 100644
--- a/templates/tomopy/1.14/tomopy.prep.normalize/normalize_roi.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.normalize/normalize_roi.yaml
@@ -1,9 +1,8 @@
-- tomopy.prep.normalize:
-    normalize_roi:
-      data_in: tomo
-      data_out: tomo
-      roi:
-      - 0
-      - 0
-      - 10
-      - 10
+- method: normalize_roi
+  module_path: tomopy.prep.normalize
+  parameters:
+    roi:
+    - 0
+    - 0
+    - 10
+    - 10
diff --git a/templates/tomopy/1.14/tomopy.prep.phase/retrieve_phase.yaml b/templates/tomopy/1.14/tomopy.prep.phase/retrieve_phase.yaml
index 24268b43f..e020a75b7 100644
--- a/templates/tomopy/1.14/tomopy.prep.phase/retrieve_phase.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.phase/retrieve_phase.yaml
@@ -1,9 +1,8 @@
-- tomopy.prep.phase:
-    retrieve_phase:
-      data_in: tomo
-      data_out: tomo
-      pixel_size: 0.0001
-      dist: 50
-      energy: 20
-      alpha: 0.001
-      pad: true
+- method: retrieve_phase
+  module_path: tomopy.prep.phase
+  parameters:
+    pixel_size: 0.0001
+    dist: 50
+    energy: 20
+    alpha: 0.001
+    pad: true
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_all_stripe.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_all_stripe.yaml
index d3b74f19b..19c77f31d 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_all_stripe.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_all_stripe.yaml
@@ -1,8 +1,7 @@
-- tomopy.prep.stripe:
-    remove_all_stripe:
-      data_in: tomo
-      data_out: tomo
-      snr: 3
-      la_size: 61
-      sm_size: 21
-      dim: 1
+- method: remove_all_stripe
+  module_path: tomopy.prep.stripe
+  parameters:
+    snr: 3
+    la_size: 61
+    sm_size: 21
+    dim: 1
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_dead_stripe.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_dead_stripe.yaml
index 33094ad5e..18dce1f5d 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_dead_stripe.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_dead_stripe.yaml
@@ -1,7 +1,6 @@
-- tomopy.prep.stripe:
-    remove_dead_stripe:
-      data_in: tomo
-      data_out: tomo
-      snr: 3
-      size: 51
-      norm: true
+- method: remove_dead_stripe
+  module_path: tomopy.prep.stripe
+  parameters:
+    snr: 3
+    size: 51
+    norm: true
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_large_stripe.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_large_stripe.yaml
index 527b15324..ca24d3a0a 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_large_stripe.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_large_stripe.yaml
@@ -1,8 +1,7 @@
-- tomopy.prep.stripe:
-    remove_large_stripe:
-      data_in: tomo
-      data_out: tomo
-      snr: 3
-      size: 51
-      drop_ratio: 0.1
-      norm: true
+- method: remove_large_stripe
+  module_path: tomopy.prep.stripe
+  parameters:
+    snr: 3
+    size: 51
+    drop_ratio: 0.1
+    norm: true
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_filtering.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_filtering.yaml
index 2de8496b5..ee584fb6f 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_filtering.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_filtering.yaml
@@ -1,7 +1,6 @@
-- tomopy.prep.stripe:
-    remove_stripe_based_filtering:
-      data_in: tomo
-      data_out: tomo
-      sigma: 3
-      size: null
-      dim: 1
+- method: remove_stripe_based_filtering
+  module_path: tomopy.prep.stripe
+  parameters:
+    sigma: 3
+    size: null
+    dim: 1
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_fitting.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_fitting.yaml
index 8b6db982c..9dc35b7a3 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_fitting.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_fitting.yaml
@@ -1,8 +1,7 @@
-- tomopy.prep.stripe:
-    remove_stripe_based_fitting:
-      data_in: tomo
-      data_out: tomo
-      order: 3
-      sigma: !!python/tuple
-      - 5
-      - 20
+- method: remove_stripe_based_fitting
+  module_path: tomopy.prep.stripe
+  parameters:
+    order: 3
+    sigma: !!python/tuple
+    - 5
+    - 20
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_interpolation.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_interpolation.yaml
index d8b004d5f..29f7a6c59 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_interpolation.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_interpolation.yaml
@@ -1,8 +1,7 @@
-- tomopy.prep.stripe:
-    remove_stripe_based_interpolation:
-      data_in: tomo
-      data_out: tomo
-      snr: 3
-      size: 31
-      drop_ratio: 0.1
-      norm: true
+- method: remove_stripe_based_interpolation
+  module_path: tomopy.prep.stripe
+  parameters:
+    snr: 3
+    size: 31
+    drop_ratio: 0.1
+    norm: true
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_sorting.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_sorting.yaml
index 3d0ec0377..f5f8d799a 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_sorting.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_based_sorting.yaml
@@ -1,6 +1,5 @@
-- tomopy.prep.stripe:
-    remove_stripe_based_sorting:
-      data_in: tomo
-      data_out: tomo
-      size: null
-      dim: 1
+- method: remove_stripe_based_sorting
+  module_path: tomopy.prep.stripe
+  parameters:
+    size: null
+    dim: 1
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_fw.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_fw.yaml
index 0d800889c..5aa654390 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_fw.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_fw.yaml
@@ -1,8 +1,7 @@
-- tomopy.prep.stripe:
-    remove_stripe_fw:
-      data_in: tomo
-      data_out: tomo
-      level: null
-      wname: db5
-      sigma: 2
-      pad: true
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_sf.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_sf.yaml
index 4fd3c71b2..c63f6f006 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_sf.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_sf.yaml
@@ -1,5 +1,4 @@
-- tomopy.prep.stripe:
-    remove_stripe_sf:
-      data_in: tomo
-      data_out: tomo
-      size: 5
+- method: remove_stripe_sf
+  module_path: tomopy.prep.stripe
+  parameters:
+    size: 5
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_ti.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_ti.yaml
index 42756feab..3a0152b56 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_ti.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/remove_stripe_ti.yaml
@@ -1,6 +1,5 @@
-- tomopy.prep.stripe:
-    remove_stripe_ti:
-      data_in: tomo
-      data_out: tomo
-      nblock: 0
-      alpha: 1.5
+- method: remove_stripe_ti
+  module_path: tomopy.prep.stripe
+  parameters:
+    nblock: 0
+    alpha: 1.5
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/stripes_detect3d.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/stripes_detect3d.yaml
index 8024e378a..e00632891 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/stripes_detect3d.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/stripes_detect3d.yaml
@@ -1,6 +1,5 @@
-- tomopy.prep.stripe:
-    stripes_detect3d:
-      data_in: tomo
-      data_out: tomo
-      size: 10
-      radius: 3
+- method: stripes_detect3d
+  module_path: tomopy.prep.stripe
+  parameters:
+    size: 10
+    radius: 3
diff --git a/templates/tomopy/1.14/tomopy.prep.stripe/stripes_mask3d.yaml b/templates/tomopy/1.14/tomopy.prep.stripe/stripes_mask3d.yaml
index 34b5bebf4..198549b37 100644
--- a/templates/tomopy/1.14/tomopy.prep.stripe/stripes_mask3d.yaml
+++ b/templates/tomopy/1.14/tomopy.prep.stripe/stripes_mask3d.yaml
@@ -1,10 +1,9 @@
-- tomopy.prep.stripe:
-    stripes_mask3d:
-      data_in: tomo
-      data_out: tomo
-      weights: REQUIRED
-      threshold: 0.6
-      min_stripe_length: 20
-      min_stripe_depth: 10
-      min_stripe_width: 5
-      sensitivity_perc: 85.0
+- method: stripes_mask3d
+  module_path: tomopy.prep.stripe
+  parameters:
+    weights: REQUIRED
+    threshold: 0.6
+    min_stripe_length: 20
+    min_stripe_depth: 10
+    min_stripe_width: 5
+    sensitivity_perc: 85.0
diff --git a/templates/tomopy/1.14/tomopy.recon.algorithm/init_tomo.yaml b/templates/tomopy/1.14/tomopy.recon.algorithm/init_tomo.yaml
new file mode 100644
index 000000000..c2efca89c
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.recon.algorithm/init_tomo.yaml
@@ -0,0 +1,5 @@
+- method: init_tomo
+  module_path: tomopy.recon.algorithm
+  parameters:
+    sinogram_order: REQUIRED
+    sharedmem: true
diff --git a/templates/tomopy/1.14/tomopy.recon.algorithm/recon.yaml b/templates/tomopy/1.14/tomopy.recon.algorithm/recon.yaml
index 1c97d485b..b1b2972e9 100644
--- a/templates/tomopy/1.14/tomopy.recon.algorithm/recon.yaml
+++ b/templates/tomopy/1.14/tomopy.recon.algorithm/recon.yaml
@@ -1,9 +1,8 @@
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: null
-      sinogram_order: false
-      algorithm: null
-      init_recon: null
-      '#additional parameters': AVAILABLE
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: null
+    init_recon: null
+    #additional parameters: AVAILABLE
diff --git a/templates/tomopy/1.14/tomopy.recon.rotation/find_center.yaml b/templates/tomopy/1.14/tomopy.recon.rotation/find_center.yaml
index b4b94714f..fb2b45dc7 100644
--- a/templates/tomopy/1.14/tomopy.recon.rotation/find_center.yaml
+++ b/templates/tomopy/1.14/tomopy.recon.rotation/find_center.yaml
@@ -1,14 +1,15 @@
-- tomopy.recon.rotation:
-    find_center:
-      data_in: tomo
-      data_out:
-      - cor
-      - overlap
-      - side
-      - overlap_position
-      ind: null
-      init: null
-      tol: 0.5
-      mask: true
-      ratio: 1.0
-      sinogram_order: false
+- method: find_center
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: null
+    init: null
+    tol: 0.5
+    mask: true
+    ratio: 1.0
+    sinogram_order: false
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+    overlap: overlap
+    side: side
+    overlap_position: overlap_position
diff --git a/templates/tomopy/1.14/tomopy.recon.rotation/find_center_pc.yaml b/templates/tomopy/1.14/tomopy.recon.rotation/find_center_pc.yaml
index d13373a73..30961eea3 100644
--- a/templates/tomopy/1.14/tomopy.recon.rotation/find_center_pc.yaml
+++ b/templates/tomopy/1.14/tomopy.recon.rotation/find_center_pc.yaml
@@ -1,8 +1,7 @@
-- tomopy.recon.rotation:
-    find_center_pc:
-      data_in: tomo
-      data_out: tomo
-      proj1: REQUIRED
-      proj2: REQUIRED
-      tol: 0.5
-      rotc_guess: null
+- method: find_center_pc
+  module_path: tomopy.recon.rotation
+  parameters:
+    proj1: REQUIRED
+    proj2: REQUIRED
+    tol: 0.5
+    rotc_guess: null
diff --git a/templates/tomopy/1.14/tomopy.recon.rotation/find_center_vo.yaml b/templates/tomopy/1.14/tomopy.recon.rotation/find_center_vo.yaml
index 78ada91d5..1e213797c 100644
--- a/templates/tomopy/1.14/tomopy.recon.rotation/find_center_vo.yaml
+++ b/templates/tomopy/1.14/tomopy.recon.rotation/find_center_vo.yaml
@@ -1,11 +1,13 @@
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: null
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: null
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
diff --git a/templates/tomopy/1.14/tomopy.recon.rotation/mask_empty_slice.yaml b/templates/tomopy/1.14/tomopy.recon.rotation/mask_empty_slice.yaml
new file mode 100644
index 000000000..4d623bf61
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.recon.rotation/mask_empty_slice.yaml
@@ -0,0 +1,4 @@
+- method: mask_empty_slice
+  module_path: tomopy.recon.rotation
+  parameters:
+    threshold: 0.25
diff --git a/templates/tomopy/1.14/tomopy.recon.rotation/write_center.yaml b/templates/tomopy/1.14/tomopy.recon.rotation/write_center.yaml
index 33e5d6448..dc7b2bb5b 100644
--- a/templates/tomopy/1.14/tomopy.recon.rotation/write_center.yaml
+++ b/templates/tomopy/1.14/tomopy.recon.rotation/write_center.yaml
@@ -1,12 +1,11 @@
-- tomopy.recon.rotation:
-    write_center:
-      data_in: tomo
-      data_out: tomo
-      dpath: tmp/center
-      cen_range: null
-      ind: null
-      mask: false
-      ratio: 1.0
-      sinogram_order: false
-      algorithm: gridrec
-      filter_name: parzen
+- method: write_center
+  module_path: tomopy.recon.rotation
+  parameters:
+    dpath: tmp/center
+    cen_range: null
+    ind: null
+    mask: false
+    ratio: 1.0
+    sinogram_order: false
+    algorithm: gridrec
+    filter_name: parzen
diff --git a/templates/tomopy/1.14/tomopy.sim.project/add_drift.yaml b/templates/tomopy/1.14/tomopy.sim.project/add_drift.yaml
index acbd29af5..5535fdd2d 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/add_drift.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/add_drift.yaml
@@ -1,7 +1,6 @@
-- tomopy.sim.project:
-    add_drift:
-      data_in: tomo
-      data_out: tomo
-      amp: 0.2
-      period: 50
-      mean: 1
+- method: add_drift
+  module_path: tomopy.sim.project
+  parameters:
+    amp: 0.2
+    period: 50
+    mean: 1
diff --git a/templates/tomopy/1.14/tomopy.sim.project/add_focal_spot_blur.yaml b/templates/tomopy/1.14/tomopy.sim.project/add_focal_spot_blur.yaml
index 123a543c4..64c99c66e 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/add_focal_spot_blur.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/add_focal_spot_blur.yaml
@@ -1,5 +1,4 @@
-- tomopy.sim.project:
-    add_focal_spot_blur:
-      data_in: tomo
-      data_out: tomo
-      spotsize: REQUIRED
+- method: add_focal_spot_blur
+  module_path: tomopy.sim.project
+  parameters:
+    spotsize: REQUIRED
diff --git a/templates/tomopy/1.14/tomopy.sim.project/add_gaussian.yaml b/templates/tomopy/1.14/tomopy.sim.project/add_gaussian.yaml
index 3869dcfce..e9b7031b8 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/add_gaussian.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/add_gaussian.yaml
@@ -1,6 +1,5 @@
-- tomopy.sim.project:
-    add_gaussian:
-      data_in: tomo
-      data_out: tomo
-      mean: 0
-      std: null
+- method: add_gaussian
+  module_path: tomopy.sim.project
+  parameters:
+    mean: 0
+    std: null
diff --git a/templates/tomopy/1.14/tomopy.sim.project/add_poisson.yaml b/templates/tomopy/1.14/tomopy.sim.project/add_poisson.yaml
index 141ab753b..4c68479d0 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/add_poisson.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/add_poisson.yaml
@@ -1,4 +1,3 @@
-- tomopy.sim.project:
-    add_poisson:
-      data_in: tomo
-      data_out: tomo
+- method: add_poisson
+  module_path: tomopy.sim.project
+  parameters: {}
diff --git a/templates/tomopy/1.14/tomopy.sim.project/add_rings.yaml b/templates/tomopy/1.14/tomopy.sim.project/add_rings.yaml
index 4fdb843ab..a96c6cb8f 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/add_rings.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/add_rings.yaml
@@ -1,5 +1,4 @@
-- tomopy.sim.project:
-    add_rings:
-      data_in: tomo
-      data_out: tomo
-      std: 0.05
+- method: add_rings
+  module_path: tomopy.sim.project
+  parameters:
+    std: 0.05
diff --git a/templates/tomopy/1.14/tomopy.sim.project/add_salt_pepper.yaml b/templates/tomopy/1.14/tomopy.sim.project/add_salt_pepper.yaml
index eaa1d4e5e..9777ac341 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/add_salt_pepper.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/add_salt_pepper.yaml
@@ -1,6 +1,5 @@
-- tomopy.sim.project:
-    add_salt_pepper:
-      data_in: tomo
-      data_out: tomo
-      prob: 0.01
-      val: null
+- method: add_salt_pepper
+  module_path: tomopy.sim.project
+  parameters:
+    prob: 0.01
+    val: null
diff --git a/templates/tomopy/1.14/tomopy.sim.project/add_zingers.yaml b/templates/tomopy/1.14/tomopy.sim.project/add_zingers.yaml
index 8c228a4c9..5048a4c7e 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/add_zingers.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/add_zingers.yaml
@@ -1,6 +1,5 @@
-- tomopy.sim.project:
-    add_zingers:
-      data_in: tomo
-      data_out: tomo
-      f: 0.01
-      sat: 65536
+- method: add_zingers
+  module_path: tomopy.sim.project
+  parameters:
+    f: 0.01
+    sat: 65536
diff --git a/templates/tomopy/1.14/tomopy.sim.project/angles.yaml b/templates/tomopy/1.14/tomopy.sim.project/angles.yaml
new file mode 100644
index 000000000..dd5e94636
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.sim.project/angles.yaml
@@ -0,0 +1,6 @@
+- method: angles
+  module_path: tomopy.sim.project
+  parameters:
+    nang: REQUIRED
+    ang1: 0.0
+    ang2: 180.0
diff --git a/templates/tomopy/1.14/tomopy.sim.project/fan_to_para.yaml b/templates/tomopy/1.14/tomopy.sim.project/fan_to_para.yaml
new file mode 100644
index 000000000..dd7eb3fe3
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.sim.project/fan_to_para.yaml
@@ -0,0 +1,5 @@
+- method: fan_to_para
+  module_path: tomopy.sim.project
+  parameters:
+    dist: REQUIRED
+    geom: REQUIRED
diff --git a/templates/tomopy/1.14/tomopy.sim.project/para_to_fan.yaml b/templates/tomopy/1.14/tomopy.sim.project/para_to_fan.yaml
new file mode 100644
index 000000000..3fec2dc88
--- /dev/null
+++ b/templates/tomopy/1.14/tomopy.sim.project/para_to_fan.yaml
@@ -0,0 +1,5 @@
+- method: para_to_fan
+  module_path: tomopy.sim.project
+  parameters:
+    dist: REQUIRED
+    geom: REQUIRED
diff --git a/templates/tomopy/1.14/tomopy.sim.project/project.yaml b/templates/tomopy/1.14/tomopy.sim.project/project.yaml
index 7efc08e44..ed843f1a5 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/project.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/project.yaml
@@ -1,9 +1,8 @@
-- tomopy.sim.project:
-    project:
-      data_in: tomo
-      data_out: tomo
-      obj: REQUIRED
-      center: null
-      emission: true
-      pad: true
-      sinogram_order: false
+- method: project
+  module_path: tomopy.sim.project
+  parameters:
+    obj: REQUIRED
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    emission: true
+    pad: true
+    sinogram_order: false
diff --git a/templates/tomopy/1.14/tomopy.sim.project/project2.yaml b/templates/tomopy/1.14/tomopy.sim.project/project2.yaml
index 773a827a1..562321403 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/project2.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/project2.yaml
@@ -1,11 +1,10 @@
-- tomopy.sim.project:
-    project2:
-      data_in: tomo
-      data_out: tomo
-      objx: REQUIRED
-      objy: REQUIRED
-      center: null
-      emission: true
-      pad: true
-      sinogram_order: false
-      axis: 0
+- method: project2
+  module_path: tomopy.sim.project
+  parameters:
+    objx: REQUIRED
+    objy: REQUIRED
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    emission: true
+    pad: true
+    sinogram_order: false
+    axis: 0
diff --git a/templates/tomopy/1.14/tomopy.sim.project/project3.yaml b/templates/tomopy/1.14/tomopy.sim.project/project3.yaml
index fec2ae8d7..6bc3cde1e 100644
--- a/templates/tomopy/1.14/tomopy.sim.project/project3.yaml
+++ b/templates/tomopy/1.14/tomopy.sim.project/project3.yaml
@@ -1,12 +1,11 @@
-- tomopy.sim.project:
-    project3:
-      data_in: tomo
-      data_out: tomo
-      objx: REQUIRED
-      objy: REQUIRED
-      objz: REQUIRED
-      center: null
-      emission: true
-      pad: true
-      sinogram_order: false
-      axis: 0
+- method: project3
+  module_path: tomopy.sim.project
+  parameters:
+    objx: REQUIRED
+    objy: REQUIRED
+    objz: REQUIRED
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    emission: true
+    pad: true
+    sinogram_order: false
+    axis: 0
diff --git a/templates/yaml_templates_generator.py b/templates/yaml_templates_generator.py
index 8372a9570..f6eab4361 100644
--- a/templates/yaml_templates_generator.py
+++ b/templates/yaml_templates_generator.py
@@ -15,9 +15,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # ---------------------------------------------------------------------------
-# Created By  : Daniil Kazantsev <scientificsoftware@diamond.ac.uk>
+# Created By  : Tomography Team <scientificsoftware@diamond.ac.uk>
 # Created Date: 14/October/2022
-# version ='0.2'
+# version ='0.3'
 # ---------------------------------------------------------------------------
 """Script that exposes all functions of a given software package as YAML templates.
 
@@ -29,6 +29,7 @@
 import inspect
 import os
 import re
+from typing import List, Dict
 
 import yaml
 
@@ -37,37 +38,14 @@ def yaml_generator(path_to_modules: str, output_folder: str) -> int:
     """function that exposes all method of a given software package as YAML templates
 
     Args:
-        path_to_modules (str): path to the list of modules yaml file
-        output_folder (str): path to output folder with saved templates
+        path_to_modules: path to the list of modules yaml file
+        output_folder: path to output folder with saved templates
 
     Returns:
-        int: returns zero if the processing is succesfull
+        returns zero if the processing is succesfull
     """
-    # Can work with any software in principle,
-    # but for TomoPy and httomolib there are additional keys
-    # that needed to be discarded in templates in order to let
-    # httomo work smoothly.
-    discard_keys = [
-        "tomo",
-        "arr",
-        "prj",
-        "data",
-        "ncore",
-        "nchunk",
-        "flats",
-        "flat",
-        "dark",
-        "darks",
-        "theta",
-        "out",
-        "ang",        
-        "comm_rank",
-        "out_dir",
-        "angles",
-        "gpu_id",
-    ]  # discard from parameters list
-
-    no_data_out_modules = ["save_to_images"]  # discard data_out from certain modules
+    discard_keys = _get_discard_keys()
+    no_data_out_modules = _get_discard_data_out()
 
     # open YAML file with modules to inspect
     with open(path_to_modules, "r") as stream:
@@ -97,16 +75,8 @@ def yaml_generator(path_to_modules: str, output_folder: str) -> int:
             get_method_docs = inspect.getdoc(getattr(imported_module, methods_list[m]))
 
             # put the parameters in the dictionary
-            params_list: list = []
-            params_dict: dict = {}
-            params_dict["data_in"] = "tomo"  # default dataset names
-            # dealing with special cases for "data_out"
-            if method_name not in no_data_out_modules:
-                params_dict["data_out"] = "tomo"
-            if method_name in "find_center_vo":
-                params_dict["data_out"] = "cor"
-            if method_name in "find_center_360":
-                params_dict["data_out"] = ["cor", "overlap", "side", "overlap_position"]
+            params_list: List = []
+            params_dict: Dict = {}
             for k, v in get_method_params.parameters.items():
                 if v is not None:
                     append = True
@@ -115,25 +85,112 @@ def yaml_generator(path_to_modules: str, output_folder: str) -> int:
                             append = False
                             break
                     if append:
-                        if str(v).find("=") == -1 and str(k) != "kwargs":
-                            params_dict[str(k)] = "REQUIRED"
-                        elif str(k) == "kwargs":
-                            params_dict["#additional parameters"] = "AVAILABLE"
-                        else:
-                            params_dict[str(k)] = v.default
+                        _set_param_value(k, v, params_dict)
+            method_dict = {
+                "method": method_name,
+                "module_path": module_name,
+                "parameters": params_dict,
+            }
+            _set_dict_special_cases(method_dict, method_name)
+            params_list = [method_dict]
+            _save_yaml(module_name, method_name, params_list)
+    return 0
 
-            params_list = [{module_name: {method_name: params_dict}}]
 
-            # save the list as a YAML file
-            path_dir = output_folder + "/" + module_name
-            path_file = path_dir + "/" + str(method_name) + ".yaml"
+def _set_param_value(k: int, v: int, params_dict: Dict):
+    """Set param value for method inside dictionary
+    Args:
+        k: Method name, dict key
+        v: Method value, dict value
+        params_dict: Parameter dictionary
+    """
+    if str(v).find("=") == -1 and str(k) != "kwargs":
+        params_dict[str(k)] = "REQUIRED"
+    elif str(k) == "kwargs":
+        params_dict["#additional parameters"] = "AVAILABLE"
+    elif str(k) == "center":
+        # Temporary value
+        params_dict[str(k)] = "${{centering.side_outputs.centre_of_rotation}}"
+    else:
+        params_dict[str(k)] = v.default
+
+
+def _save_yaml(module_name: str, method_name: str, params_list: List[str]):
+    """Save the list as a YAML file
+    Args:
+        module_name: Name of module
+        method_name: Name of method
+        params_list: List of parameters
+    """
+    path_dir = output_folder + "/" + module_name
+    path_file = path_dir + "/" + str(method_name) + ".yaml"
 
-            if not os.path.exists(path_dir):
-                os.makedirs(path_dir)
+    if not os.path.exists(path_dir):
+        os.makedirs(path_dir)
 
-            with open(path_file, "w") as file:
-                outputs = yaml.dump(params_list, file, sort_keys=False)
-    return 0
+    with open(path_file, "w") as file:
+        outputs = yaml.dump(params_list, file, sort_keys=False)
+
+
+def _set_dict_special_cases(method_dict: Dict, method_name: str):
+    """Dealing with special cases for "data_out"
+
+    Args:
+        method_dict: Dictionary of modules and parameters
+        method_name: Name of method
+    """
+    if method_name in "find_center_vo":
+        method_dict["id"] = "centering"
+        method_dict["side_outputs"] = {"cor": "centre_of_rotation"}
+    if method_name in "find_center_360":
+        method_dict["id"] = "centering"
+        method_dict["side_outputs"] = {
+            "centre_of_rotation": "cor",
+            "overlap": "overlap",
+            "side": "side",
+            "overlap_position": "overlap_position",
+        }
+
+
+def _get_discard_data_out() -> List[str]:
+    """Discard data_out from certain modules
+
+    Returns: list of data_out to discard
+    """
+    discard_data_out = ["save_to_images"]
+    return discard_data_out
+
+
+def _get_discard_keys() -> List[str]:
+    """Can work with any software in principle,
+    but for TomoPy and httomolib there are additional keys
+    that needed to be discarded in templates in order to let
+    httomo work smoothly.
+
+    Returns: List of keys to discard
+    """
+    discard_keys = [
+        "data_in",
+        "tomo",
+        "arr",
+        "prj",
+        "data",
+        "ncore",
+        "nchunk",
+        "flats",
+        "flat",
+        "dark",
+        "darks",
+        "theta",
+        "out",
+        "ang",
+        "comm_rank",
+        "out_dir",
+        "angles",
+        "gpu_id",
+        "comm"
+    ]
+    return discard_keys
 
 
 def get_args():


Test patch:
diff --git a/samples/pipeline_template_examples/testing/empty_loader_stage.yaml b/samples/pipeline_template_examples/testing/empty_loader_stage.yaml
index 8acadcc42..aadfb12ad 100644
--- a/samples/pipeline_template_examples/testing/empty_loader_stage.yaml
+++ b/samples/pipeline_template_examples/testing/empty_loader_stage.yaml
@@ -1,54 +1,53 @@
 --- # loading
 --- # pre-processing
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
 --- # main processing
-- tomopy.prep.stripe:
-    remove_stripe_fw:
-      data_in: tomo
-      data_out: tomo
-      level: null
-      wname: db5
-      sigma: 2
-      pad: true
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
-      save_result: true
-      #additional parameters': AVAILABLE
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 1
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
-      glob_stats: true
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    save_result: true
+    #additional parameters: AVAILABLE
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 1
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: true
 
 
diff --git a/samples/pipeline_template_examples/testing/incorrect_method.yaml b/samples/pipeline_template_examples/testing/incorrect_method.yaml
index 79de7e3fc..b838fbf67 100644
--- a/samples/pipeline_template_examples/testing/incorrect_method.yaml
+++ b/samples/pipeline_template_examples/testing/incorrect_method.yaml
@@ -1,25 +1,29 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detector/image_key
-      preview:
-        - 
-        - start: 30
-          stop: 60
-        - 
-      pad: 0
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview:
+      -
+      - start: 30
+        stop: 60
+      -
+    pad: 0
 --- # pre-processing
-- tomopy.misc.corr:
-    median_filters:
-      data: tomo
-      data_out: tomo
-      size: tomo
-      axis: 0
+- method: median_filters # incorrect method name
+  module_path: tomopy.misc.corr
+  parameters:
+    size: tomo # incorrect size parameter
+    axis: 0
 --- # main processing
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
diff --git a/samples/pipeline_template_examples/testing/incorrect_path.yaml b/samples/pipeline_template_examples/testing/incorrect_path.yaml
index 685cb8a6f..7323a1d1a 100644
--- a/samples/pipeline_template_examples/testing/incorrect_path.yaml
+++ b/samples/pipeline_template_examples/testing/incorrect_path.yaml
@@ -1,20 +1,26 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detect/image_key
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detect/image_key #incorrect path
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview: [None, None, None]
+    pad: 0
 --- # pre-processing
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
 --- # main processing
-- tomopy.prep.stripe:
-    remove_stripe_fw:
-      data_in: tomo
-      data_out: tomo
-      level: null
-      wname: db5
-      sigma: 2
-      pad: true
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
+
diff --git a/samples/pipeline_template_examples/testing/invalid_loader_stage.yaml b/samples/pipeline_template_examples/testing/invalid_loader_stage.yaml
index 2dccbe04e..07c4cb7ba 100644
--- a/samples/pipeline_template_examples/testing/invalid_loader_stage.yaml
+++ b/samples/pipeline_template_examples/testing/invalid_loader_stage.yaml
@@ -1,60 +1,63 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry1/tomo_entry/data/data
-      image_key_path: /entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      pad: 0
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: /entry1/tomo_entry/data/data
+    image_key_path: /entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    pad: 0
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
 --- # pre-processing
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
 --- # main processing
-- tomopy.prep.stripe:
-    remove_stripe_fw:
-      data_in: tomo
-      data_out: tomo
-      level: null
-      wname: db5
-      sigma: 2
-      pad: true
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
-      save_result: true
-      #additional parameters': AVAILABLE
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 1
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
-      glob_stats: true
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    save_result: true
+    #additional parameters': AVAILABLE
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: true
 
diff --git a/samples/pipeline_template_examples/testing/missing_loader_stage.yaml b/samples/pipeline_template_examples/testing/missing_loader_stage.yaml
index f523fd346..1a01eadb3 100644
--- a/samples/pipeline_template_examples/testing/missing_loader_stage.yaml
+++ b/samples/pipeline_template_examples/testing/missing_loader_stage.yaml
@@ -1,52 +1,51 @@
 --- # pre-processing
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
 --- # main processing
-- tomopy.prep.stripe:
-    remove_stripe_fw:
-      data_in: tomo
-      data_out: tomo
-      level: null
-      wname: db5
-      sigma: 2
-      pad: true
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
-      save_result: true
-      #additional parameters': AVAILABLE
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 1
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
-      glob_stats: true
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    save_result: true
+    #additional parameters': AVAILABLE
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 1
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: true
 
diff --git a/samples/pipeline_template_examples/testing/more_than_one_method.yaml b/samples/pipeline_template_examples/testing/more_than_one_method.yaml
index baf91e48c..ed7f48c89 100644
--- a/samples/pipeline_template_examples/testing/more_than_one_method.yaml
+++ b/samples/pipeline_template_examples/testing/more_than_one_method.yaml
@@ -1,24 +1,30 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: entry1/tomo_entry/data/data
-      image_key_path: entry1/tomo_entry/instrument/detector/image_key
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview: [None, None, None]
+    pad: 0
 --- # pre-processing
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-    minus_log:
-      data_in: tomo
-      data_out: tomo
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+  method: minus_log # more than one method
+  module_path: tomopy.prep.normalize
+  parameters: {}
 --- # main processing
-- tomopy.prep.stripe:
-    remove_stripe_fw:
-      data_in: tomo
-      data_out: tomo
-      level: null
-      wname: db5
-      sigma: 2
-      pad: true
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
diff --git a/samples/pipeline_template_examples/testing/required_param.yaml b/samples/pipeline_template_examples/testing/required_param.yaml
index 9f6f69c48..ddc0ff13e 100644
--- a/samples/pipeline_template_examples/testing/required_param.yaml
+++ b/samples/pipeline_template_examples/testing/required_param.yaml
@@ -1,25 +1,29 @@
 --- # loading
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry1/tomo_entry/data/data
-      image_key_path: /entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      pad: 0
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: /entry1/tomo_entry/data/data
+    image_key_path: /entry1/tomo_entry/instrument/detector/image_key
+    # rotation_angles:
+    #        data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    # preview: [None, None, None]
+    pad: 0
 --- # pre-processing
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
 --- # main processing
-- tomopy.prep.stripe:
-    stripes_mask3d:
-      data_in: tomo
-      data_out: tomo
-      weights: REQUIRED
-      threshold: 0.6
-      min_stripe_length: 20
-      min_stripe_depth: 10
-      min_stripe_width: 5
-      sensitivity_perc: 85.0
+- method: stripes_mask3d
+  module_path: tomopy.prep.stripe
+  parameters:
+    weights: REQUIRED
+    threshold: 0.6
+    min_stripe_length: 20
+    min_stripe_depth: 10
+    min_stripe_width: 5
+    sensitivity_perc: 85.0
diff --git a/samples/pipeline_template_examples/testing/step_absent.yml b/samples/pipeline_template_examples/testing/step_absent.yml
index da1cc2e3d..226b9a782 100644
--- a/samples/pipeline_template_examples/testing/step_absent.yml
+++ b/samples/pipeline_template_examples/testing/step_absent.yml
@@ -1,17 +1,21 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry1/tomo_entry/data/data
-      image_key_path: /entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      pad: 0
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: !SweepRange
-        start: 10
-        stop: 50
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: /entry1/tomo_entry/data/data
+    image_key_path: /entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    # preview: [None, None, None]
+    pad: 0
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: !SweepRange
+      start: 10
+      stop: 50
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
diff --git a/samples/pipeline_template_examples/testing/sweep_testing_pipeline.yaml b/samples/pipeline_template_examples/testing/sweep_testing_pipeline.yaml
index 97ea60434..6e87be095 100644
--- a/samples/pipeline_template_examples/testing/sweep_testing_pipeline.yaml
+++ b/samples/pipeline_template_examples/testing/sweep_testing_pipeline.yaml
@@ -1,10 +1,15 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-      name: tomo
-      data_path: /entry1/tomo_entry/data/data
-      image_key_path: /entry1/tomo_entry/instrument/detector/image_key
-      dimension: 1
-      pad: 0
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+    in_file: tests/test_data/tomo_standard.nxs
+    data_path: entry1/tomo_entry/data/data
+    image_key_path: entry1/tomo_entry/instrument/detector/image_key
+    rotation_angles:
+      data_path: /entry1/tomo_entry/data/rotation_angle
+    dimension: 1
+    preview: [None, None, None]
+    pad: 0
 - tomopy.misc.corr:
     median_filter:
       data_in: tomo
@@ -13,8 +18,9 @@
         - 3
         - 5
       axis: 0
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: 10.0
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: 10.0
+    averaging: mean
+
diff --git a/samples/pipeline_template_examples/testing/testing_pipeline.yaml b/samples/pipeline_template_examples/testing/testing_pipeline.yaml
index 5ce7656d3..93349c67d 100644
--- a/samples/pipeline_template_examples/testing/testing_pipeline.yaml
+++ b/samples/pipeline_template_examples/testing/testing_pipeline.yaml
@@ -1,51 +1,50 @@
 --- # pre-processing
-- tomopy.recon.rotation:
-    find_center_vo:
-      data_in: tomo
-      data_out: cor
-      ind: mid
-      smin: -50
-      smax: 50
-      srad: 6
-      step: 0.25
-      ratio: 0.5
-      drop: 20
+- method: find_center_vo
+  module_path: tomopy.recon.rotation
+  parameters:
+    ind: mid
+    smin: -50
+    smax: 50
+    srad: 6
+    step: 0.25
+    ratio: 0.5
+    drop: 20
+  id: centering
+  side_outputs:
+    cor: centre_of_rotation
 --- # main processing
-- tomopy.prep.normalize:
-    normalize:
-      data_in: tomo
-      data_out: tomo
-      cutoff: null
-- tomopy.prep.normalize:
-    minus_log:
-      data_in: tomo
-      data_out: tomo
-- tomopy.prep.stripe:
-    remove_stripe_fw:
-      data_in: tomo
-      data_out: tomo
-      level: null
-      wname: db5
-      sigma: 2
-      pad: true
-- tomopy.recon.algorithm:
-    recon:
-      data_in: tomo
-      data_out: tomo
-      center: cor
-      sinogram_order: false
-      algorithm: gridrec
-      init_recon: null
-      save_result: true
-      #additional parameters': AVAILABLE
-- httomolib.misc.images:
-    save_to_images:
-      data_in: tomo
-      subfolder_name: images
-      axis: 1
-      file_format: tif
-      bits: 8
-      perc_range_min: 0.0
-      perc_range_max: 100.0
-      jpeg_quality: 95
-      glob_stats: true
+- method: normalize
+  module_path: tomopy.prep.normalize
+  parameters:
+    cutoff: null
+    averaging: mean
+- method: minus_log
+  module_path: tomopy.prep.normalize
+  parameters: {}
+- method: remove_stripe_fw
+  module_path: tomopy.prep.stripe
+  parameters:
+    level: null
+    wname: db5
+    sigma: 2
+    pad: true
+- method: recon
+  module_path: tomopy.recon.algorithm
+  parameters:
+    center: ${{centering.side_outputs.centre_of_rotation}}
+    sinogram_order: false
+    algorithm: gridrec
+    init_recon: null
+    save_result: true
+    #additional parameters': AVAILABLE
+- method: save_to_images
+  module_path: httomolib.misc.images
+  parameters:
+    subfolder_name: images
+    axis: 0
+    file_format: tif
+    bits: 8
+    perc_range_min: 0.0
+    perc_range_max: 100.0
+    jpeg_quality: 95
+    glob_stats: true
diff --git a/samples/pipeline_template_examples/testing/wrong_indentation_pipeline.yaml b/samples/pipeline_template_examples/testing/wrong_indentation_pipeline.yaml
index a559bee6f..cd9b62c38 100644
--- a/samples/pipeline_template_examples/testing/wrong_indentation_pipeline.yaml
+++ b/samples/pipeline_template_examples/testing/wrong_indentation_pipeline.yaml
@@ -1,7 +1,12 @@
-- httomo.data.hdf.loaders:
-    standard_tomo:
-        name: tomo
+- method: standard_tomo
+  module_path: httomo.data.hdf.loaders
+  parameters:
+    name: tomo
+      in_file: tests/test_data/tomo_standard.nxs
       data_path: /entry1/tomo_entry/data/data
       image_key_path: /entry1/tomo_entry/instrument/detector/image_key
+      rotation_angles:
+        data_path: /entry1/tomo_entry/data/rotation_angle
       dimension: 1
+      preview: [None, None, None]
       pad: 0
diff --git a/tests/conftest.py b/tests/conftest.py
index 3bc8fadc1..40ae2726e 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -76,8 +76,7 @@ def cmd():
 @pytest.fixture
 def standard_data():
     return "tests/test_data/tomo_standard.nxs"
-
-
+    
 @pytest.fixture(scope="session")
 def test_data_path():
     return os.path.join(CUR_DIR, "test_data")
@@ -220,11 +219,34 @@ def sample_pipelines():
 def gpu_pipeline():
     return "samples/pipeline_template_examples/03_basic_gpu_pipeline_tomo_standard.yaml"
 
+@pytest.fixture
+def python_pipeline1():
+    return "samples/python_templates/pipeline_cpu1.py"
+
+@pytest.fixture
+def python_pipeline2():
+    return "samples/python_templates/pipeline_cpu2.py"
+
+@pytest.fixture
+def python_pipeline3():
+    return "samples/python_templates/pipeline_gpu1.py"
+
+@pytest.fixture
+def yaml_pipeline1():
+    return "samples/pipeline_template_examples/pipeline_cpu1.yaml"
+
+@pytest.fixture
+def yaml_pipeline2():
+    return "samples/pipeline_template_examples/pipeline_cpu2.yaml"
+
+@pytest.fixture
+def yaml_pipeline3():
+    return "samples/pipeline_template_examples/pipeline_gpu1.yaml"
+
 @pytest.fixture(scope="session")
 def distortion_correction_path(test_data_path):
     return os.path.join(test_data_path, "distortion-correction")
 
-
 @pytest.fixture
 def merge_yamls():
     def _merge_yamls(*yamls) -> None:
diff --git a/tests/test_yaml_checker.py b/tests/test_yaml_checker.py
index 97559a812..009d6057f 100644
--- a/tests/test_yaml_checker.py
+++ b/tests/test_yaml_checker.py
@@ -7,7 +7,6 @@
 from httomo.yaml_checker import (
     check_all_stages_defined,
     check_all_stages_non_empty,
-    check_first_stage_has_loader,
     check_hdf5_paths_against_loader,
     check_loading_stage_one_method,
     check_methods_exist_in_templates,
@@ -58,15 +57,6 @@ def test_invalid_loader_stage(sample_pipelines, yaml_loader: type[YamlLoader]):
     assert not check_loading_stage_one_method(conf)
 
 
-def test_first_stage_has_loader(sample_pipelines, yaml_loader: type[YamlLoader]):
-    incorrect_first_stage_pipeline = (
-        sample_pipelines + "testing/incorrect_first_stage.yaml"
-    )
-    with open(incorrect_first_stage_pipeline, "r") as f:
-        conf = list(yaml.load_all(f, Loader=yaml_loader))
-    assert not check_first_stage_has_loader(conf)
-
-
 def test_one_method_per_module(more_than_one_method, yaml_loader: type[YamlLoader]):
     with open(more_than_one_method, "r") as f:
         conf = list(yaml.load_all(f, Loader=yaml_loader))
diff --git a/tests/ui/__init__.py b/tests/ui/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/ui/test_ui_layer_py.py b/tests/ui/test_ui_layer_py.py
new file mode 100644
index 000000000..bc0cbf352
--- /dev/null
+++ b/tests/ui/test_ui_layer_py.py
@@ -0,0 +1,125 @@
+from unittest import mock
+
+import numpy as np
+from mpi4py import MPI
+
+from httomo.ui_layer import UiLayer
+
+
+def test_pipeline_cpu1(standard_data, python_pipeline1):
+    """Testing existing python pipelines by reading them and generating Pipelines
+    """
+
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(python_pipeline1, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+
+    assert len(pipeline._methods) == 5
+    assert LayerUI.PipelineStageConfig[0]['method'] == 'standard_tomo'
+    assert LayerUI.PipelineStageConfig[0]['module_path'] == 'httomo.data.hdf.loaders'
+    assert LayerUI.PipelineStageConfig[1]['method'] == 'normalize'
+    assert LayerUI.PipelineStageConfig[1]['module_path'] == 'tomopy.prep.normalize'
+    assert LayerUI.PipelineStageConfig[2]['method'] == 'minus_log'
+    assert LayerUI.PipelineStageConfig[2]['module_path'] == 'tomopy.prep.normalize'
+    assert LayerUI.PipelineStageConfig[3]['method'] == 'find_center_vo'
+    assert LayerUI.PipelineStageConfig[3]['module_path'] == 'tomopy.recon.rotation'
+    assert LayerUI.PipelineStageConfig[3]['side_outputs'] == {'cor' : 'centre_of_rotation'}
+    assert LayerUI.PipelineStageConfig[4]['method'] == 'recon'
+    assert LayerUI.PipelineStageConfig[4]['module_path'] == 'tomopy.recon.algorithm'
+    assert LayerUI.PipelineStageConfig[5]['method'] == 'save_to_images'
+    assert LayerUI.PipelineStageConfig[5]['module_path'] == 'httomolib.misc.images'    
+
+def test_test_pipeline_cpu1_outref(standard_data, python_pipeline1):
+    """Testing OutputRef.
+    """
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(python_pipeline1, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+    
+    obj = LayerUI.PipelineStageConfig[4]['parameters']['center']
+    assert obj.mapped_output_name == 'centre_of_rotation'
+
+
+def test_pipeline_cpu2(standard_data, python_pipeline2):
+    """Testing existing python pipelines by reading them and generating Pipelines
+    """
+
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(python_pipeline2, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+
+    assert len(pipeline._methods) == 8
+    assert LayerUI.PipelineStageConfig[0]['method'] == 'standard_tomo'
+    assert LayerUI.PipelineStageConfig[0]['module_path'] == 'httomo.data.hdf.loaders'
+    assert LayerUI.PipelineStageConfig[0]['parameters']['preview'] == [None, {'start': 30, 'stop': 60}, None]
+    assert LayerUI.PipelineStageConfig[1]['method'] == 'find_center_vo'
+    assert LayerUI.PipelineStageConfig[1]['module_path'] == 'tomopy.recon.rotation'    
+    assert LayerUI.PipelineStageConfig[1]['side_outputs'] == {'cor' : 'centre_of_rotation'}
+    assert LayerUI.PipelineStageConfig[2]['method'] == 'remove_outlier'
+    assert LayerUI.PipelineStageConfig[2]['module_path'] == 'tomopy.misc.corr'    
+    assert LayerUI.PipelineStageConfig[3]['method'] == 'normalize'
+    assert LayerUI.PipelineStageConfig[3]['module_path'] == 'tomopy.prep.normalize'
+    assert LayerUI.PipelineStageConfig[4]['method'] == 'minus_log'
+    assert LayerUI.PipelineStageConfig[4]['module_path'] == 'tomopy.prep.normalize'
+    assert LayerUI.PipelineStageConfig[5]['method'] == 'remove_stripe_fw'
+    assert LayerUI.PipelineStageConfig[5]['module_path'] == 'tomopy.prep.stripe'
+    assert LayerUI.PipelineStageConfig[6]['method'] == 'recon'
+    assert LayerUI.PipelineStageConfig[6]['module_path'] == 'tomopy.recon.algorithm'
+    assert LayerUI.PipelineStageConfig[7]['method'] == 'median_filter'
+    assert LayerUI.PipelineStageConfig[7]['module_path'] == 'tomopy.misc.corr'
+    assert LayerUI.PipelineStageConfig[8]['method'] == 'save_to_images'
+    assert LayerUI.PipelineStageConfig[8]['module_path'] == 'httomolib.misc.images'
+
+
+def test_pipeline_cpu1_outref(standard_data, python_pipeline2):
+    """Testing OutputRef.
+    """
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(python_pipeline2, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+    
+    obj = LayerUI.PipelineStageConfig[6]['parameters']['center']
+    assert obj.mapped_output_name == 'centre_of_rotation'
+
+def test_pipeline_gpu1(standard_data, python_pipeline3):
+    """Testing existing python pipelines by reading them and generating Pipelines
+    """
+
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(python_pipeline3, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+
+    assert len(pipeline._methods) == 6
+    assert LayerUI.PipelineStageConfig[0]['method'] == 'standard_tomo'
+    assert LayerUI.PipelineStageConfig[0]['module_path'] == 'httomo.data.hdf.loaders'
+    assert LayerUI.PipelineStageConfig[0]['parameters']['preview'] == [None, None, None]
+    assert LayerUI.PipelineStageConfig[1]['method'] == 'find_center_vo'
+    assert LayerUI.PipelineStageConfig[1]['module_path'] == 'httomolibgpu.recon.rotation'    
+    assert LayerUI.PipelineStageConfig[1]['side_outputs'] == {'cor' : 'centre_of_rotation'}
+    assert LayerUI.PipelineStageConfig[2]['method'] == 'remove_outlier3d'
+    assert LayerUI.PipelineStageConfig[2]['module_path'] == 'httomolibgpu.misc.corr'    
+    assert LayerUI.PipelineStageConfig[3]['method'] == 'normalize'
+    assert LayerUI.PipelineStageConfig[3]['module_path'] == 'httomolibgpu.prep.normalize'
+    assert LayerUI.PipelineStageConfig[4]['method'] == 'remove_stripe_based_sorting'
+    assert LayerUI.PipelineStageConfig[4]['module_path'] == 'httomolibgpu.prep.stripe'
+    assert LayerUI.PipelineStageConfig[5]['method'] == 'FBP'
+    assert LayerUI.PipelineStageConfig[5]['module_path'] == 'httomolibgpu.recon.algorithm'
+    assert LayerUI.PipelineStageConfig[6]['method'] == 'save_to_images'
+    assert LayerUI.PipelineStageConfig[6]['module_path'] == 'httomolib.misc.images'
+
+
+def test_pipeline_gpu1_outref(standard_data, python_pipeline3):
+    """Testing OutputRef.
+    """
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(python_pipeline3, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+    
+    obj = LayerUI.PipelineStageConfig[5]['parameters']['center']
+    assert obj.mapped_output_name == 'centre_of_rotation'    
\ No newline at end of file
diff --git a/tests/ui/test_ui_layer_yaml.py b/tests/ui/test_ui_layer_yaml.py
new file mode 100644
index 000000000..abf7ecd36
--- /dev/null
+++ b/tests/ui/test_ui_layer_yaml.py
@@ -0,0 +1,129 @@
+from unittest import mock
+from pytest_mock import MockerFixture
+
+
+import numpy as np
+import pytest
+from mpi4py import MPI
+
+from httomo.ui_layer import UiLayer
+
+def test_pipeline_cpu1l(standard_data, yaml_pipeline1):
+    """Testing existing yaml pipelines by reading them and generating Pipelines
+    """
+
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(yaml_pipeline1, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+
+    assert len(pipeline._methods) == 5
+    assert LayerUI.PipelineStageConfig[0]['method'] == 'standard_tomo'
+    assert LayerUI.PipelineStageConfig[0]['module_path'] == 'httomo.data.hdf.loaders'
+    assert LayerUI.PipelineStageConfig[1]['method'] == 'normalize'
+    assert LayerUI.PipelineStageConfig[1]['module_path'] == 'tomopy.prep.normalize'
+    assert LayerUI.PipelineStageConfig[2]['method'] == 'minus_log'
+    assert LayerUI.PipelineStageConfig[2]['module_path'] == 'tomopy.prep.normalize'
+    assert LayerUI.PipelineStageConfig[3]['method'] == 'find_center_vo'
+    assert LayerUI.PipelineStageConfig[3]['module_path'] == 'tomopy.recon.rotation'
+    assert LayerUI.PipelineStageConfig[3]['side_outputs'] == {'cor' : 'centre_of_rotation'}
+    assert LayerUI.PipelineStageConfig[4]['method'] == 'recon'
+    assert LayerUI.PipelineStageConfig[4]['module_path'] == 'tomopy.recon.algorithm'
+    assert LayerUI.PipelineStageConfig[5]['method'] == 'save_to_images'
+    assert LayerUI.PipelineStageConfig[5]['module_path'] == 'httomolib.misc.images'
+
+
+def test_pipeline_cpu1_outref(standard_data, yaml_pipeline1):
+    """Testing OutputRef.
+    """
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(yaml_pipeline1, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+    
+    obj = LayerUI.PipelineStageConfig[4]['parameters']['center']
+    assert obj.mapped_output_name == 'centre_of_rotation'
+
+
+def test_pipeline_cpu2_yaml(standard_data, yaml_pipeline2):
+    """Testing existing python pipelines by reading them and generating Pipelines
+    """
+
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(yaml_pipeline2, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+
+    assert len(pipeline._methods) == 8
+    assert LayerUI.PipelineStageConfig[0]['method'] == 'standard_tomo'
+    assert LayerUI.PipelineStageConfig[0]['module_path'] == 'httomo.data.hdf.loaders'
+    assert LayerUI.PipelineStageConfig[0]['parameters']['preview'] == [None, {'start': 30, 'stop': 60}, None]
+    assert LayerUI.PipelineStageConfig[1]['method'] == 'find_center_vo'
+    assert LayerUI.PipelineStageConfig[1]['module_path'] == 'tomopy.recon.rotation'    
+    assert LayerUI.PipelineStageConfig[1]['side_outputs'] == {'cor' : 'centre_of_rotation'}
+    assert LayerUI.PipelineStageConfig[2]['method'] == 'remove_outlier'
+    assert LayerUI.PipelineStageConfig[2]['module_path'] == 'tomopy.misc.corr'    
+    assert LayerUI.PipelineStageConfig[3]['method'] == 'normalize'
+    assert LayerUI.PipelineStageConfig[3]['module_path'] == 'tomopy.prep.normalize'
+    assert LayerUI.PipelineStageConfig[4]['method'] == 'minus_log'
+    assert LayerUI.PipelineStageConfig[4]['module_path'] == 'tomopy.prep.normalize'
+    assert LayerUI.PipelineStageConfig[5]['method'] == 'remove_stripe_fw'
+    assert LayerUI.PipelineStageConfig[5]['module_path'] == 'tomopy.prep.stripe'
+    assert LayerUI.PipelineStageConfig[6]['method'] == 'recon'
+    assert LayerUI.PipelineStageConfig[6]['module_path'] == 'tomopy.recon.algorithm'
+    assert LayerUI.PipelineStageConfig[7]['method'] == 'median_filter'
+    assert LayerUI.PipelineStageConfig[7]['module_path'] == 'tomopy.misc.corr'
+    assert LayerUI.PipelineStageConfig[8]['method'] == 'save_to_images'
+    assert LayerUI.PipelineStageConfig[8]['module_path'] == 'httomolib.misc.images'
+
+
+def test_pipeline_cpu2_outref(standard_data, yaml_pipeline2):
+    """Testing OutputRef.
+    """
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(yaml_pipeline2, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+    
+    obj = LayerUI.PipelineStageConfig[6]['parameters']['center']
+    assert obj.mapped_output_name == 'centre_of_rotation' 
+
+
+def test_pipeline_gpu1(standard_data, yaml_pipeline3):
+    """Testing existing python pipelines by reading them and generating Pipelines
+    """
+
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(yaml_pipeline3, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+
+    assert len(pipeline._methods) == 6
+    assert LayerUI.PipelineStageConfig[0]['method'] == 'standard_tomo'
+    assert LayerUI.PipelineStageConfig[0]['module_path'] == 'httomo.data.hdf.loaders'
+    assert LayerUI.PipelineStageConfig[0]['parameters']['preview'] == [None, None, None]
+    assert LayerUI.PipelineStageConfig[1]['method'] == 'find_center_vo'
+    assert LayerUI.PipelineStageConfig[1]['module_path'] == 'httomolibgpu.recon.rotation'    
+    assert LayerUI.PipelineStageConfig[1]['side_outputs'] == {'cor' : 'centre_of_rotation'}
+    assert LayerUI.PipelineStageConfig[2]['method'] == 'remove_outlier3d'
+    assert LayerUI.PipelineStageConfig[2]['module_path'] == 'httomolibgpu.misc.corr'    
+    assert LayerUI.PipelineStageConfig[3]['method'] == 'normalize'
+    assert LayerUI.PipelineStageConfig[3]['module_path'] == 'httomolibgpu.prep.normalize'
+    assert LayerUI.PipelineStageConfig[4]['method'] == 'remove_stripe_based_sorting'
+    assert LayerUI.PipelineStageConfig[4]['module_path'] == 'httomolibgpu.prep.stripe'
+    assert LayerUI.PipelineStageConfig[5]['method'] == 'FBP'
+    assert LayerUI.PipelineStageConfig[5]['module_path'] == 'httomolibgpu.recon.algorithm'
+    assert LayerUI.PipelineStageConfig[6]['method'] == 'save_to_images'
+    assert LayerUI.PipelineStageConfig[6]['module_path'] == 'httomolib.misc.images'
+
+
+def test_pipeline_gpu1_outref(standard_data, yaml_pipeline3):
+    """Testing OutputRef.
+    """
+    comm = MPI.COMM_WORLD
+    LayerUI = UiLayer(yaml_pipeline3, standard_data, comm=comm)
+
+    pipeline = LayerUI.build_pipeline()
+    
+    obj = LayerUI.PipelineStageConfig[5]['parameters']['center']
+    assert obj.mapped_output_name == 'centre_of_rotation'