diff --git a/src/agora/io/metadata.py b/src/agora/io/metadata.py
index 4da1b2800130c3cc6649475969226175332d6041..bed04c492c100c8aa52b3939b1c7f4ce8f7d8e0c 100644
--- a/src/agora/io/metadata.py
+++ b/src/agora/io/metadata.py
@@ -211,6 +211,9 @@ def get_meta_from_legacy(parsed_metadata: dict):
 def parse_swainlab_metadata(filedir: t.Union[str, Path]):
     """Parse new, .log, and old, .txt, files in a directory into a dict."""
     filedir = Path(filedir)
+    if filedir.is_file() or str(filedir).endswith(".zarr"):
+        # log file is in parent directory
+        filedir = filedir.parent
     filepath = find_file(filedir, "*.log")
     if filepath:
         # new log files ending in .log
@@ -218,9 +221,6 @@ def parse_swainlab_metadata(filedir: t.Union[str, Path]):
         minimal_meta = get_minimal_meta_swainlab(raw_parse)
     else:
         # old log files ending in .txt
-        if filedir.is_file() or str(filedir).endswith(".zarr"):
-            # log file is in parent directory
-            filedir = filedir.parent
         legacy_parse = parse_logfiles(filedir)
         minimal_meta = (
             get_meta_from_legacy(legacy_parse) if legacy_parse else {}
diff --git a/src/aliby/broken_pipeline.py b/src/aliby/broken_pipeline.py
index b03eabfea318ff5264640b18fe9f2e94235ae017..d54c2698d896bfdee148888d59031ca64ab07110 100644
--- a/src/aliby/broken_pipeline.py
+++ b/src/aliby/broken_pipeline.py
@@ -224,7 +224,7 @@ class Pipeline(ProcessABC):
             directory = self.store or root_dir / conn.unique_name
             if not directory.exists():
                 directory.mkdir(parents=True)
-            # get logs to use for metadata
+            # copy logs to h5 directory
             conn.cache_logs(directory)
         print("Positions available:")
         for i, pos in enumerate(position_ids.keys()):
@@ -280,7 +280,8 @@ class Pipeline(ProcessABC):
 
     def run(self):
         """Run separate pipelines for all positions in an experiment."""
-        self.OMERO_channels = self.channels_from_OMERO()
+        if not hasattr(self, "OMERO_channels"):
+            self.OMERO_channels = self.channels_from_OMERO()
         config = self.parameters.to_dict()
         position_ids = self.setup()
         # pick particular positions if desired
diff --git a/src/aliby/io/image.py b/src/aliby/io/image.py
index 42005645b6935e07ff264f8e4b699258d2c75d37..b87bcdc1a3a3116beabc14230a15ee7c6ee94757 100644
--- a/src/aliby/io/image.py
+++ b/src/aliby/io/image.py
@@ -50,8 +50,9 @@ def instantiate_image(
 
 
 def dispatch_image(source: t.Union[str, int, t.Dict[str, str], Path]):
-    """Pick the appropriate Image class depending on the source of data."""
+    """Pick the appropriate Image class for the source of data."""
     if isinstance(source, (int, np.int64)):
+        # requires omero module
         from aliby.io.omero import Image
 
         instantiator = Image
diff --git a/src/aliby/io/omero.py b/src/aliby/io/omero.py
index e91ec683bcbf4ea3c04b7383fc34a1e4c347cc5e..8d453f57cfea6cc6073c071a000f8da17d9eed28 100644
--- a/src/aliby/io/omero.py
+++ b/src/aliby/io/omero.py
@@ -4,7 +4,6 @@ Tools to manage I/O using a remote OMERO server.
 
 import re
 import typing as t
-from abc import abstractmethod
 from pathlib import Path
 
 import dask.array as da
diff --git a/src/aliby/tile/tiler.py b/src/aliby/tile/tiler.py
index c8bb150c0b2ce918fc3b0b443c7c604f37d9ae1d..981b4c770c279687bb6b9aead5937ef0cada7f2f 100644
--- a/src/aliby/tile/tiler.py
+++ b/src/aliby/tile/tiler.py
@@ -268,7 +268,9 @@ class Tiler(StepABC):
                 list(range(metadata.get("size_c", 0))),
             )
         else:
-            # new image meta data contains channels for that image
+            channels = []
+        if not channels:
+            # image meta data contains channels for that image
             channels = metadata.get(
                 "channels", list(range(metadata.get("size_c", 0)))
             )