From 0c25e41dc1a59dd47720d4cd17ae45eb83d44420 Mon Sep 17 00:00:00 2001
From: Christopher Rhodes <christopher.rhodes@embl.de>
Date: Fri, 26 Apr 2024 14:28:12 +0200
Subject: [PATCH] Run pixel and object classification on ilastik projects' own
 inputs

---
 .../verify_multichannel_ilastik_inputs.py     | 111 ++++++++++++++++++
 1 file changed, 111 insertions(+)
 create mode 100644 model_server/scripts/verify_multichannel_ilastik_inputs.py

diff --git a/model_server/scripts/verify_multichannel_ilastik_inputs.py b/model_server/scripts/verify_multichannel_ilastik_inputs.py
new file mode 100644
index 00000000..1159b3f1
--- /dev/null
+++ b/model_server/scripts/verify_multichannel_ilastik_inputs.py
@@ -0,0 +1,111 @@
+from pathlib import Path
+
+import h5py
+import numpy as np
+import pandas as pd
+
+from model_server.base.accessors import generate_file_accessor, write_accessor_data_to_file, InMemoryDataAccessor
+from model_server.extensions.ilastik.models import IlastikPixelClassifierModel, IlastikObjectClassifierFromPixelPredictionsModel
+
+def get_input_files(where_ilp: Path) -> list:
+    files = []
+    with h5py.File(where_ilp, 'r') as h5:
+        infos = h5['Input Data/infos']
+        for lane in infos.keys():
+            lane_dict = {}
+            for role in infos[lane].keys():
+                if len(infos[lane][role]) == 0:
+                    continue
+                rel_path = Path(infos[lane][role]['filePath'][()].decode())
+                lane_dict[role] = where_ilp.parent / rel_path
+            files.append(lane_dict)
+    return files
+
+if __name__ == '__main__':
+    where_out = Path('c:/Users/rhodes/projects/proj0015-model-server/issues/0032_multiple_input_channels/output')
+    root = Path('w:/03_analysis/Trial3_LSM900')
+    max_files = 1
+    ilps = [
+        '01_ilastik_files/relpath_240301_LSM900_DNA_PC.ilp',
+        '01_ilastik_files/relpath_240320_LSM900_DNA_OC_new.ilp',
+        '01_ilastik_files/relpath_240301_LSM900_TM_PC.ilp',
+        '01_ilastik_files/relpath_240320_LSM900_TM_OC_new.ilp'
+    ]
+    records = []
+    for f in ilps:
+        ilp = root / f
+        assert ilp.exists()
+        outdir = where_out / ilp.stem
+        outdir.mkdir(parents=True, exist_ok=True)
+
+        if ilp.stem.upper().endswith('_PC'):
+            mod = IlastikPixelClassifierModel(
+                params={'project_file': str(ilp)},
+                enforce_embedded=False
+            )
+            infiles = get_input_files(ilp)
+            for ln in infiles[0:max_files]:
+                acc_raw = generate_file_accessor(root / ln['Raw Data'])
+                pxmap = mod.infer(acc_raw)[0]
+                pxmap_fn = 'pxmap_' + ln['Raw Data'].stem + '.tif'
+                write_accessor_data_to_file(outdir / pxmap_fn, pxmap)
+                record = {
+                    'classifier': str(ilp.relative_to(root)),
+                    'input_raw_data': str(ln['Raw Data'].relative_to(root)),
+                    'input_raw_data_chroma': acc_raw.chroma,
+                    'input_raw_data_dtype': acc_raw.dtype,
+                    'input_raw_data_shape_dict': acc_raw.shape_dict,
+                    'output_file': pxmap_fn,
+                    'output_dtype': pxmap.dtype,
+                    'output_chroma': pxmap.chroma,
+                    'output_shape_dict': pxmap.shape_dict,
+                }
+                records.append(record)
+
+        elif ilp.stem.upper().endswith('_OC_NEW'):
+            mod = IlastikObjectClassifierFromPixelPredictionsModel(
+                params={'project_file': str(ilp)},
+                enforce_embedded=False
+            )
+            infiles = get_input_files(ilp)
+            for ln in infiles[0:max_files]:
+                acc_raw = generate_file_accessor(root / ln['Raw Data'])
+                pa_pxmap = root / ln['Prediction Maps']
+
+                if pa_pxmap.parts[-2].upper().endswith('.H5'):
+                    pa_h5f = root / Path(*pa_pxmap.parts[0:-1])
+                    h5_key = pa_pxmap.parts[-1]
+                    pxmap_data = h5py.File(pa_h5f)[h5_key][()] # C x Y x X ?
+                    pxmap_yxc = np.moveaxis(
+                        pxmap_data,
+                        [1, 2, 0],
+                        [0, 1, 2]
+                    )
+                    acc_pxmap = InMemoryDataAccessor(np.expand_dims(pxmap_yxc, -1))
+                else:
+                    acc_pxmap = generate_file_accessor(pa_pxmap)
+                obmap = mod.infer(acc_raw, acc_pxmap)[0]
+                obmap_fn = 'obmap_' + ln['Raw Data'].stem + '.tif'
+                write_accessor_data_to_file(outdir / obmap_fn, obmap)
+                record = {
+                    'classifier': str(ilp.relative_to(root)),
+                    'input_raw_data': str(ln['Raw Data'].relative_to(root)),
+                    'input_raw_data_chroma': acc_raw.chroma,
+                    'input_raw_data_dtype': acc_raw.dtype,
+                    'input_raw_data_shape_dict': acc_raw.shape_dict,
+                    'input_pxmap': str(ln['Prediction Maps'].relative_to(root)),
+                    'input_pxmap_chroma': acc_pxmap.chroma,
+                    'input_pxmap_dtype': acc_pxmap.dtype,
+                    'input_pxmap_shape_dict': acc_pxmap.shape_dict,
+                    'output_file': obmap_fn,
+                    'output_dtype': obmap.dtype,
+                    'output_chroma': obmap.chroma,
+                    'output_shape_dict': obmap.shape_dict,
+                }
+                records.append(record)
+
+        else:
+            raise Exception(f'unidentified project file {ilp}')
+
+    pd.DataFrame(records).to_csv(where_out / 'record.csv', index=False)
+    print('Finished')
-- 
GitLab