diff --git a/cfel_crystfel.py b/cfel_crystfel.py
index 911b63cfe4cdf4f7b9ea7f27030e985e7f2e063f..553984fc5f6b5acb95e4aea0de0e52f525b4dcb1 100644
--- a/cfel_crystfel.py
+++ b/cfel_crystfel.py
@@ -329,6 +329,23 @@ def _find_min_max_d(detector):
 
 
 def load_crystfel_geometry(filename):
+    """Loads a CrystFEL geometry file into a dictionary.
+    
+    Reimplements the get_detector_geometry_2 function from CrystFEL amost verbatim. Returns a dictionary with the
+    geometry information. Entries in the geometry file appears as keys in the returned dictionary. For a full
+    documentation on the CrystFEL geometry format, see:
+    
+    tfel/manual-crystfel_geometry.html
+    
+    Args:
+        
+        filename (str): filename of the geometry file
+        
+    Returns:
+        
+        detector (dict): dictionary with the geometry loaded from the file
+    
+    """
 
     fh = open(filename, 'r')
 
diff --git a/cfel_cxi.py b/cfel_cxi.py
index 557ef805e64cafdf12caba152c7b1cc1e0314ce2..e338672910c1cca4256e2b352fdd345fc5a933e8 100644
--- a/cfel_cxi.py
+++ b/cfel_cxi.py
@@ -13,9 +13,11 @@
 #    You should have received a copy of the GNU General Public License
 #    along with cfelpyutils.  If not, see <http://www.gnu.org/licenses/>.
 """
-Utilities for interoperability with the CrystFEL software package.
+Utilities for writing multi-event files in the CXIDB format.
 
-This module contains reimplementation of Crystfel functions and utilities.
+This module contains utilities to write files that adhere to the CXIDB file format: 
+
+http://www.cxidb.org/cxi.html .
 """
 
 from __future__ import absolute_import
@@ -94,7 +96,80 @@ def _validate_data(data):
 
 
 class CXIWriter:
+    """Writing of multi-event CXIDB files.
+
+    Implements a simple low-level CXIDB file format writer for multi event files. it allows the user to write data
+    "stacks" in the CXIDB files, making sure that the entries in all stacks are synchronized. 
+    
+    A CXI Writer instance manages one file. A user can add a stack to a CXI Writer instance with the
+    add_stack_to_writer function, which also writes the first entry in the stack. The user can then add to the writer 
+    all the stacks that he wants in the file. Once all stacks are added, the user initializes them  with the
+    initialize_stacks function. After initialization, no more stacks can be added. Instead, entries can be appended to
+    the existing stacks, using the append_data_to_stack function. 
+    
+    A "slice" (a set of synced entries in all the stacks in the file) can be written to the a file only after an entry
+    has been appended to all stacks in the file. Conversely, after an entry has been appended to a stack, the user
+    cannot append another entry before a slice is written. This ensures synchronization of the data in all the stacks.
+    
+    A file can be closed at any time. In any case, the writer will not allow a file to contain more than the
+    number_of_entries specified during instantiation.
+    
+    Simple non-stack entries can be written to the file at any time, before or after stack initialization (provided of
+    course that the file is open). Entries and stacks will general never be overwritten unless the overwrite parameter
+    is set to True.
+    
+    Example of usage of the stack API:
+    
+        c1 = 0
+        c2 = 0
+    
+        f1 = CXIWriter('/data/test1.h5', )
+        f2 = CXIWriter('/data/test2.h5', )
+    
+        f1.add_stack_to_writer('detector1', '/entry_1/detector_1/data', numpy.random.rand(2, 2))
+        f2.add_stack_to_writer('detector2', '/entry_1/detector_1/data', numpy.random.rand(3, 2))
+    
+        f1.add_stack_to_writer('counter1', '/entry_1/detector_1/count', c1)
+        f2.add_stack_to_writer('counter2', '/entry_1/detector_1/count', c2)
+    
+        f1.write_simple_entry('/entry_1/detector_1/name', 'FrontCSPAD')
+        f2.write_simple_entry('/entry_1/detector_1/name', 'BackCSPAD')
+    
+        f1.initialize_stacks()
+        f2.initialize_stacks()
+    
+        for i in range(1, 60):
+            print('Writing slice:', i)
+            a = numpy.random.rand(2, 2)
+            b = numpy.random.rand(2, 2)
+    
+            c1 += 1
+            c2 += 2
+    
+            f1.append_data_to_stack('detector1', a)
+            f2.append_data_to_stack('detector2', b)
+    
+            f1.append_data_to_stack('counter1', c1)
+            f2.append_data_to_stack('counter2', c2)
+    
+            f1.write_stack_slice_and_increment()
+            f2.write_stack_slice_and_increment()
+    
+        f1.close_file()
+        f2.close_file()    
+    """
+
     def __init__(self, filename, max_num_slices=5000):
+        """Instantiates a CXI Writer, managing one file.
+        
+        Instantiates a CXI Writer, responsible for writing data into one file.
+        
+        Args:
+            
+            filename (str): name of the file managed by the CXI Writer
+            
+            max_num_slices (int): maximum number of slices for the stacks in the file (default 5000)
+        """
 
         self._cxi_stacks = {}
         self._pending_simple_entries = []
@@ -122,6 +197,26 @@ class CXIWriter:
         self._fh.create_dataset(entry.path, data=entry.data)
 
     def add_stack_to_writer(self, name, path, initial_data, overwrite=True):
+        """Adds a new stack to the file.
+        
+        Adds a new stack to the CXI Writer instance. The user must provide a name for the stack, that will identify
+        the stack in all subsequents operations. The user must also provide the data that will be written as the
+        initial entry in the stack (initial_data). This initial entry is used to set the size and type of data that the
+        stack will hold and these parameters are in turn be used to validate all data that is subsequently appended to
+        the stack.
+        
+        Args:
+            
+            name (str): stack name.
+            
+            path (str): path in the hdf5 file where the stack will be written.
+            
+            initial_data (Union: numpy.ndarray, str, int, float): initial entry in the stack. It gets written to the 
+            stack as slice 0. Its characteristics are used to validate all data subsequently appended to the stack.
+            
+            overwrite (bool): if set to True, a stack already existing at the same location will be overwritten. If set
+            to False, an attempt to overwrite a stack will raise an error.
+        """
 
         _validate_data(initial_data)
 
@@ -137,7 +232,21 @@ class CXIWriter:
         new_stack = _Stack(path, initial_data)
         self._cxi_stacks[name] = new_stack
 
-    def write_entry(self, path, data, overwrite=False):
+    def write_simple_entry(self, path, data, overwrite=False):
+        """Writes a simple, non-stack entry in the file.
+        
+        Writes a simple, non-stack entry in the file, at the specified path. A simple entry can be written at all times,
+        before or after the stack initialization.
+        
+        Args:
+        
+            path (str): path in the hdf5 file where the entry will be written.
+            
+            data (Union: numpy.ndarray, str, int, float): data to write
+            
+            overwrite (bool): if set to True, an entry already existing at the same location will be overwritten. If set
+            to False, an attempt to overwrite an entry will raise an error.
+        """
 
         _validate_data(data)
 
@@ -150,6 +259,11 @@ class CXIWriter:
             self._write_simple_entry(new_entry)
 
     def initialize_stacks(self):
+        """Initializes the stacks.
+        
+        Initializes the stacks in the CXI Writer instance. This fixes the number and type of stacks in the file. No 
+        stacks can be added to the CXI Writer after initialization.
+        """
 
         if self._file_is_open is not True:
             raise RuntimeError('The file is closed. Cannot initialize the file.')
@@ -168,7 +282,20 @@ class CXIWriter:
 
         self._initialized = True
 
-    def append_to_stack(self, name, data):
+    def append_data_to_stack(self, name, data):
+        """Appends data to a stack.
+        
+        Appends data to a stack, validating the data to make sure that the data type and size match the previous entries
+        in the stack. Only one entry can be appended to each stack before writing a slice across all stacks with
+        the write_slice_and_increment.
+        
+        Args:
+            
+            name (str): stack name, defining the stack to which the data will be appended.
+            
+            data (Union: numpy.ndarray, str, int, float): data to write. The data will be validated against the type
+            and size of previous entries in the stack.
+        """
 
         _validate_data(data)
 
@@ -184,6 +311,13 @@ class CXIWriter:
             raise RuntimeError('Error appending to stack {}: {}'.format(name, e))
 
     def write_stack_slice_and_increment(self):
+        """Writes a slice across all stacks and resets the writer for the next slice.
+        
+        Writes a slice across all stacks in the file. It checks that an entry has been appended to each stack, and
+        writes all the entries on top of the relevant stacks in one go. If an entry is missing in a stack, the function
+        will raise an error. After writing the slice, the function resets the writer to allow again appending data to 
+        the stacks.
+        """
 
         if self._file_is_open is not True:
             raise RuntimeError('The file is closed. The slice cannot be written.')
@@ -196,7 +330,7 @@ class CXIWriter:
 
         for entry in self._cxi_stacks.values():
             if entry._data_to_write is None:
-                raise RuntimeError('The slice is incomplete and will not be written. The following stac is not '
+                raise RuntimeError('The slice is incomplete and will not be written. The following stack is not '
                                    'present in the current slice:', entry.path)
 
         for entry in self._cxi_stacks.values():
@@ -205,6 +339,15 @@ class CXIWriter:
         self._curr_slice += 1
 
     def get_file_handle(self):
+        """Access to the naked h5py file handle.
+        
+        This function allows access to the a naked h5py handle for the file managed by the CXI Writer. This allowa
+        operations on the file that are not covered by  CXI Writer API. Use it at your own risk.
+        
+        Returns:
+            
+            fh (h5py.File): an h5py file handle to the file managed by the writer.
+        """
 
         if self._file_is_open is not True:
             raise RuntimeError('The file is closed. Cannot get the file handle.')
@@ -212,6 +355,10 @@ class CXIWriter:
         return self._fh
 
     def close_file(self):
+        """Closes the file.
+        
+        Closes the file for writing, ending all writing operations.
+        """
 
         if self._file_is_open is not True:
             raise RuntimeError('The file is already closed. Cannot close the file.')
@@ -221,45 +368,4 @@ class CXIWriter:
 
         self._fh.close()
 
-        self._file_is_open = False
-
-
-if __name__ == "__main__":
-
-    c1 = 0
-    c2 = 0
-
-    f1 = CXIWriter('/data/test1.h5', )
-    f2 = CXIWriter('/data/test2.h5', )
-
-    f1.add_stack_to_writer('detector1', '/entry_1/detector_1/data', numpy.random.rand(2, 2))
-    f2.add_stack_to_writer('detector2', '/entry_1/detector_1/data', numpy.random.rand(3, 2))
-
-    f1.add_stack_to_writer('counter1', '/entry_1/detector_1/count', c1)
-    f2.add_stack_to_writer('counter2', '/entry_1/detector_1/count', c2)
-
-    f1.write_entry('/entry_1/detector_1/name', 'FrontCSPAD')
-    f2.write_entry('/entry_1/detector_1/name', 'BackCSPAD')
-
-    f1.initialize_stacks()
-    f2.initialize_stacks()
-
-    for i in range(1, 60):
-        print('Writing slice:', i)
-        a = numpy.random.rand(2, 2)
-        b = numpy.random.rand(2, 2)
-
-        c1 += 1
-        c2 += 2
-
-        f1.append_to_stack('detector1', a)
-        f2.append_to_stack('detector2', b)
-
-        f1.append_to_stack('counter1', c1)
-        f2.append_to_stack('counter2', c2)
-
-        f1.write_stack_slice_and_increment()
-        f2.write_stack_slice_and_increment()
-
-    f1.close_file()
-    f2.close_file()
+        self._file_is_open = False
\ No newline at end of file