Index: DataLoader/readers/IgorReader.py
===================================================================
--- DataLoader/readers/IgorReader.py	(revision 28caa03404030faac2dd29ba6ae3e5afc427a99b)
+++ DataLoader/readers/IgorReader.py	(revision fe78c7be16b3ca74072592fdeda007c4a989ce82)
@@ -290,5 +290,6 @@
             output.zaxis("\\rm{Intensity}","cm^{-1}")
     
-        
+        # Store loading process information
+        output.meta_data['loader'] = self.type_name
         return output
     
Index: DataLoader/readers/abs_reader.py
===================================================================
--- DataLoader/readers/abs_reader.py	(revision 28caa03404030faac2dd29ba6ae3e5afc427a99b)
+++ DataLoader/readers/abs_reader.py	(revision fe78c7be16b3ca74072592fdeda007c4a989ce82)
@@ -222,4 +222,7 @@
                 else:
                     output.yaxis("\\rm{Intensity}","cm^{-1}")
+                    
+                # Store loading process information
+                output.meta_data['loader'] = self.type_name                       
                 return output
         else:
Index: DataLoader/readers/ascii_reader.py
===================================================================
--- DataLoader/readers/ascii_reader.py	(revision e082e2cfc4f00926039169b8129f6917fdf3fd4b)
+++ DataLoader/readers/ascii_reader.py	(revision fe78c7be16b3ca74072592fdeda007c4a989ce82)
@@ -308,4 +308,8 @@
                 else:
                     output.yaxis("\\rm{Intensity}","cm^{-1}")
+                    
+                # Store loading process information
+                output.meta_data['loader'] = self.type_name    
+                    
                 return output
             
Index: DataLoader/readers/cansas_reader.py
===================================================================
--- DataLoader/readers/cansas_reader.py	(revision b0d072360e8109c7e554d3115ecbe42a599dd294)
+++ DataLoader/readers/cansas_reader.py	(revision fe78c7be16b3ca74072592fdeda007c4a989ce82)
@@ -92,68 +92,5 @@
     return value, attr
 
-def _store_float(location, node, variable, storage):
-    """
-        Get the content of a xpath location and store
-        the result. Check that the units are compatible
-        with the destination. The value is expected to
-        be a float.
-        
-        The xpath location might or might not exist.
-        If it does not exist, nothing is done
-        
-        @param location: xpath location to fetch
-        @param node: node to read the data from
-        @param variable: name of the data member to store it in [string]
-        @param storage: data object that has the 'variable' data member
-        
-        @raise ValueError: raised when the units are not recognized
-    """
-    entry = get_content(location, node)
-    try:
-        value = float(entry.text)
-    except:
-        value = None
-        
-    if value is not None:
-        # If the entry has units, check to see that they are
-        # compatible with what we currently have in the data object
-        units = entry.get('unit')
-        if units is not None:
-            toks = variable.split('.')
-            exec "local_unit = storage.%s_unit" % toks[0]
-            if units.lower()!=local_unit.lower():
-                if has_converter==True:
-                    try:
-                        conv = Converter(units)
-                        exec "storage.%s = %g" % (variable, conv(value, units=local_unit))
-                    except:
-                        raise ValueError, "CanSAS reader: could not convert %s unit [%s]; expecting [%s]\n  %s" \
-                        % (variable, units, local_unit, sys.exc_value)
-                else:
-                    raise ValueError, "CanSAS reader: unrecognized %s unit [%s]; expecting [%s]" \
-                        % (variable, units, local_unit)
-            else:
-                exec "storage.%s = value" % variable
-        else:
-            exec "storage.%s = value" % variable
-            
-
-def _store_content(location, node, variable, storage):
-    """
-        Get the content of a xpath location and store
-        the result. The value is treated as a string.
-        
-        The xpath location might or might not exist.
-        If it does not exist, nothing is done
-        
-        @param location: xpath location to fetch
-        @param node: node to read the data from
-        @param variable: name of the data member to store it in [string]
-        @param storage: data object that has the 'variable' data member
-    """
-    entry = get_content(location, node)
-    if entry is not None and entry.text is not None:
-        exec "storage.%s = entry.text.strip()" % variable
-
+            
 
 class Reader:
@@ -173,4 +110,8 @@
     ext=['.xml', '.XML']  
     
+    def __init__(self):
+        ## List of errors
+        self.errors = []
+    
     def read(self, path):
         """ 
@@ -199,6 +140,11 @@
                 
                 for entry in entry_list:
+                    self.errors = []
                     sas_entry = self._parse_entry(entry)
                     sas_entry.filename = basename
+                    
+                    # Store loading process information
+                    sas_entry.errors = self.errors
+                    sas_entry.meta_data['loader'] = self.type_name
                     output.append(sas_entry)
                 
@@ -227,5 +173,5 @@
         
         # Look up title      
-        _store_content('ns:Title', dom, 'title', data_info)
+        self._store_content('ns:Title', dom, 'title', data_info)
         
         # Look up run number   
@@ -240,5 +186,5 @@
                            
         # Look up instrument name              
-        _store_content('ns:SASinstrument/ns:name', dom, 'instrument', data_info)
+        self._store_content('ns:SASinstrument/ns:name', dom, 'instrument', data_info)
 
         # Notes
@@ -251,5 +197,7 @@
                         data_info.notes.append(note_value)
             except:
-                logging.error("cansas_reader.read: error processing entry notes\n  %s" % sys.exc_value)
+                err_mess = "cansas_reader.read: error processing entry notes\n  %s" % sys.exc_value
+                self.errors.append(err_mess)
+                logging.error(err_mess)
         
         # Sample info ###################
@@ -258,11 +206,11 @@
             data_info.sample.name = entry.get('name')
             
-        _store_content('ns:SASsample/ns:ID', 
+        self._store_content('ns:SASsample/ns:ID', 
                      dom, 'ID', data_info.sample)                    
-        _store_float('ns:SASsample/ns:thickness', 
+        self._store_float('ns:SASsample/ns:thickness', 
                      dom, 'thickness', data_info.sample)
-        _store_float('ns:SASsample/ns:transmission', 
+        self._store_float('ns:SASsample/ns:transmission', 
                      dom, 'transmission', data_info.sample)
-        _store_float('ns:SASsample/ns:temperature', 
+        self._store_float('ns:SASsample/ns:temperature', 
                      dom, 'temperature', data_info.sample)
         
@@ -275,20 +223,22 @@
                         data_info.sample.details.append(detail_value)
             except:
-                logging.error("cansas_reader.read: error processing sample details\n  %s" % sys.exc_value)
+                err_mess = "cansas_reader.read: error processing sample details\n  %s" % sys.exc_value
+                self.errors.append(err_mess)
+                logging.error(err_mess)
         
         # Position (as a vector)
-        _store_float('ns:SASsample/ns:position/ns:x', 
+        self._store_float('ns:SASsample/ns:position/ns:x', 
                      dom, 'position.x', data_info.sample)          
-        _store_float('ns:SASsample/ns:position/ns:y', 
+        self._store_float('ns:SASsample/ns:position/ns:y', 
                      dom, 'position.y', data_info.sample)          
-        _store_float('ns:SASsample/ns:position/ns:z', 
+        self._store_float('ns:SASsample/ns:position/ns:z', 
                      dom, 'position.z', data_info.sample)          
         
         # Orientation (as a vector)
-        _store_float('ns:SASsample/ns:orientation/ns:roll', 
+        self._store_float('ns:SASsample/ns:orientation/ns:roll', 
                      dom, 'orientation.x', data_info.sample)          
-        _store_float('ns:SASsample/ns:orientation/ns:pitch', 
+        self._store_float('ns:SASsample/ns:orientation/ns:pitch', 
                      dom, 'orientation.y', data_info.sample)          
-        _store_float('ns:SASsample/ns:orientation/ns:yaw', 
+        self._store_float('ns:SASsample/ns:orientation/ns:yaw', 
                      dom, 'orientation.z', data_info.sample)          
        
@@ -298,15 +248,15 @@
             data_info.source.name = entry.get('name')
         
-        _store_content('ns:SASinstrument/ns:SASsource/ns:radiation', 
+        self._store_content('ns:SASinstrument/ns:SASsource/ns:radiation', 
                      dom, 'radiation', data_info.source)                    
-        _store_content('ns:SASinstrument/ns:SASsource/ns:beam_shape', 
+        self._store_content('ns:SASinstrument/ns:SASsource/ns:beam_shape', 
                      dom, 'beam_shape', data_info.source)                    
-        _store_float('ns:SASinstrument/ns:SASsource/ns:wavelength', 
+        self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength', 
                      dom, 'wavelength', data_info.source)          
-        _store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_min', 
+        self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_min', 
                      dom, 'wavelength_min', data_info.source)          
-        _store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_max', 
+        self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_max', 
                      dom, 'wavelength_max', data_info.source)          
-        _store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_spread', 
+        self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_spread', 
                      dom, 'wavelength_spread', data_info.source)    
         
@@ -316,9 +266,9 @@
             data_info.source.beam_size_name = entry.get('name')
             
-        _store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:x', 
+        self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:x', 
                      dom, 'beam_size.x', data_info.source)    
-        _store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:y', 
+        self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:y', 
                      dom, 'beam_size.y', data_info.source)    
-        _store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:z', 
+        self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:z', 
                      dom, 'beam_size.z', data_info.source)    
         
@@ -329,5 +279,5 @@
             if item.get('name') is not None:
                 collim.name = item.get('name')
-            _store_float('ns:length', item, 'length', collim)  
+            self._store_float('ns:length', item, 'length', collim)  
             
             # Look for apertures
@@ -340,5 +290,5 @@
                 aperture.type = apert.get('type')
                     
-                _store_float('ns:distance', apert, 'distance', aperture)    
+                self._store_float('ns:distance', apert, 'distance', aperture)    
                 
                 entry = get_content('ns:size', apert)
@@ -346,7 +296,7 @@
                     aperture.size_name = entry.get('name')
                 
-                _store_float('ns:size/ns:x', apert, 'size.x', aperture)    
-                _store_float('ns:size/ns:y', apert, 'size.y', aperture)    
-                _store_float('ns:size/ns:z', apert, 'size.z', aperture)
+                self._store_float('ns:size/ns:x', apert, 'size.x', aperture)    
+                self._store_float('ns:size/ns:y', apert, 'size.y', aperture)    
+                self._store_float('ns:size/ns:z', apert, 'size.z', aperture)
                 
                 collim.aperture.append(aperture)
@@ -360,28 +310,28 @@
             detector = Detector()
             
-            _store_content('ns:name', item, 'name', detector)
-            _store_float('ns:SDD', item, 'distance', detector)    
+            self._store_content('ns:name', item, 'name', detector)
+            self._store_float('ns:SDD', item, 'distance', detector)    
             
             # Detector offset (as a vector)
-            _store_float('ns:offset/ns:x', item, 'offset.x', detector)    
-            _store_float('ns:offset/ns:y', item, 'offset.y', detector)    
-            _store_float('ns:offset/ns:z', item, 'offset.z', detector)    
+            self._store_float('ns:offset/ns:x', item, 'offset.x', detector)    
+            self._store_float('ns:offset/ns:y', item, 'offset.y', detector)    
+            self._store_float('ns:offset/ns:z', item, 'offset.z', detector)    
             
             # Detector orientation (as a vector)
-            _store_float('ns:orientation/ns:roll',  item, 'orientation.x', detector)    
-            _store_float('ns:orientation/ns:pitch', item, 'orientation.y', detector)    
-            _store_float('ns:orientation/ns:yaw',   item, 'orientation.z', detector)    
+            self._store_float('ns:orientation/ns:roll',  item, 'orientation.x', detector)    
+            self._store_float('ns:orientation/ns:pitch', item, 'orientation.y', detector)    
+            self._store_float('ns:orientation/ns:yaw',   item, 'orientation.z', detector)    
             
             # Beam center (as a vector)
-            _store_float('ns:beam_center/ns:x', item, 'beam_center.x', detector)    
-            _store_float('ns:beam_center/ns:y', item, 'beam_center.y', detector)    
-            _store_float('ns:beam_center/ns:z', item, 'beam_center.z', detector)    
+            self._store_float('ns:beam_center/ns:x', item, 'beam_center.x', detector)    
+            self._store_float('ns:beam_center/ns:y', item, 'beam_center.y', detector)    
+            self._store_float('ns:beam_center/ns:z', item, 'beam_center.z', detector)    
             
             # Pixel size (as a vector)
-            _store_float('ns:pixel_size/ns:x', item, 'pixel_size.x', detector)    
-            _store_float('ns:pixel_size/ns:y', item, 'pixel_size.y', detector)    
-            _store_float('ns:pixel_size/ns:z', item, 'pixel_size.z', detector)    
-            
-            _store_float('ns:slit_length', item, 'slit_length', detector)
+            self._store_float('ns:pixel_size/ns:x', item, 'pixel_size.x', detector)    
+            self._store_float('ns:pixel_size/ns:y', item, 'pixel_size.y', detector)    
+            self._store_float('ns:pixel_size/ns:z', item, 'pixel_size.z', detector)    
+            
+            self._store_float('ns:slit_length', item, 'slit_length', detector)
             
             data_info.detector.append(detector)    
@@ -391,7 +341,7 @@
         for item in nodes:
             process = Process()
-            _store_content('ns:name', item, 'name', process)
-            _store_content('ns:date', item, 'date', process)
-            _store_content('ns:description', item, 'description', process)
+            self._store_content('ns:name', item, 'name', process)
+            self._store_content('ns:date', item, 'date', process)
+            self._store_content('ns:description', item, 'description', process)
             
             term_list = item.xpath('ns:term', namespaces={'ns': CANSAS_NS})
@@ -405,5 +355,7 @@
                         process.term.append(term_attr)
                 except:
-                    logging.error("cansas_reader.read: error processing process term\n  %s" % sys.exc_value)
+                    err_mess = "cansas_reader.read: error processing process term\n  %s" % sys.exc_value
+                    self.errors.append(err_mess)
+                    logging.error(err_mess)
             
             note_list = item.xpath('ns:SASprocessnote', namespaces={'ns': CANSAS_NS})
@@ -756,5 +708,81 @@
         fd.close()
         
-        
+    def _store_float(self, location, node, variable, storage, optional=True):
+        """
+            Get the content of a xpath location and store
+            the result. Check that the units are compatible
+            with the destination. The value is expected to
+            be a float.
+            
+            The xpath location might or might not exist.
+            If it does not exist, nothing is done
+            
+            @param location: xpath location to fetch
+            @param node: node to read the data from
+            @param variable: name of the data member to store it in [string]
+            @param storage: data object that has the 'variable' data member
+            @param optional: if True, no exception will be raised if unit conversion can't be done
+    
+            @raise ValueError: raised when the units are not recognized
+        """
+        entry = get_content(location, node)
+        try:
+            value = float(entry.text)
+        except:
+            value = None
+            
+        if value is not None:
+            # If the entry has units, check to see that they are
+            # compatible with what we currently have in the data object
+            units = entry.get('unit')
+            if units is not None:
+                toks = variable.split('.')
+                exec "local_unit = storage.%s_unit" % toks[0]
+                if units.lower()!=local_unit.lower():
+                    if has_converter==True:
+                        try:
+                            conv = Converter(units)
+                            exec "storage.%s = %g" % (variable, conv(value, units=local_unit))
+                        except:
+                            err_mess = "CanSAS reader: could not convert %s unit [%s]; expecting [%s]\n  %s" \
+                                % (variable, units, local_unit, sys.exc_value)
+                            self.errors.append(err_mess)
+                            if optional:
+                                logging.info(err_mess)
+                            else:
+                                raise ValueError, err_mess 
+                    else:
+                        err_mess = "CanSAS reader: unrecognized %s unit [%s]; expecting [%s]" \
+                            % (variable, units, local_unit)
+                        self.errors.append(err_mess)
+                        if optional:
+                            logging.info(err_mess)
+                        else:
+                            raise ValueError, err_mess
+                else:
+                    exec "storage.%s = value" % variable
+            else:
+                exec "storage.%s = value" % variable
+                
+    def _store_content(self, location, node, variable, storage):
+        """
+            Get the content of a xpath location and store
+            the result. The value is treated as a string.
+            
+            The xpath location might or might not exist.
+            If it does not exist, nothing is done
+            
+            @param location: xpath location to fetch
+            @param node: node to read the data from
+            @param variable: name of the data member to store it in [string]
+            @param storage: data object that has the 'variable' data member
+            @return: return a list of errors
+        """
+        entry = get_content(location, node)
+        if entry is not None and entry.text is not None:
+            exec "storage.%s = entry.text.strip()" % variable
+
+            
+            
 if __name__ == "__main__": 
     logging.basicConfig(level=logging.ERROR,
Index: DataLoader/readers/danse_reader.py
===================================================================
--- DataLoader/readers/danse_reader.py	(revision 28caa03404030faac2dd29ba6ae3e5afc427a99b)
+++ DataLoader/readers/danse_reader.py	(revision fe78c7be16b3ca74072592fdeda007c4a989ce82)
@@ -275,5 +275,8 @@
             else:
                 logging.info("Danse_reader Reading %s \n"%filename)
-                return output
+            
+            # Store loading process information
+            output.meta_data['loader'] = self.type_name    
+            return output
         
         return None
Index: DataLoader/readers/hfir1d_reader.py
===================================================================
--- DataLoader/readers/hfir1d_reader.py	(revision 28caa03404030faac2dd29ba6ae3e5afc427a99b)
+++ DataLoader/readers/hfir1d_reader.py	(revision fe78c7be16b3ca74072592fdeda007c4a989ce82)
@@ -120,4 +120,6 @@
                     output.yaxis("\\rm{Intensity}","cm^{-1}")
                 
+                # Store loading process information
+                output.meta_data['loader'] = self.type_name   
                 return output
         else:
Index: DataLoader/readers/tiff_reader.py
===================================================================
--- DataLoader/readers/tiff_reader.py	(revision 28caa03404030faac2dd29ba6ae3e5afc427a99b)
+++ DataLoader/readers/tiff_reader.py	(revision fe78c7be16b3ca74072592fdeda007c4a989ce82)
@@ -95,4 +95,6 @@
         output.ymax       = im.size[0]-1
         
+        # Store loading process information
+        output.meta_data['loader'] = self.type_name 
         return output
         
