diff --git a/cfel_fabio.py b/cfel_fabio.py
new file mode 100644
index 0000000000000000000000000000000000000000..7edc689eab8b36da91ad536a790858df059a0d9b
--- /dev/null
+++ b/cfel_fabio.py
@@ -0,0 +1,88 @@
+#    This file is part of cfelpyutils.
+#
+#    cfelpyutils is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    cfelpyutils is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with cfelpyutils.  If not, see <http://www.gnu.org/licenses/>.
+"""
+Utilities based on the fabio python module.
+
+This module contains utilities based on the fabio python module.
+files.
+"""
+
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import numpy
+import fabio.cbfimage
+
+
+def read_cbf_from_stream(stream):
+    """Reads a cbfimage object out of a data string buffer.
+
+    Read a data string buffer received as a payload from the PETRAIII P11 sender, and creates a cbfimage object from
+    it (See the documentation of the fabio python module).
+
+    Args:
+
+       stream (str): a data string buffer received from the PETRAIII P11 sender.
+
+    Returns:
+
+        cbf_obj (fabio.cbfimage): a cbfimage object containing the data extracted
+            from the string buffer.
+    """
+
+    cbf_obj = fabio.cbfimage.cbfimage()
+
+    cbf_obj.header = {}
+    cbf_obj.resetvals()
+
+    infile = stream
+    cbf_obj._readheader(infile)
+    if fabio.cbfimage.CIF_BINARY_BLOCK_KEY not in cbf_obj.cif:
+        err = "Not key %s in CIF, no CBF image in stream" % fabio.cbfimage.CIF_BINARY_BLOCK_KEY
+        logger.error(err)
+        for kv in cbf_obj.cif.items():
+            print("%s: %s" % kv)
+        raise RuntimeError(err)
+    if cbf_obj.cif[fabio.cbfimage.CIF_BINARY_BLOCK_KEY] == "CIF Binary Section":
+        cbf_obj.cbs += infile.read(len(fabio.cbfimage.STARTER) + int(cbf_obj.header["X-Binary-Size"])
+                                   - len(cbf_obj.cbs) + cbf_obj.start_binary)
+    else:
+        if len(cbf_obj.cif[fabio.cbfimage.CIF_BINARY_BLOCK_KEY]) > int(
+                cbf_obj.header["X-Binary-Size"]) + cbf_obj.start_binary + len(fabio.cbfimage.STARTER):
+            cbf_obj.cbs = cbf_obj.cif[fabio.cbfimage.CIF_BINARY_BLOCK_KEY][:int(cbf_obj.header["X-Binary-Size"]) +
+                                                                           cbf_obj.start_binary +
+                                                                           len(fabio.cbfimage.STARTER)]
+        else:
+            cbf_obj.cbs = cbf_obj.cif[fabio.cbfimage.CIF_BINARY_BLOCK_KEY]
+    binary_data = cbf_obj.cbs[cbf_obj.start_binary + len(fabio.cbfimage.STARTER):]
+
+    if "Content-MD5" in cbf_obj.header:
+        ref = numpy.string_(cbf_obj.header["Content-MD5"])
+        obt = fabio.cbfimage.md5sum(binary_data)
+        if ref != obt:
+            logger.error("Checksum of binary data mismatch: expected %s, got %s" % (ref, obt))
+
+    if cbf_obj.header["conversions"] == "x-CBF_BYTE_OFFSET":
+        cbf_obj.data = cbf_obj._readbinary_byte_offset(binary_data).astype(cbf_obj.bytecode).reshape(
+            (cbf_obj.dim2, cbf_obj.dim1))
+    else:
+        raise Exception(IOError, "Compression scheme not yet supported, please contact the author")
+
+    cbf_obj.resetvals()
+    # ensure the PIL image is reset
+    cbf_obj.pilimage = None
+    return cbf_obj
diff --git a/cfelgeom.py b/cfel_geom.py
similarity index 73%
rename from cfelgeom.py
rename to cfel_geom.py
index 9711c1b8b085381dd43f2519a3571167f33701f2..0f5937e69ceded764be1da63bd84ad6a8e9f6acf 100644
--- a/cfelgeom.py
+++ b/cfel_geom.py
@@ -19,15 +19,20 @@ This module contains utilities for the processing of CrystFEL-style geometry
 files.
 """
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
 
 import numpy
 
 
 def apply_geometry_from_file(data_as_slab, geometry_filename):
-    """Parse a geometry file and applies the geometry to detector data in 'slab' format.
-    Turns a 2d array of pixel values into an array containing a representation of the
-    physical layout of the detector, keeping the origin of the  reference system at the
-    beam interaction point.
+    """Parses a geometry file and applies the geometry to data.
+
+    Parses a geometry file and applies the geometry to detector data in 'slab' format. Turns a 2d array of pixel
+    values into an array containing a representation of the physical layout of the detector, keeping the origin of
+    the reference system at the beam interaction point.
 
     Args:
 
@@ -37,9 +42,8 @@ def apply_geometry_from_file(data_as_slab, geometry_filename):
 
     Returns:
 
-        im_out (numpy.ndarray data_as_slab.dtype): Array containing a representation of the
-        physical layout of the detector, with the origin of the  reference system at the
-        beam interaction point.
+        im_out (numpy.ndarray data_as_slab.dtype): Array containing a representation of the physical layout of the
+        detector, with the origin of the  reference system at the beam interaction point.
     """
 
     yx, slab_shape, img_shape = pixel_maps_for_image_view(geometry_filename)
@@ -50,10 +54,11 @@ def apply_geometry_from_file(data_as_slab, geometry_filename):
 
 
 def apply_geometry_from_pixel_maps(data_as_slab, yx, im_out=None):
-    """Applies geometry, in the form of pixel maps, to detector data in 'slab' format.
-    Turns a 2d array of pixel values into an array containing a representation of the
-    physical layout of the detector, keeping the origin of the  reference system at the
-    beam interaction point.
+    """Applies geometry in pixel map format to data.
+
+    Applies geometry, in the form of pixel maps, to detector data in 'slab' format. Turns a 2d array of pixel values
+    into an array containing a representation of the physical layout of the detector, keeping the origin of the
+    reference system at the beam interaction point.
 
     Args:
 
@@ -61,15 +66,15 @@ def apply_geometry_from_pixel_maps(data_as_slab, yx, im_out=None):
 
         yx (tuple): the yx pixel maps describing the geometry of the detector; each map is a numpy.ndarray.
 
-        im_out (Optional[numpy.ndarray]): array to hold the output; if not provided, one will be generated automatically.
-
+        im_out (Optional[numpy.ndarray]): array to hold the output; if not provided, one will be generated
+        automatically.
 
     Returns:
 
-        im_out (numpy.ndarray data_as_slab.dtype): Array containing a representation of the
-        physical layout of the detector, with the origin of the  reference system at the
-        beam interaction point.
+        im_out (numpy.ndarray data_as_slab.dtype): Array containing a representation of the physical layout of the
+        detector, with the origin of the  reference system at the beam interaction point.
     """
+
     if im_out is None:
         im_out = numpy.zeros(data_as_slab.shape, dtype=data_as_slab.dtype)
 
@@ -78,11 +83,12 @@ def apply_geometry_from_pixel_maps(data_as_slab, yx, im_out=None):
 
 
 def pixel_maps_for_image_view(geometry_filename):
-    """Parse the geometry file and pixel maps for an  array in 'slab' format
-    containing pixel values. The pixel maps can be used to create a representation
-    of the physical layout of the detector in a pyqtgraph ImageView widget (i.e.
-    they apply the detector geometry setting the origin of the reference
-    system is in the top left corner of the output array).
+    """Parses a geometry file and creates pixel maps for pyqtgraph visualization.
+
+    Parse the geometry file and creates pixel maps for an  array in 'slab' format containing pixel values. The pixel
+    maps can be used to create a representation of the physical layout of the detector in a pyqtgraph ImageView
+    widget (i.e. they apply the detector geometry setting the origin of the reference system is in the top left corner
+    of the output array).
 
     Args:
 
@@ -92,12 +98,13 @@ def pixel_maps_for_image_view(geometry_filename):
 
         (y, x) (numpy.ndarray int, numpy.ndarray int): pixel maps
 
-        slab_shape tuple (int, int): shape of the original geometry uncorrected array
-        (the pixel values in "slab" format).
+        slab_shape tuple (int, int): shape of the original geometry uncorrected array (the pixel values in "slab"
+        format).
 
-        img_shape tuple (int, int): shape of the array needed to contain the
-        representation of the physical layout of the detector.
+        img_shape tuple (int, int): shape of the array needed to contain the representation of the physical layout
+        of the detector.
     """
+
     pixm = pixel_maps_from_geometry_file(geometry_filename)
     x, y = pixm[0], pixm[1]
     slab_shape = x.shape
@@ -117,8 +124,9 @@ def pixel_maps_for_image_view(geometry_filename):
 
 
 def parse_xy(string):
-    """Parse the x, y values from strings that have the format:
-    '1x + 2.0y'.
+    """Extracts x and y values from strings in a geometry file.
+
+    Parse the x, y values from strings in that have the format: '1x + 2.0y'.
 
     Args:
 
@@ -128,6 +136,7 @@ def parse_xy(string):
 
         x, y (float, float): the values of x and y.
     """
+
     x = y = 0
 
     if string.find('x') is not -1:
@@ -147,9 +156,10 @@ def parse_xy(string):
 
 
 def pixel_maps_from_geometry_file(fnam):
-    """Extracts pixel maps from a CrystFEL-style geometry file. The pixel maps
-    can be used to create a representation of the physical layout of the
-    detector, keeping the origin of the  reference system at the beam interaction
+    """Parses a geometry file and creates pixel maps.
+
+    Extracts pixel maps from a CrystFEL-style geometry file. The pixel maps can be used to create a representation of
+    the physical layout of the detector, keeping the origin of the  reference system at the beam interaction
     point.
 
     Args:
@@ -158,9 +168,8 @@ def pixel_maps_from_geometry_file(fnam):
 
     Returns:
 
-        x,y,r (numpy.ndarray float, numpy.ndarray float, numpy.ndarray float):
-        slab-like pixel maps with respectively x, y coordinates of the pixel
-        and distance of the pixel from the center of the reference system
+        x,y,r (numpy.ndarray float, numpy.ndarray float, numpy.ndarray float): slab-like pixel maps with
+        respectively x, y coordinates of the pixel and distance of the pixel from the center of the reference system.
     """
 
     f = open(fnam, 'r')
@@ -231,8 +240,9 @@ def pixel_maps_from_geometry_file(fnam):
 
 
 def coffset_from_geometry_file(fnam):
-    """Extracts detector distance offset information from a CrystFEL-style
-       geometry file.
+    """Extracts detector distance information from a geometry file.
+
+    Extracts detector distance offset information from a CrystFEL-style geometry file.
 
     Args:
 
@@ -242,6 +252,7 @@ def coffset_from_geometry_file(fnam):
 
         coffset (float): the detector distance offset
     """
+
     f = open(fnam, 'r')
     f_lines = f.readlines()
     f.close()
@@ -256,8 +267,9 @@ def coffset_from_geometry_file(fnam):
 
 
 def res_from_geometry_file(fnam):
-    """Extracts pixel resolution information from a CrystFEL-style
-       geometry file.
+    """Extracts pixel resolution information from a geometry file.
+
+    Extracts pixel resolution information from a CrystFEL-style geometry file.
 
     Args:
 
@@ -267,6 +279,7 @@ def res_from_geometry_file(fnam):
 
         res (float): the pixel resolution
     """
+
     f = open(fnam, 'r')
     f_lines = f.readlines()
     f.close()
diff --git a/cfelhdf5.py b/cfel_hdf5.py
similarity index 73%
rename from cfelhdf5.py
rename to cfel_hdf5.py
index 76946ae893549650b22a1cb95dd3640e30da1259..a789c314dc4746bbec49fbb0569ee8468520f655 100644
--- a/cfelhdf5.py
+++ b/cfel_hdf5.py
@@ -19,9 +19,13 @@ This module contains utilities for the processing of HDF5. This module builds
 on what the h5py module already provides.
 """
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
 
-import numpy
 import h5py
+import numpy
 
 
 def load_nparray_from_hdf5_file(data_filename, data_group):
@@ -37,8 +41,11 @@ def load_nparray_from_hdf5_file(data_filename, data_group):
 
        nparray (numpy.ndarray): numpy array with the data read from the file.
     """
-
-    hdfile = h5py.File(data_filename, 'r')
-    nparray = numpy.array(hdfile[data_group])
-    hdfile.close()
-    return nparray
+    try:
+        with h5py.File(data_filename, 'r') as hdfile:
+            nparray = numpy.array(hdfile[data_group])
+            hdfile.close()
+    except:
+        raise RuntimeError('Error reading file {0} (data block: {1}).'.format(data_filename, data_group))
+    else:
+        return nparray
diff --git a/cfeloptarg.py b/cfel_optarg.py
similarity index 81%
rename from cfeloptarg.py
rename to cfel_optarg.py
index e3746d3c50ca023759e9090f8cc9f92afd4b156b..40ec42061321e1b21f2b6390b3d7459a284d5a35 100644
--- a/cfeloptarg.py
+++ b/cfel_optarg.py
@@ -14,6 +14,12 @@
 #    along with cfelpyutils.  If not, see <http://www.gnu.org/licenses/>.
 
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+
 """
 Utilities for parsing command line options and configuration files.
 
@@ -22,30 +28,20 @@ configuration files.
 """
 
 
-import argparse
-import os
-
-
 def parse_parameters(config):
     """Sets correct types for parameter dictionaries.
 
-    Reads a parameter dictionary returned by the ConfigParser python modue,
-    and assigns correct types to parameters, without changing the structure of
-    the dictionary.
+    Reads a parameter dictionary returned by the ConfigParser python module, and assigns correct types to parameters,
+    without changing the structure of the dictionary.
 
-    The parser tries to interpret each entry in the dictionary according to the
-    following rules:
+    The parser tries to interpret each entry in the dictionary according to the following rules:
 
-    - If the entry starts and ends with a single quote, it is interpreted as a
-      string.
-    - If the entry is the word None, without quotes, then the entry is
-      interpreted as NoneType.
-    - If the entry is the word False, without quotes, then the entry is
-      interpreted as a boolean False.
-    - If the entry is the word True, without quotes, then the entry is
-      interpreted as a boolean True.
-    - If non of the previous options match the content of the entry,
-      the parser tries to interpret the entry in order as:
+    - If the entry starts and ends with a single quote, it is interpreted as a string.
+    - If the entry is the word None, without quotes, then the entry is interpreted as NoneType.
+    - If the entry is the word False, without quotes, then the entry is interpreted as a boolean False.
+    - If the entry is the word True, without quotes, then the entry is interpreted as a boolean True.
+    - If non of the previous options match the content of the entry, the parser tries to interpret the entry in order
+      as:
 
         - An integer number.
         - A float number.
@@ -59,8 +55,8 @@ def parse_parameters(config):
 
     Returns:
 
-        monitor_params (dict): dictionary with the same structure as the input
-        dictionary, but with correct types assigned to each entry.
+        monitor_params (dict): dictionary with the same structure as the input dictionary, but with correct types
+        assigned to each entry.
     """
 
     monitor_params = {}
@@ -84,11 +80,11 @@ def parse_parameters(config):
             try:
                 monitor_params[sect][op] = int(monitor_params[sect][op])
                 continue
-            except:
+            except ValueError:
                 try:
                     monitor_params[sect][op] = float(monitor_params[sect][op])
                     continue
-                except:
+                except ValueError:
                     pass
 
     return monitor_params
diff --git a/cfelpsana.py b/cfel_psana.py
similarity index 76%
rename from cfelpsana.py
rename to cfel_psana.py
index bdead5d49ecefdd5f3de2916d04aba176ca08b55..f17d8e9f73bfff48878b53effddb1020894b27d1 100644
--- a/cfelpsana.py
+++ b/cfel_psana.py
@@ -17,11 +17,16 @@
 """
 Utilities based on the psana python module.
 
-This module provides utilities that build on the functionality provided by the
-psana python module.
+This module provides utilities that build on the functionality provided by the psana python module.
 """
 
 
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+
 def psana_obj_from_string(name):
     """Converts a string into a psana object type.
 
@@ -46,9 +51,8 @@ def psana_obj_from_string(name):
 def psana_event_inspection(source):
     """Prints the structure of psana events.
 
-    Takes a psana source string (e.g. exp=CXI/cxix....) and inspects the
-    structure of the first event in the data, printing information about
-    the the content of the event.
+    Takes a psana source string (e.g. exp=CXI/cxix....) and inspects the structure of the first event in the data,
+    printing information about the the content of the event.
 
     Args:
 
@@ -57,22 +61,8 @@ def psana_event_inspection(source):
 
     import psana
 
-    def my_import(name):
-        mod = __import__(name)
-        components = name.split('.')
-        for comp in components[1:]:
-            mod = getattr(mod, comp)
-        return mod
-
-    def my_psana_from_string(name):
-        components = name.split('.')
-        mod = __import__(components[0])
-        for comp in components[1:]:
-            mod = getattr(mod, comp)
-        return mod
-
     print('\n\n')
-    print('data source : %s' % source)
+    print('data source :', source)
 
     print('\n')
     print('Opening dataset...')
@@ -91,8 +81,8 @@ def psana_event_inspection(source):
     itr = ds.events()
     evt = itr.next()
     for k in evt.keys():
-        print('Type: %s   Source: %s   Alias: %s   Key: %s') % (k.type(), k.src(), k.alias(), k.key())
-        print('\n')
+        print('Type: {0}   Source: {1}   Alias: {2}   Key: {3}'.format(k.type(), k.src(), k.alias(), k.key()))
+        print('')
 
     for k in evt.keys():
         print(k)
@@ -104,9 +94,8 @@ def psana_event_inspection(source):
 def dirname_from_source_runs(source):
     """Returns a directory name based on a psana source string.
 
-    Takes a psana source string (e.g exp=CXI/cxix....) and returns
-    a string that can be used as a subdirectory name or a prefix for files and
-    directories.
+    Takes a psana source string (e.g exp=CXI/cxix....) and returns a string that can be used as a subdirectory name or
+    a prefix for files and directories.
 
     Args:
 
@@ -125,5 +114,5 @@ def dirname_from_source_runs(source):
     nums = runs.split(',')
     if len(nums) == 0:
         nums = runs
-    dirname = 'run_' + "_".join(nums)
+    dirname = 'run_' + '_'.join(nums)
     return dirname
diff --git a/cfelfabio.py b/cfelfabio.py
deleted file mode 100644
index ac7a46d951c2c851e216e443b28c378cc7197b6f..0000000000000000000000000000000000000000
--- a/cfelfabio.py
+++ /dev/null
@@ -1,57 +0,0 @@
-import numpy
-import fabio.cbfimage
-
-def read_cbf_from_stream(stream):
-    """Reads a cbfimage object out of a data string buffer.
-
-    Read a data string buffer received as a payload from the PETRAIII P11 sender,
-    and creates a cbfimage object from it (See the documentation of the fabio
-    python module).
-
-    Args:
-
-       stream (str): a data string buffer received from the PETRAIII P11 sender.
-
-    Returns:
-
-        cbf_obj (fabio.cbfimage): a cbfimage object containing the data extracted
-            from the string buffer.
-    """
-
-    cbf_obj = fabio.cbfimage.cbfimage()
-
-    cbf_obj.header = {}
-    cbf_obj.resetvals()
-
-    infile = stream
-    cbf_obj._readheader(infile)
-    if fabio.cbfimage.CIF_BINARY_BLOCK_KEY not in cbf_obj.cif:
-        err = "Not key %s in CIF, no CBF image in stream" % (fabio.cbfimage.CIF_BINARY_BLOCK_KEY)
-        logger.error(err)
-        for kv in cbf_obj.cif.items():
-            print("%s: %s" % kv)
-        raise RuntimeError(err)
-    if cbf_obj.cif[fabio.cbfimage.CIF_BINARY_BLOCK_KEY] == "CIF Binary Section":
-        cbf_obj.cbs += infile.read(len(fabio.cbfimage.STARTER) + int(cbf_obj.header["X-Binary-Size"]) - len(cbf_obj.cbs) + cbf_obj.start_binary)
-    else:
-        if len(cbf_obj.cif[fabio.cbfimage.CIF_BINARY_BLOCK_KEY]) > int(cbf_obj.header["X-Binary-Size"]) + cbf_obj.start_binary + len(fabio.cbfimage.STARTER):
-            cbf_obj.cbs = cbf_obj.cif[fabio.cbfimage.CIF_BINARY_BLOCK_KEY][:int(cbf_obj.header["X-Binary-Size"]) + cbf_obj.start_binary + len(fabio.cbfimage.STARTER)]
-        else:
-            cbf_obj.cbs = cbf_obj.cif[fabio.cbfimage.CIF_BINARY_BLOCK_KEY]
-    binary_data = cbf_obj.cbs[cbf_obj.start_binary + len(fabio.cbfimage.STARTER):]
-
-    if "Content-MD5" in cbf_obj.header:
-            ref = numpy.string_(cbf_obj.header["Content-MD5"])
-            obt = fabio.cbfimage.md5sum(binary_data)
-            if ref != obt:
-                logger.error("Checksum of binary data mismatch: expected %s, got %s" % (ref, obt))
-
-    if cbf_obj.header["conversions"] == "x-CBF_BYTE_OFFSET":
-        cbf_obj.data = cbf_obj._readbinary_byte_offset(binary_data).astype(cbf_obj.bytecode).reshape((cbf_obj.dim2, cbf_obj.dim1))
-    else:
-        raise Exception(IOError, "Compression scheme not yet supported, please contact the author")
-
-    cbf_obj.resetvals()
-    # ensure the PIL image is reset
-    cbf_obj.pilimage = None
-    return cbf_obj