From b4418bc3149fcfe553d692f32feeb22c1168864c Mon Sep 17 00:00:00 2001
From: Laurent Mercadier <laurent.mercadier@xfel.eu>
Date: Wed, 19 Mar 2025 07:59:37 +0100
Subject: [PATCH] Add mode for peak integration, return peak integration
 attributes

---
 src/toolbox_scs/detectors/digitizers.py | 36 ++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/toolbox_scs/detectors/digitizers.py b/src/toolbox_scs/detectors/digitizers.py
index 506335d..e610171 100644
--- a/src/toolbox_scs/detectors/digitizers.py
+++ b/src/toolbox_scs/detectors/digitizers.py
@@ -32,7 +32,8 @@ log = logging.getLogger(__name__)
 
 
 def peaks_from_raw_trace(traces, pulseStart, pulseStop, baseStart, baseStop,
-                         period=None, npulses=None, extra_dim=None):
+                         period=None, npulses=None, extra_dim=None,
+                         mode='trapz'):
     """
     Computes peaks from raw digitizer traces by trapezoidal integration.
 
@@ -55,6 +56,9 @@ def peaks_from_raw_trace(traces, pulseStart, pulseStop, baseStart, baseStop,
         number of pulses. Ignored if intstart is a 1D-array.
     extra_dim: str
         Name given to the dimension along the peaks. Defaults to 'pulseId'.
+    mode: str in ['trapz', 'sum', 'mean', 'ampl']
+        The operation performed over the integration region. `ampl` is the
+        amplitude between the baseline and the peak height.
 
     Returns
     -------
@@ -86,7 +90,15 @@ def peaks_from_raw_trace(traces, pulseStart, pulseStop, baseStart, baseStop,
     results = xr.DataArray(np.empty((traces.shape[0], len(pulses))),
                            coords=coords,
                            dims=['trainId', extra_dim])
-
+    func = {'trapz': np.trapz, 'sum': np.sum,
+            'mean': np.mean}.get(mode)
+    if mode == 'ampl':
+        def func(val, axis):
+            return np.max(val, axis=axis) - np.min(val, axis=axis)
+
+    if func is None:
+        raise ValueError('mode must be a string in ["trapz", "sum",'
+                         '"mean", "ampl"]')
     for i, p in enumerate(pulses):
         a = pulseStart + p
         b = pulseStop + p
@@ -96,7 +108,7 @@ def peaks_from_raw_trace(traces, pulseStart, pulseStop, baseStart, baseStop,
             break
         bg = np.outer(np.median(traces[:, bkga:bkgb], axis=1),
                       np.ones(b-a))
-        results[:, i] = np.trapz(traces[:, a:b] - bg, axis=1)
+        results[:, i] = func(traces[:, a:b] - bg, axis=1)
     return results
 
 
@@ -720,7 +732,7 @@ def digitizer_type(run, source):
 
 
 def get_digitizer_peaks(proposal, runNB, mnemonic, merge_with=None,
-                        bunchPattern='sase3', integParams=None,
+                        bunchPattern='sase3', integParams=None, mode='trapz',
                         save=False, subdir='usr/processed_runs'):
     """
     Extract the peaks from digitizer raw traces. The result can be merged
@@ -753,6 +765,14 @@ def get_digitizer_peaks(proposal, runNB, mnemonic, merge_with=None,
         {'pulseStart':100, 'pulsestop':200, 'baseStart':50,
         'baseStop':99, 'period':24, 'npulses':500}.
         If None, integration parameters are computed automatically.
+    mode: str in ['trapz', 'sum', 'mean', 'ampl']
+        The operation performed over the integration region. `ampl` is the
+        amplitude between the baseline and the peak height.
+    save: bool
+        If True, save the computed peaks and the average raw trace in a h5
+        file in the subdir + f'/r{runNB:04d}/ folder.
+    subdir: str
+        subdirectory to save the output in.
 
     Returns
     -------
@@ -793,7 +813,8 @@ def get_digitizer_peaks(proposal, runNB, mnemonic, merge_with=None,
         run, mnemonic, trace, integParams, pattern)
 
     # extract peaks
-    peaks = peaks_from_raw_trace(traces, **params, extra_dim=extra_dim)
+    peaks = peaks_from_raw_trace(traces, **params,
+                                 extra_dim=extra_dim, mode=mode)
     peaks = peaks.rename(mnemonic.replace('raw', 'peaks'))
 
     # Align pulse id
@@ -812,13 +833,16 @@ def get_digitizer_peaks(proposal, runNB, mnemonic, merge_with=None,
         if params[p] is None:
             params[p] = 'None'
         peaks.attrs[f'{peaks.name}_{p}'] = params[p]
+    peaks.attrs[f'{peaks.name}_mode'] = mode
+
 
     # save peaks
     if save:
         save_peaks(proposal, runNB, peaks, trace, subdir)
 
     # merge with existing dataset
-    ds = mw_ds.merge(peaks, join='inner')
+    ds = mw_ds.merge(peaks.to_dataset(promote_attrs=True), join='inner',
+                     combine_attrs='drop_conflicts')
     return ds
 
 
-- 
GitLab