diff --git a/src/agora/io/signal.py b/src/agora/io/signal.py
index 20c7b950d3a3e4dbf1cb21dec29947467b938bd7..6b9457bd77b91d9303758168188603ce7d5b728f 100644
--- a/src/agora/io/signal.py
+++ b/src/agora/io/signal.py
@@ -9,6 +9,7 @@ import h5py
 import numpy as np
 import pandas as pd
 
+import aliby.global_parameters as global_parameters
 from agora.io.bridge import BridgeH5
 from agora.io.decorators import _first_arg_str_to_raw_df
 from agora.utils.indexing import validate_lineage
@@ -36,16 +37,7 @@ class Signal(BridgeH5):
             "cell_label",
             "mother_label",
         )
-        self.candidate_channels = (
-            "GFP",
-            "GFPFast",
-            "mCherry",
-            "Flavin",
-            "Citrine",
-            "mKO2",
-            "Cy5",
-            "pHluorin405",
-        )
+        self.candidate_channels = global_parameters.possible_imaging_channels
 
     def __getitem__(self, dsets: t.Union[str, t.Collection]):
         """Get and potentially pre-process data from h5 file and return as a dataframe."""
diff --git a/src/aliby/global_parameters.py b/src/aliby/global_parameters.py
new file mode 100644
index 0000000000000000000000000000000000000000..92b58f8969de09ee31c558019ccabe52a01338c5
--- /dev/null
+++ b/src/aliby/global_parameters.py
@@ -0,0 +1,38 @@
+# parameters to stop the pipeline when exceeded
+earlystop = dict(
+    min_tp=100,
+    thresh_pos_clogged=0.4,
+    thresh_trap_ncells=8,
+    thresh_trap_area=0.9,
+    ntps_to_eval=5,
+)
+
+# imaging properties of the microscope
+imaging_specifications = {
+    "pixel_size": 0.236,
+    "z_size": 0.6,
+    "spacing": 0.6,
+}
+
+# possible imaging channels
+possible_imaging_channels = [
+    "Citrine",
+    "GFP",
+    "GFPFast",
+    "mCherry",
+    "Flavin",
+    "Citrine",
+    "mKO2",
+    "Cy5",
+    "pHluorin405",
+    "pHluorin488",
+]
+
+# functions to apply to the fluorescence of each cell
+fluorescence_functions = [
+    "mean",
+    "median",
+    "std",
+    "imBackground",
+    "max5px_median",
+]
diff --git a/src/aliby/pipeline.py b/src/aliby/pipeline.py
index 0d73c3356455040e0712a62a669b9de9e186c96f..ede77e7c9acce43356ee515fcca47a11f5178e04 100644
--- a/src/aliby/pipeline.py
+++ b/src/aliby/pipeline.py
@@ -14,6 +14,7 @@ import numpy as np
 from pathos.multiprocessing import Pool
 from tqdm import tqdm
 
+import aliby.global_parameters as global_parameters
 from agora.abc import ParametersABC, ProcessABC
 from agora.io.metadata import MetaData, parse_logfiles
 from agora.io.reader import StateReader
@@ -119,13 +120,7 @@ class PipelineParameters(ParametersABC):
                 tps=tps,
                 directory=str(directory.parent),
                 filter="",
-                earlystop=dict(
-                    min_tp=100,
-                    thresh_pos_clogged=0.4,
-                    thresh_trap_ncells=8,
-                    thresh_trap_area=0.9,
-                    ntps_to_eval=5,
-                ),
+                earlystop=global_parameters.earlystop,
                 logfile_level="INFO",
                 use_explog=True,
             )
@@ -162,10 +157,25 @@ class PipelineParameters(ParametersABC):
         return cls(**{k: v for k, v in defaults.items()})
 
     def load_logs(self):
+        """Load and parse log files."""
         parsed_flattened = parse_logfiles(self.log_dir)
         return parsed_flattened
 
 
+def find_channels_by_group(meta):
+    """Parse meta data to find which imaging channels are used for each group."""
+    channels_dict = {group_no: [] for group_no in meta["positions/group"]}
+    imaging_channels = global_parameters.possible_imaging_channels
+    for i, group_no in enumerate(meta["positions/group"]):
+        for imaging_channel in imaging_channels:
+            if (
+                "positions/" + imaging_channel in meta
+                and meta["positions/" + imaging_channel][i]
+            ):
+                channels_dict[group_no].append(imaging_channel)
+    return channels_dict
+
+
 class Pipeline(ProcessABC):
     """
     Initialise and run tiling, segmentation, extraction and post-processing.
@@ -224,11 +234,6 @@ class Pipeline(ProcessABC):
         fh.setFormatter(formatter)
         logger.addHandler(fh)
 
-    @classmethod
-    def from_yaml(cls, fpath):
-        # an unfinished convenience function
-        return cls(parameters=PipelineParameters.from_yaml(fpath))
-
     @classmethod
     def from_folder(cls, dir_path):
         """
@@ -324,7 +329,7 @@ class Pipeline(ProcessABC):
             directory = self.store or root_dir / conn.unique_name
             if not directory.exists():
                 directory.mkdir(parents=True)
-            # download logs to use for metadata
+            # get logs to use for metadata
             conn.cache_logs(directory)
         print("Positions available:")
         for i, pos in enumerate(position_ids.keys()):
diff --git a/src/extraction/core/extractor.py b/src/extraction/core/extractor.py
index 0192434d554218d7286be1dbbb1680bb5b82fdbe..7cb11443b2e9b6197382911230ce82ee90dc9cec 100644
--- a/src/extraction/core/extractor.py
+++ b/src/extraction/core/extractor.py
@@ -16,6 +16,7 @@ from extraction.core.functions.loaders import (
     load_funs,
     load_redfuns,
 )
+import aliby.global_parameters as global_parameters
 
 # define types
 reduction_method = t.Union[t.Callable, str, None]
@@ -89,12 +90,7 @@ class Extractor(StepABC):
     or leaf level.
     """
 
-    # TODO Move this to a location with the SwainLab defaults
-    default_meta = {
-        "pixel_size": 0.236,
-        "z_size": 0.6,
-        "spacing": 0.6,
-    }
+    default_meta = global_parameters.imaging_specifications
 
     def __init__(
         self,
diff --git a/src/extraction/core/functions/defaults.py b/src/extraction/core/functions/defaults.py
index 1c32d0e2c7c2ba652a35419e78d8bcfa94eab00b..bc9107b7f86fd00a510d443596171d5607525191 100644
--- a/src/extraction/core/functions/defaults.py
+++ b/src/extraction/core/functions/defaults.py
@@ -4,6 +4,7 @@ from pathlib import Path
 
 import h5py
 
+import aliby.global_parameters as global_parameters
 from aliby.tile.tiler import find_channel_name
 
 
@@ -21,26 +22,10 @@ def exparams_from_meta(
         "tree": {"general": {"None": ["area", "volume", "eccentricity"]}},
         "multichannel_ops": {},
     }
-    candidate_channels = {
-        "Citrine",
-        "GFP",
-        "GFPFast",
-        "mCherry",
-        "pHluorin405",
-        "pHluorin488",
-        "Flavin",
-        "Cy5",
-        "mKO2",
-    }
+    candidate_channels = set(global_parameters.possible_imaging_channels)
     default_reductions = {"max"}
-    default_metrics = {
-        "mean",
-        "median",
-        "std",
-        "imBackground",
-        "max5px_median",
-        # "nuc_est_conv",
-    }
+    default_metrics = set(global_parameters.fluorescence_functions)
+
     # define ratiometric combinations
     # key is numerator and value is denominator
     # add more to support additional channel names