diff --git a/bdaq53/analysis/analysis.py b/bdaq53/analysis/analysis.py
index b05e029e157b4478a993914c86c9e9b02b9ac11e..c329ba28d6367e889282c16d50bb58ffc2f2d40e 100644
--- a/bdaq53/analysis/analysis.py
+++ b/bdaq53/analysis/analysis.py
@@ -11,7 +11,6 @@
 
 from __future__ import division
 
-import zlib     # workaround for matplotlib segmentation fault, with Anaconda python
 import os.path
 
 import numpy as np
@@ -228,6 +227,22 @@ class Analysis(object):
             # Set end_of_cluster function for shape and distance calculation
             self.clz.set_end_of_cluster_function(end_of_cluster_function)
 
+    def _range_of_parameter(self, meta_data):
+        ''' Calculate the raw data word indeces of each scan parameter
+        '''
+        _, index = np.unique(meta_data['scan_param_id'], return_index=True)
+        expected_values = np.arange(np.max(meta_data['scan_param_id']) + 1)
+
+        # Check for scan parameter IDs with no data
+        sel = np.isin(expected_values, meta_data['scan_param_id'])
+        if not np.all(sel):
+            self.logger.warning('No words for scan parameter IDs: %s', str(expected_values[~sel]))
+
+        start = meta_data[index]['index_start']
+        stop = np.append(start[:-1] + np.diff(start), meta_data[-1]['index_stop'])
+
+        return np.column_stack((expected_values[sel], start, stop))
+
     def _words_of_parameter(self, par_range, data):
         ''' Yield all raw data words of a scan parameter
 
@@ -272,11 +287,7 @@ class Analysis(object):
         row.append()
 
         for kw, value in yaml.load(in_file.root.meta_data.attrs.kwargs).iteritems():
-            if kw not in ['start_column', 'stop_column', 'start_row', 'stop_row', 'mask_step', 'maskfile', 'disable',
-                          'n_injections', 'n_triggers', 'limit', 'VCAL_MED', 'VCAL_HIGH', 'VCAL_HIGH_start',
-                          'VCAL_HIGH_stop', 'VCAL_HIGH_step', 'VTH_start', 'VTH_stop', 'VTH_step', 'VTH_name',
-                          'vth_offset', 'DAC', 'type', 'value_start', 'value_stop', 'value_step', 'addresses',
-                          'mask_diff', 'trimbit', 'samples']:
+            if kw not in ['start_column', 'stop_column', 'start_row', 'stop_row', 'mask_step', 'maskfile', 'disable', 'n_injections', 'n_triggers', 'limit', 'VCAL_MED', 'VCAL_HIGH', 'VCAL_HIGH_start', 'VCAL_HIGH_stop', 'VCAL_HIGH_step', 'VTH_start', 'VTH_stop', 'VTH_step', 'VTH_name', 'vth_offset', 'DAC', 'type', 'value_start', 'value_stop', 'value_step', 'addresses']:
                 continue
             row = run_config_table.row
             row['attribute'] = kw
@@ -361,7 +372,7 @@ class Analysis(object):
                 self.logger.warning('Data is empty. Skip analysis!')
                 return
 
-            par_range = au.range_of_parameter(meta_data)
+            par_range = self._range_of_parameter(meta_data)
             userk_out = np.zeros(par_range.shape[0], dtype={'names': ['dac', 'adc', 'voltage'],
                                                             'formats': ['uint16', 'uint16', 'float32']})
 
@@ -426,7 +437,7 @@ class Analysis(object):
                 self.logger.warning('Data is empty. Skip analysis!')
                 return
 
-            par_range = au.range_of_parameter(meta_data)
+            par_range = self._range_of_parameter(meta_data)
             n_scan_params = np.max(meta_data['scan_param_id']) + 1
 
             (hits, hist_occ, hist_tot, hist_rel_bcid,
diff --git a/bdaq53/fifo_readout.py b/bdaq53/fifo_readout.py
index 338e00941c7dec413ccf7d9f2c9bf25d8a3a08ca..8ced4995757387822dff91158db63e466e9ee101 100644
--- a/bdaq53/fifo_readout.py
+++ b/bdaq53/fifo_readout.py
@@ -219,19 +219,17 @@ class FifoReadout(object):
                 if self.stop_readout.is_set():
                     break
             else:
-                data_words = data.shape[0]
-                if data_words > 0:
-                    last_time, curr_time = self.update_timestamp()
-                    status = 0
-                    if self.callback:
-                        self._data_deque.append((data, last_time, curr_time, status))
-                    if self.fill_buffer:
-                        self._data_buffer.append((data, last_time, curr_time, status))
-                    self._words_per_read.append(data_words)
-                elif self.stop_readout.is_set():
+                n_words = data.shape[0]
+                last_time, curr_time = self.update_timestamp()
+                status = 0
+                if self.callback:
+                    self._data_deque.append((data, last_time, curr_time, status))
+                if self.fill_buffer:
+                    self._data_buffer.append((data, last_time, curr_time, status))
+                self._words_per_read.append(n_words)
+                # FIXME: busy FE prevents scan termination? To be checked
+                if n_words == 0 and self.stop_readout.is_set():
                     break
-                else:
-                    self._words_per_read.append(0)
             finally:
                 time_wait = self.readout_interval - (time() - time_read)
             if self._calculate.is_set():