diff --git a/Load.py b/Load.py
index d539553c5606c979143a0025ae32ccc0b486c2f6..d05679c50cd3b914174b5e870500e1e30f0e3427 100644
--- a/Load.py
+++ b/Load.py
@@ -116,6 +116,14 @@ mnemonics = {
     "VFM_BENDERF": {'source':'SCS_KBS_VFM/MOTOR/BENDERF',
                     'key':'encoderPosition.value',
                     'dim':None},
+    
+    # LASER TIMING
+    "AFS_PhaseShifter": {'source':'SCS_ILH_LAS/PHASESHIFTER/DOOCS',
+                 'key':'actualPosition.value',
+                 'dim':None},
+    "AFS_DelayLine": {'source':'SCS_ILH_LAS/MOTOR/LT3',
+                 'key':'AActualPosition.value',
+                 'dim':None},
 
     # FFT
     "scannerX": {'source':'SCS_CDIFFT_SAM/LMOTOR/SCANNERX',
@@ -192,6 +200,68 @@ mnemonics = {
                 'key':'digitizers.channel_1_A.raw.samples',
                 'dim': ['samplesId']},
 
+    # FastADC
+    "FastADC0peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_0.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC0raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_0.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC1peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_1.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC1raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_1.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC2peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_2.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC2raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_2.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC3peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_3.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC3raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_3.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC4peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_4.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC4raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_4.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC5peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_5.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC5raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_5.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC6peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_6.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC6raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_6.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC7peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_7.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC7raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_7.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC8peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_8.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC8raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_8.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+    "FastADC9peaks": {'source':'SCS_UTC1_MCP/ADC/1:channel_9.output',
+                'key':'data.peaks',
+                'dim':['peakId']},
+    "FastADC9raw": {'source':'SCS_UTC1_MCP/ADC/1:channel_9.output',
+                'key':'data.rawData',
+                'dim':['samplesId']},
+
     # KARABACON
     "KARABACON": {'source':'SCS_DAQ_SCAN/MDL/KARABACON',
                     'key': 'actualStep.value',
diff --git a/xgm.py b/xgm.py
index 5b292f64a1a03c9d5f861cf6c53fd5f12729b74c..9b62b14a332b21be5e3a4daf3388657f7c0fd935 100644
--- a/xgm.py
+++ b/xgm.py
@@ -10,6 +10,7 @@ import numpy as np
 import xarray as xr
 
 
+# Machine
 def pulsePatternInfo(data, plot=False):
     ''' display general information on the pulse patterns operated by SASE1 and SASE3.
         This is useful to track changes of number of pulses or mode of operation of
@@ -114,6 +115,7 @@ def repRate(data, sase='sase3'):
     return f
     
             
+# XGM
 def selectSASEinXGM(data, sase='sase3', xgm='SCS_XGM', sase3First=True, npulses=None):
     ''' Extract SASE1- or SASE3-only XGM data.
         There are various cases depending on i) the mode of operation (10 Hz
@@ -385,6 +387,7 @@ def calibrateXGMs(data, rollingWindow=200, plot=False):
     return np.array([sa3_calib_factor, scs_calib_factor])
 
 
+# TIM
 def mcpPeaks(data, intstart, intstop, bkgstart, bkgstop, mcp=1, t_offset=None, npulses=None):
     ''' Computes peak integration from raw MCP traces.
     
@@ -844,4 +847,93 @@ def matchXgmTimPulseId(data, use_apd=True, intstart=None, intstop=None,
                 dropList.append('MCP{}apd'.format(mcp))
     mergeList.append(data.drop(dropList))
     subset = xr.merge(mergeList, join='inner')
+    subset.attrs['run'] = data.attrs['run']
     return subset
+
+# Fast ADC
+def fastAdcPeaks(data, channel, intstart, intstop, bkgstart, bkgstop, period=None, npulses=None):
+    ''' Computes peak integration from raw FastADC traces.
+    
+        Inputs:
+            data: xarray Dataset containing FastADC raw traces (e.g. 'FastADC1raw')
+            channel: FastADC channel number
+            intstart: trace index of integration start
+            intstop: trace index of integration stop
+            bkgstart: trace index of background start
+            bkgstop: trace index of background stop
+            period: number of samples between two pulses. Needed if bunch
+                pattern info is not available. If None, checks the pulse
+                pattern and determine the period assuming a resolution of
+                9.23 ns per sample which leads to 24 samples between
+                two bunches @ 4.5 MHz. 
+            npulses: number of pulses. If None, takes the maximum number of
+                pulses according to the bunch patter (field 'npulses_sase3')
+            
+        Output:
+            results: DataArray with dims trainId x max(sase3 pulses) 
+            
+    '''
+    keyraw = 'FastADC{}raw'.format(channel)
+    if keyraw not in data:
+        raise ValueError("Source not found: {}!".format(keyraw))
+    if npulses is None:
+        npulses = int(data['npulses_sase3'].max().values)
+    if period is None:
+        sa3 = data['sase3'].where(data['sase3']>1)
+        if npulses > 1:
+            #Calculate the number of pulses between two lasing pulses (step)
+            step = sa3.where(data['npulses_sase3']>1, drop=True)[0,:2].values
+            step = int(step[1] - step[0])
+            #multiply by elementary pulse length (221.5 ns / 9.23 ns = 24 samples)
+            period = 24 * step
+        else:
+            period = 1
+    results = xr.DataArray(np.empty((data.trainId.shape[0], npulses)), coords=data[keyraw].coords,
+                           dims=['trainId', 'peakId'.format(channel)])
+    for i in range(npulses):
+        a = intstart + period*i
+        b = intstop + period*i
+        bkga = bkgstart + period*i
+        bkgb = bkgstop + period*i
+        bg = np.outer(np.median(data[keyraw][:,bkga:bkgb], axis=1), np.ones(b-a))
+        integ = np.trapz(data[keyraw][:,a:b] - bg, axis=1)
+        results[:,i] = integ
+    return results
+
+
+def mergeFastAdcPeaks(data, channel, intstart, intstop, bkgstart, bkgstop, 
+                      period=None, npulses=None, dim='lasPulseId'):
+    ''' Calculates the peaks from Fast ADC raw traces with fastAdcPeaks()
+        and merges the results in Dataset.
+        Inputs:
+            data: xr Dataset with 'FastADC[channel]raw' traces
+            channel: Fast ADC channel
+            intstart: trace index of integration start
+            intstop: trace index of integration stop
+            bkgstart: trace index of background start
+            bkgstop: trace index of background stop
+            period: Number of samples separation between two pulses. Needed
+                if bunch pattern info is not available. If None, checks the 
+                pulse pattern and determine the period assuming a resolution
+                of 9.23 ns per sample which leads to 24 samples between
+                two bunches @ 4.5 MHz. 
+            npulses: number of pulses. If None, takes the maximum number of
+                pulses according to the bunch patter (field 'npulses_sase3')
+            dim: name of the xr dataset dimension along the peaks
+            
+    '''
+    peaks = fastAdcPeaks(data, channel=channel, intstart=intstart, intstop=intstop,
+                         bkgstart=bkgstart, bkgstop=bkgstop, period=period,
+                         npulses=npulses)
+    
+    key = 'FastADC{}peaks'.format(channel) 
+    if key in data:
+        s = data.drop(key)
+    else:
+        s = data
+    peaks = peaks.rename(key).rename({'peakId':dim})
+    subset = xr.merge([s, peaks], join='inner')
+    subset.attrs['run'] = data.attrs['run']
+    return subset
+
+