diff --git a/extensions/chaeo/workflows.py b/extensions/chaeo/workflows.py
index 597475f927d155e181d20f550aa76b24d43f4e35..9cd7078b3a0a51c2abf02055d4549efd11d73b06 100644
--- a/extensions/chaeo/workflows.py
+++ b/extensions/chaeo/workflows.py
@@ -9,7 +9,7 @@ from sklearn.model_selection import train_test_split
 
 from extensions.ilastik.models import IlastikPixelClassifierModel
 from extensions.chaeo.annotators import draw_boxes_on_3d_image
-from extensions.chaeo.products import export_patches_from_zstack, export_patch_masks_from_zstack, export_multichannel_patches_from_zstack
+from extensions.chaeo.products import export_patches_from_zstack, export_patch_masks_from_zstack, export_multichannel_patches_from_zstack, get_patches_from_zmask_meta, get_patch_masks_from_zmask_meta
 from extensions.chaeo.zmask import build_zmask_from_object_mask, project_stack_from_focal_points
 from extensions.ilastik.models import IlastikPixelClassifierModel
 
@@ -31,7 +31,7 @@ def get_zmask_meta(
     zmask_type: str = 'boxes',
 
 
-) -> Dict:
+) -> tuple:
     ti = Timer()
     stack = generate_file_accessor(Path(input_file_path))
     fstem = Path(input_file_path).stem
@@ -64,10 +64,9 @@ def get_zmask_meta(
         filters=zmask_filters,
         expand_box_by=zmask_expand_box_by,
     )
-    zmask_acc = InMemoryDataAccessor(zmask)
     ti.click('generate_zmasks')
 
-    return ti, stack, fstem, pxmap, zmask, zmask_meta, df, interm
+    return ti, stack, fstem, obmask, pxmap, zmask, zmask_meta, df, interm
 
 
 # TODO: unpack and validate inputs
@@ -98,7 +97,7 @@ def export_patches_from_multichannel_zstack(
 ) -> Dict:
     pixel_classifier = models[0]
 
-    ti, stack, fstem, pxmap, zmask, zmask_meta, df, interm = get_zmask_meta(
+    ti, stack, fstem, obmask, pxmap, zmask, zmask_meta, df, interm = get_zmask_meta(
         input_file_path,
         pixel_classifier,
         segmentation_channel,
@@ -210,6 +209,65 @@ def export_patches_from_multichannel_zstack(
         'interm': interm,
     }
 
+def get_object_map_from_zstack(
+        input_file_path: str,
+        output_folder_path: str,
+        models: List[Model],
+        pxmap_threshold: float,
+        pxmap_foreground_channel: int,
+        segmentation_channel: int,
+        patches_channel: int,
+        zmask_zindex: int = None,  # None for MIP,
+        zmask_clip: int = None,
+        zmask_type: str = 'boxes',
+        zmask_filters: Dict = None,
+        zmask_expand_box_by: int = None,
+        **kwargs,
+) -> Dict:
+    pixel_classifier = models[0]
+
+    ti, stack, fstem, obmask, pxmap, zmask, zmask_meta, df, interm = get_zmask_meta(
+        input_file_path,
+        pixel_classifier,
+        segmentation_channel,
+        pxmap_threshold,
+        pxmap_foreground_channel=pxmap_foreground_channel,
+        zmask_zindex=zmask_zindex,
+        zmask_clip=zmask_clip,
+        zmask_expand_box_by=zmask_expand_box_by,
+        zmask_filters=zmask_filters,
+        zmask_type=zmask_type,
+    )
+
+    # extract patches to accessor
+    patches_acc = get_patches_from_zmask_meta(
+        stack,
+        zmask_meta,
+        rescale_clip=zmask_clip,
+        make_3d=False,
+        **kwargs
+    )
+
+    # extract masks
+    patch_masks_acc = get_patch_masks_from_zmask_meta(
+        stack,
+        zmask_meta,
+        **kwargs
+    )
+
+    # send patches and mask stacks to object classifier
+    mod = PatchStackObjectClassifier({'project_file': where_patch_stack / ilp})
+    result_acc, _ = mod.infer(raw, mask)
+    # write_accessor_data_to_file(where_patch_stack / f'zstack_train_result_{suffix}.tif', result_acc)
+
+    # assign labels to object map:
+    for ii, mi in enumerate(zmask_meta):
+        obj = mi['info']
+        la = obj.label
+        patch = patches_acc.iat(ii)
+
+
+
 def transfer_ecotaxa_labels_to_patch_stacks(
         where_masks: str,
         where_patches: str,