From 5dc3cbddd514f60f6bfd0cfa96b34f2d44f2d0cd Mon Sep 17 00:00:00 2001
From: Egor Sobolev <egor.sobolev@xfel.eu>
Date: Sat, 1 Jun 2024 20:07:32 +0200
Subject: [PATCH] Add identification of bad pixels

---
 src/geomtools/sfx/misc.py | 41 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/src/geomtools/sfx/misc.py b/src/geomtools/sfx/misc.py
index 0a8e637..60f7a89 100644
--- a/src/geomtools/sfx/misc.py
+++ b/src/geomtools/sfx/misc.py
@@ -1,5 +1,6 @@
 import numpy as np
 import pandas as pd
+from scipy.stats import iqr
 
 
 def gauss2d_fit(x, y):
@@ -82,3 +83,43 @@ def rmsd_per_group(pxdispl, panels, group_name, minpeaks=3):
         peak_num=('r_avg', 'count')
     )
     return rmsd
+
+
+def badpixels_mask(pe, panels, snr=6, min_peak_count=4):
+    """Makes pixel dataset with peak stats and marks bad pixels."""
+    # aggregate peak in pixels
+    px = pe.copy()
+    px[['fs', 'ss']] = px[['fs', 'ss']].astype(int)
+    px = (
+        px[['panel', 'fs', 'ss', 'intensity']]
+        .groupby(['panel', 'fs', 'ss'])
+        .agg(num_peaks=('intensity', 'count'))
+        .reset_index()
+    )
+    px = (
+        px
+        .join(get_peak_position(px, panels))
+        .join(panels[['modno']], on="panel")
+    )
+    px['r'] = np.sqrt(px.x * px.x + px.y * px.y)
+    px['ri'] = np.round(px.r).astype(int)
+
+    # compute radial profile
+    rp = px.groupby('ri').agg(
+        num_peaks_med=('num_peaks', np.median),
+        num_peaks_iqr=('num_peaks', iqr))
+
+    rp['num_peaks_hi'] = np.maximum(
+        rp.num_peaks_med + snr * 1.349 * rp.num_peaks_iqr, min_peak_count)
+
+    # bad pixels
+    px = px.join(rp, on="ri")
+    px['msk'] = (px.num_peaks > px.num_peaks_hi)
+    return px
+
+
+def pixels_to_image(shape, px, attr='msk'):
+    """Transforms dataset of pixels to the image array."""
+    img = np.zeros(shape, px[attr].dtype)
+    img[px.modno, px.ss, px.fs] = px[attr]
+    return img
-- 
GitLab