diff --git a/extensions/chaeo/examples/batch_run_patches.py b/extensions/chaeo/examples/batch_run_patches.py
index 7d38aa13c546f4de0c2a6f1907104fabf52e407d..f2fd45d94609ad5354ea6881a7f4861d18ceff97 100644
--- a/extensions/chaeo/examples/batch_run_patches.py
+++ b/extensions/chaeo/examples/batch_run_patches.py
@@ -16,9 +16,13 @@ if __name__ == '__main__':
         'c:/Users/rhodes/projects/proj0011-plankton-seg/exp0009/output'
     )
     yyyymmdd = strftime('%Y%m%d', localtime())
+
     idx = 0
-    while Path(where_output_root / f'batch-output-{yyyymmdd}-{idx:04d}').exists():
-        idx += 1
+    for ff in Path(where_output_root).iterdir():
+        ma = re.match(f'batch-output-{yyyymmdd}-([\d]+)', ff.name)
+        if ma:
+            idx = max(idx, int(ma.groups()[0]) + 1 )
+
     where_output = Path(
         where_output_root / f'batch-output-{yyyymmdd}-{idx:04d}'
     )
@@ -26,14 +30,15 @@ if __name__ == '__main__':
     csv_args = {'mode': 'w', 'header': True} # when creating file
     px_ilp = Path.home() / 'model-server' / 'ilastik' / 'AF405-bodies_boundaries.ilp'
 
-    # TODO: try/catch blocks and error handling around workflow calls
-    # TODO: pack JSON-serializable workflow inputs
+    #TODO: try/catch blocks and error handling around workflow calls
+    #TODO: pack JSON-serializable workflow inputs
     for ff in where_czi.iterdir():
+
         pattern = 'Selection--W([\d]+)--P([\d]+)-T([\d]+)'
         ma = re.match(pattern, ff.stem)
 
         print(ff)
-        if not ff.suffix.upper() == '.CZI':
+        if not ff.suffix.upper () == '.CZI':
             continue
         if int(ma.groups()[1]) > 10: # skip second half of set
             continue
diff --git a/extensions/chaeo/examples/export_patch_focus_metrics.py b/extensions/chaeo/examples/export_patch_focus_metrics.py
index 6c963e8b51dceb4f195776ff6c3ccab549448727..93a9fb458a8d582f68fdd78bd9028b3f85b2d113 100644
--- a/extensions/chaeo/examples/export_patch_focus_metrics.py
+++ b/extensions/chaeo/examples/export_patch_focus_metrics.py
@@ -3,10 +3,12 @@ import re
 from time import localtime, strftime
 from typing import Dict
 
+import numpy as np
 import pandas as pd
+from skimage.filters import gaussian, sobel
 
 from extensions.ilastik.models import IlastikPixelClassifierModel
-from extensions.chaeo.products import export_3d_patches_with_focus_metrics
+from extensions.chaeo.products import export_3d_patches_with_focus_metrics, export_patches_from_zstack
 from extensions.chaeo.zmask import build_zmask_from_object_mask
 from model_server.accessors import generate_file_accessor, InMemoryDataAccessor, write_accessor_data_to_file
 from model_server.workflows import Timer
@@ -64,12 +66,24 @@ def export_patch_focus_metrics_from_multichannel_zstack(
         stack.get_one_channel_data(patches_channel),
         zmask_meta,
         prefix=fstem,
-        draw_bounding_box=False,
         rescale_clip=0.0,
         make_3d=True,
         annotate_focus_metric=annotate_focus_metric,
     )
-    ti.click('export_patches')
+    ti.click('export_3d_patches')
+
+    files = export_patches_from_zstack(
+        Path(where_output) / '2d_patches',
+        stack.get_one_channel_data(patches_channel),
+        zmask_meta,
+        prefix=fstem,
+        draw_bounding_box=True,
+        rescale_clip=0.0,
+        # focus_metric=lambda x: np.max(sobel(x)),
+        focus_metric='max_sobel',
+        make_3d=False,
+    )
+    ti.click('export_2d_patches')
 
     return {
         'pixel_model_id': px_model.model_id,
@@ -101,6 +115,9 @@ if __name__ == '__main__':
     px_ilp = Path.home() / 'model-server' / 'ilastik' / 'AF405-bodies_boundaries.ilp'
 
     for ff in where_czi.iterdir():
+        if ff.stem != 'Selection--W0000--P0009-T0001':
+            continue
+
         pattern = 'Selection--W([\d]+)--P([\d]+)-T([\d]+)'
         ma = re.match(pattern, ff.stem)