From f4cd66255b9c69fa6569e3fcd838d327a7ebe919 Mon Sep 17 00:00:00 2001
From: Christopher Rhodes <christopher.rhodes@embl.de>
Date: Wed, 25 Oct 2023 11:30:37 +0200
Subject: [PATCH] Add EcoTaxa-spec'd TSV export to batch running script

---
 .../20230807_kristineberg_spiked.py           | 55 +++++++++++++++++++
 ...fer_labels_to_ilastik_object_classifier.py | 26 ++++++---
 extensions/chaeo/workflows.py                 |  4 --
 3 files changed, 73 insertions(+), 12 deletions(-)
 create mode 100644 extensions/chaeo/actual_runs/20230807_kristineberg_spiked.py

diff --git a/extensions/chaeo/actual_runs/20230807_kristineberg_spiked.py b/extensions/chaeo/actual_runs/20230807_kristineberg_spiked.py
new file mode 100644
index 00000000..5d88e386
--- /dev/null
+++ b/extensions/chaeo/actual_runs/20230807_kristineberg_spiked.py
@@ -0,0 +1,55 @@
+from pathlib import Path
+
+from extensions.chaeo.util import autonumber_new_directory, get_matching_files, loop_workflow
+from extensions.chaeo.workflows import export_patches_from_multichannel_zstack
+
+from model_server.accessors import CziImageFileAccessor, write_accessor_data_to_file, InMemoryDataAccessor
+from model_server.process import rescale
+
+# TODO: support list-comp of single image sequence in multiple locations
+
+# TODO: split multi-pos CZI into sequence of accessors, append to list
+
+if __name__ == '__main__':
+    root = Path('c:/Users/rhodes/projects/proj0012-trec-handoff/owncloud-sync/TREC-HD/Images/')
+    where_czi = (root / 'TREC_STOP_24_Bilbao/231008_automic/20231008-162336/Selection').__str__()
+    where_output = autonumber_new_directory(
+        'c:/Users/rhodes/projects/proj0011-plankton-seg/exp0017',
+        'batch-output'
+    )
+
+    px_ilp = Path('c:/Users/rhodes/projects/proj0011-plankton-seg/exp0017/pxAF405_dim8bit.ilp').__str__()
+
+    params = {
+        'ilastik_project_file': px_ilp,
+        'pxmap_threshold': 0.25,
+        'pixel_class': 0,
+        'zmask_channel': 0,
+        'zmask_zindex': 3,
+        'patches_channel': 2,
+        'mask_type': 'boxes',
+        'zmask_filters': {'area': (1e3, 1e8)},
+        'zmask_expand_box_by': (128, 3),
+        'export_pixel_probabilities': True,
+        'export_2d_patches_for_training': True,
+        'draw_bounding_box_on_2d_patch': True,
+        'export_2d_patches_for_annotation': True,
+        'export_3d_patches': False,
+        'export_annotated_zstack': True,
+        'export_patch_masks': True,
+        'rescale_zmask_clip': 0.01,
+        'rgb_overlay_channels': (1, None, None),
+        'rgb_overlay_weights': (0.5, 1.0, 1.0)
+    }
+
+    input_files = get_matching_files(where_czi, 'czi', coord_filter={})
+
+    loop_workflow(
+        input_files,
+        where_output,
+        export_patches_from_multichannel_zstack,
+        params,
+        catch_and_continue=False,
+    )
+
+    print('Finished')
\ No newline at end of file
diff --git a/extensions/chaeo/examples/transfer_labels_to_ilastik_object_classifier.py b/extensions/chaeo/examples/transfer_labels_to_ilastik_object_classifier.py
index 46ea2988..49de008f 100644
--- a/extensions/chaeo/examples/transfer_labels_to_ilastik_object_classifier.py
+++ b/extensions/chaeo/examples/transfer_labels_to_ilastik_object_classifier.py
@@ -234,19 +234,28 @@ if __name__ == '__main__':
         proj_name='auto_obj_before'
     )
 
-
-    def infer_and_compare(ilp, suffix):
+    def infer_and_compare_training_set(ilp, suffix):
         # infer object labels from the same data used to train the classifier
         train_zstack_raw = generate_file_accessor(where_patch_stack / 'zstack_train_raw.tif')
         train_zstack_mask = generate_file_accessor(where_patch_stack / 'zstack_train_mask.tif')
+        train_truth_labels = generate_file_accessor(where_patch_stack / f'zstack_train_label.tif')
+        infer_and_compare(ilp, 'train', suffix, train_zstack_raw, train_zstack_mask, train_truth_labels)
+
+    def infer_and_compare_test_set(ilp, suffix):
+        # infer object labels from test dataset
+        test_zstack_raw = generate_file_accessor(where_patch_stack / 'zstack_test_raw.tif')
+        test_zstack_mask = generate_file_accessor(where_patch_stack / 'zstack_test_mask.tif')
+        test_truth_labels = generate_file_accessor(where_patch_stack / f'zstack_test_label.tif')
+        infer_and_compare(ilp, 'test', suffix, test_zstack_raw, test_zstack_mask, test_truth_labels)
+
+    def infer_and_compare(ilp, prefix, suffix, raw, mask, labels):
         mod = PatchStackObjectClassifier({'project_file': where_patch_stack / ilp})
-        result_acc, _ = mod.infer(train_zstack_raw, train_zstack_mask)
+        result_acc, _ = mod.infer(raw, mask)
         write_accessor_data_to_file(where_patch_stack / f'zstack_train_result_{suffix}.tif', result_acc)
 
         # write comparison tables
-        train_truth_labels = generate_file_accessor(where_patch_stack / f'zstack_train_label.tif')
-        df_comp = compare_object_maps(train_truth_labels, result_acc)
-        df_comp.to_csv(where_patch_stack / f'compare_train_result_{suffix}.csv', index=False)
+        df_comp = compare_object_maps(labels, result_acc)
+        df_comp.to_csv(where_patch_stack / f'compare_{prefix}_result_{suffix}.csv', index=False)
         print(f'Generated ilastik project {ilp}')
         print('Truth and inferred labels match?')
         print(pd.value_counts(df_comp['truth_label'] == df_comp['inferred_label']))
@@ -262,7 +271,7 @@ if __name__ == '__main__':
                 print(f'{r}: {h5[r][()]}')
 
     # infer object labels from the same data used to train the classifier
-    infer_and_compare(auto_ilp, 'before')
+    infer_and_compare_training_set(auto_ilp, 'before')
 
     # copy project and prompt user input once ilastik file has been modified in-app
     mod_ilp = shutil.copy(auto_ilp, where_patch_stack / 'auto_obj_after.ilp')
@@ -270,6 +279,7 @@ if __name__ == '__main__':
     input()
 
     # repeat inference with the modified project file
-    infer_and_compare(mod_ilp, 'after')
+    infer_and_compare_training_set(mod_ilp, 'after')
+    infer_and_compare_test_set(mod_ilp, 'after')
 
 
diff --git a/extensions/chaeo/workflows.py b/extensions/chaeo/workflows.py
index dab8215d..7486395e 100644
--- a/extensions/chaeo/workflows.py
+++ b/extensions/chaeo/workflows.py
@@ -135,10 +135,6 @@ def export_patches_from_multichannel_zstack(
         )
         df_patches = pd.DataFrame(files)
         ti.click('export_2d_patches')
-        # associate 2d patches, dropping labeled objects that were not exported as patches
-        # df = pd.merge(df, df_patches, left_index=True, right_on='df_index').drop(columns='df_index')
-        # prepopulate patch UUID
-        # df['patch_id'] = df.apply(lambda _: uuid4(), axis=1)
 
     if export_patch_masks:
         files = export_patch_masks_from_zstack(
-- 
GitLab