From 4c60e3acb816e55ccfdc454b930539b64382b4de Mon Sep 17 00:00:00 2001
From: Laurent Mercadier <laurent.mercadier@xfel.eu>
Date: Thu, 13 Oct 2022 11:25:52 +0200
Subject: [PATCH] Add function to read digitizers signal description

---
 doc/changelog.rst                       |  1 +
 src/toolbox_scs/detectors/digitizers.py | 66 +++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/doc/changelog.rst b/doc/changelog.rst
index c47bd4d..a69fdc1 100644
--- a/doc/changelog.rst
+++ b/doc/changelog.rst
@@ -14,6 +14,7 @@ unreleased
 
 - **New Features**
 
+    -  Read signal description from Fast ADC and ADQ412 digitizers :mr:`209`
 
 1.6.0
 -----
diff --git a/src/toolbox_scs/detectors/digitizers.py b/src/toolbox_scs/detectors/digitizers.py
index 297a774..01d8363 100644
--- a/src/toolbox_scs/detectors/digitizers.py
+++ b/src/toolbox_scs/detectors/digitizers.py
@@ -24,6 +24,7 @@ __all__ = [
     'get_laser_peaks',
     'get_peaks',
     'get_tim_peaks',
+    'digitizer_signal_description'
 ]
 
 log = logging.getLogger(__name__)
@@ -986,6 +987,71 @@ def get_digitizer_peaks(run, mnemonics, digitizer, merge_with=None,
     return ds
 
 
+def digitizer_signal_description(run, digitizer=None):
+    """
+    Check for the existence of signal description and return all corresponding
+    channels in a dictionnary.
+    
+    Parameters
+    ----------
+    proposal: int
+        The proposal number
+    runNB: int
+        The run number
+    digitizer: str or list of str (default=None)
+        Name of the digitizer: one in ['FastADC', FastADC2',
+        'ADQ412', 'ADQ412_2]
+        If None, all digitizers are used
+
+    Returns
+    -------
+    signal_description: dictionnary containing the signal description of
+        the digitizer channels.
+
+
+    Example
+    -------
+    import toolbox_scs as tb
+    run = tb.open_run(3481, 100)
+    signals = tb.digitizer_signal_description(run)
+    signals_fadc2 = tb.digitizer_signal_description(run, 'FastADC2')
+    """
+    if digitizer not in [None, 'FastADC', 'FastADC2']:
+        raise ValueError('digitizer must be one in '
+                         '["FastADC", "FastADC2"]')
+    if digitizer is None:
+        digitizer = ['FastADC', 'FastADC2', 'ADQ412', 'ADQ412_2']
+    else:
+        digitizer = [digitizer]
+    def key_fadc(i):
+        if i > 9:
+            return None
+        return f'channel_{i}.signalDescription.value'
+    def key_adq412(i):
+        if i > 3:
+            return None
+        return f'board1.channel_{i}.description.value'
+    
+    sources = {'FastADC': ['SCS_UTC1_MCP/ADC/1', key_fadc],
+               'FastADC2': ['SCS_UTC2_FADC/ADC/1', key_fadc],
+               'ADQ412': ['SCS_UTC1_ADQ/ADC/1', key_adq412],
+               'ADQ412_2': ['SCS_UTC2_ADQ/ADC/1', key_adq412]}
+    res = {}
+    for d in digitizer:
+        if sources[d][0] not in run.all_sources:
+            continue
+        if sources[d][1](0) not in run.get_run_values(sources[d][0]):
+            raise ValueError('No signal description available for '
+                             f'{d}: {sources[d][0]}')
+        for ch in range(10):
+            val = sources[d][1](ch)
+            if val is None:
+                break
+            desc = run.get_run_value(sources[d][0], val)
+            res[f'{d}_Ch{ch}'] = desc
+    return res
+
+
 def calibrateTIM(data, rollingWindow=200, mcp=1, plot=False, use_apd=True, intstart=None,
                  intstop=None, bkgstart=None, bkgstop=None, t_offset=None, npulses_apd=None):
     ''' Calibrate TIM signal (Peak-integrated signal) to the slow ion signal of SCS_XGM
-- 
GitLab