Index: src/sas/perspectives/fitting/pagestate.py
===================================================================
--- src/sas/perspectives/fitting/pagestate.py	(revision d838715645ac898163603c42de5b97740d520c4b)
+++ src/sas/perspectives/fitting/pagestate.py	(revision 2f4b43041eaa7b7f496750f223a299cb33cd268e)
@@ -45,34 +45,30 @@
                       ["qmax", "qmax", "float"],
                       ["npts", "npts", "float"],
-                      #["shape_rbutton", "shape_rbutton", "bool"],
-                      #["shape_indep_rbutton", "shape_indep_rbutton", "bool"],
-                      #["plugin_rbutton", "plugin_rbutton", "bool"],
-                      #["struct_rbutton", "struct_rbutton", "bool"],
                       ["categorycombobox", "categorycombobox", "string"],
                       ["formfactorcombobox", "formfactorcombobox", "string"],
                       ["structurecombobox", "structurecombobox", "string"],
-                      ["multi_factor","multi_factor","float"],
-                      ["magnetic_on","magnetic_on", "bool"],
-                      ["enable_smearer","enable_smearer","bool"],
-                      ["disable_smearer","disable_smearer","bool"],
-                      ["pinhole_smearer","pinhole_smearer","bool"],
-                      ["slit_smearer","slit_smearer","bool"],
-                      ["enable_disp","enable_disp","bool"],
-                      ["disable_disp","disable_disp","bool"],
-                      ["dI_noweight","dI_noweight","bool"],
-                      ["dI_didata","dI_didata","bool"],
-                      ["dI_sqrdata","dI_sqrdata","bool"],
-                      ["dI_idata","dI_idata","bool"],
-                      ["enable2D","enable2D","bool"],
-                      ["cb1","cb1","bool"],
-                      ["tcChi","tcChi","float"],
+                      ["multi_factor", "multi_factor", "float"],
+                      ["magnetic_on", "magnetic_on", "bool"],
+                      ["enable_smearer", "enable_smearer", "bool"],
+                      ["disable_smearer", "disable_smearer", "bool"],
+                      ["pinhole_smearer", "pinhole_smearer", "bool"],
+                      ["slit_smearer", "slit_smearer", "bool"],
+                      ["enable_disp", "enable_disp", "bool"],
+                      ["disable_disp", "disable_disp", "bool"],
+                      ["dI_noweight", "dI_noweight", "bool"],
+                      ["dI_didata", "dI_didata", "bool"],
+                      ["dI_sqrdata", "dI_sqrdata", "bool"],
+                      ["dI_idata", "dI_idata", "bool"],
+                      ["enable2D", "enable2D", "bool"],
+                      ["cb1", "cb1", "bool"],
+                      ["tcChi", "tcChi", "float"],
                       ["smearer", "smearer", "float"],
-                      ["smear_type","smear_type", "string"],
+                      ["smear_type", "smear_type", "string"],
                       ["dq_l", "dq_l", "string"],
-                      ["dq_r","dq_r", "string"],
+                      ["dq_r", "dq_r", "string"],
                       ["dx_max", "dx_max", "float"],
-                      ["dx_min","dx_min", "float"],
+                      ["dx_min", "dx_min", "float"],
                       ["dxl", "dxl", "float"],
-                      ["dxw","dxw", "float"]]
+                      ["dxw", "dxw", "float"]]
 
 list_of_model_attributes = [["values", "values"],
@@ -110,10 +106,10 @@
     """
     Create a numpy list from value extrated from the node
-    
+
     :param node: node from each the value is stored
     :param item: list name of three strings.the two first are name of data
         attribute and the third one is the type of the value of that
         attribute. type can be string, float, bool, etc.
-    
+
     : return: numpy array
     """
@@ -124,5 +120,5 @@
             try:
                 return node.get(item[0]).strip() == "True"
-                
+
             except:
                 return None
@@ -132,6 +128,6 @@
             except:
                 return None
-            
-            
+
+
 class PageState(object):
     """
@@ -141,8 +137,8 @@
         """
         Initialize the current state
-        
+
         :param model: a selected model within a page
         :param data:
-        
+
         """
         self.file = None
@@ -159,5 +155,5 @@
         self.is_2D = False
         self.images = None
-        
+
         #save additional information on data that dataloader.reader does not read
         self.is_data = None
@@ -172,8 +168,8 @@
         if self.data is not None and hasattr(self.data, "group_id"):
             self.data_group_id = self.data.group_id
-        
+
         ## reset True change the state of exsiting button
         self.reset = False
-       
+
         #engine type
         self.engine_type = None
@@ -225,5 +221,5 @@
         self.values = {}
         self.weights = {}
-                    
+
         #contains link between a model and selected parameters to fit
         self.param_toFit = []
@@ -251,5 +247,5 @@
         self.qmax_x = None
         self.qmin_x = None
-        
+
         self.npts = None
         self.name = ""
@@ -269,10 +265,10 @@
         self.enable_disp = False
         self.disable_disp = True
-       
+
         ## state of selected all check button
         self.cb1 = False
         ## store value of chisqr
         self.tcChi = None
-    
+
     def clone(self):
         """
@@ -292,18 +288,18 @@
         obj.model_list_box = copy.deepcopy(self.model_list_box)
         obj.engine_type = copy.deepcopy(self.engine_type)
-        
+
         obj.categorycombobox = self.categorycombobox
         obj.formfactorcombobox = self.formfactorcombobox
         obj.structurecombobox = self.structurecombobox
-        
+
         #obj.shape_rbutton = self.shape_rbutton
         #obj.shape_indep_rbutton = self.shape_indep_rbutton
         #obj.struct_rbutton = self.struct_rbutton
         #obj.plugin_rbutton = self.plugin_rbutton
-        
+
         obj.manager = self.manager
         obj.event_owner = self.event_owner
         obj.disp_list = copy.deepcopy(self.disp_list)
-        
+
         obj.enable2D = copy.deepcopy(self.enable2D)
         obj.parameters = copy.deepcopy(self.parameters)
@@ -316,5 +312,5 @@
         obj.disable_disp = copy.deepcopy(self.disable_disp)
         obj.tcChi = self.tcChi
-  
+
         if len(self._disp_obj_dict) > 0:
             for k, v in self._disp_obj_dict.iteritems():
@@ -343,5 +339,5 @@
         obj.dx_min = copy.deepcopy(self.dx_min)
         obj.dxl = copy.deepcopy(self.dxl)
-        obj.dxw = copy.deepcopy(self.dxw)        
+        obj.dxw = copy.deepcopy(self.dxw)
         obj.disp_box = copy.deepcopy(self.disp_box)
         obj.qmin = copy.deepcopy(self.qmin)
@@ -352,5 +348,5 @@
         obj.cb1 = copy.deepcopy(self.cb1)
         obj.smearer = copy.deepcopy(self.smearer)
-        
+
         for name, state in self.saved_states.iteritems():
             copy_name = copy.deepcopy(name)
@@ -358,5 +354,5 @@
             obj.saved_states[copy_name] = copy_state
         return obj
-    
+
     def _repr_helper(self, list, rep):
         """
@@ -375,5 +371,5 @@
             rep += "parameter unit: %s\n\n" % str(item[7])
         return rep
-    
+
     def __repr__(self):
         """
@@ -399,5 +395,5 @@
         #rep += "model type (form factor) selected: %s\n" % self.shape_rbutton 
         rep += "multi_factor : %s\n" % str(self.multi_factor)
-        rep += "magnetic_on : %s\n"% str(self.magnetic_on)
+        rep += "magnetic_on : %s\n" % str(self.magnetic_on)
         rep += "model type (Category) selected: %s\n" % self.categorycombobox
         #rep += "model type (shape independent) selected: %s\n" % self.shape_indep_rbutton
@@ -415,10 +411,10 @@
         rep += "Dispersity disable : %s\n" % str(self.disable_disp)
         rep += "Slit smearer enable: %s\n" % str(self.slit_smearer)
-        
+
         rep += "dI_noweight : %s\n" % str(self.dI_noweight)
         rep += "dI_didata : %s\n" % str(self.dI_didata)
         rep += "dI_sqrdata : %s\n" % str(self.dI_sqrdata)
         rep += "dI_idata : %s\n" % str(self.dI_idata)
-        
+
         rep += "2D enable : %s\n" % str(self.enable2D)
         rep += "All parameters checkbox selected: %s\n" % (self.cb1)
@@ -429,7 +425,7 @@
         rep += "dq_r  : %s\n" % self.dq_r
         rep += "dx_max  : %s\n" % str(self.dx_max)
-        rep += "dx_min : %s\n" % str(self.dx_min)  
+        rep += "dx_min : %s\n" % str(self.dx_min)
         rep += "dxl  : %s\n" % str(self.dxl)
-        rep += "dxw : %s\n" % str(self.dxw)    
+        rep += "dxw : %s\n" % str(self.dxw)
         rep += "model  : %s\n\n" % str(self.model)
         temp_parameters = []
@@ -450,5 +446,5 @@
                 temp_parameters = self.parameters
                 temp_fittable_param = self.fittable_param
-                
+
             rep += "number parameters(self.parameters): %s\n" % len(temp_parameters)
             rep = self._repr_helper(list=temp_parameters, rep=rep)
@@ -550,5 +546,5 @@
                     modelname = "Model name:" + " NAN"
                 model_name = CENTRE % modelname
-                 
+
             if name == "Plotting Range":
                 try:
@@ -572,14 +568,14 @@
                     paramval += param + "\n"
                     paramval_string += CENTRE % param + "\n"
-        
+
         text_string = "\n\n\n" + title + "\n\n" + file + \
                       "\n" + q_name + \
                       "\n" + chi2 + \
                       "\n\n" + paramval
-        
+
         title_name = self._check_html_format(title_name)
         file_name = self._check_html_format(file_name)
         title = self._check_html_format(title)
-                                  
+
         html_string = title_name + "\n" + file_name + \
                                    "\n" + model_name + \
@@ -591,7 +587,7 @@
                                    "\n" + FEET_1 % title + \
                                    "\n" + FEET_2
-                                                                      
+
         return html_string, text_string, title
-    
+
     def _check_html_format(self, name):
         """
@@ -600,11 +596,11 @@
         if name.count('%'):
             name = name.replace('%', '&#37')
-        
+
         return name
-    
+
     def report(self, figs=None, canvases=None):
         """
         Invoke report dialog panel
-        
+
         : param figs: list of pylab figures [list]
         """
@@ -638,5 +634,5 @@
         dialog = ReportDialog(report_list, None, -1, "")
         dialog.Show()
-        
+
     def _toXML_helper(self, thelist, element, newdoc):
         """
@@ -656,17 +652,17 @@
             sub_element.setAttribute('unit', str(item[7]))
             element.appendChild(sub_element)
-        
+
     def toXML(self, file="fitting_state.fitv", doc=None, entry_node=None):
         """
         Writes the state of the InversionControl panel to file, as XML.
-        
+
         Compatible with standalone writing, or appending to an
         already existing XML document. In that case, the XML document
         is required. An optional entry node in the XML document may also be given.
-        
+
         :param file: file to write to
         :param doc: XML document object [optional]
         :param entry_node: XML node within the XML document at which we will append the data [optional]
-        
+
         """
         from xml.dom.minidom import getDOMImplementation
@@ -697,9 +693,9 @@
                     entry_node = node_list.item(0)
                     entry_node.appendChild(top_element)
-                    
+
         attr = newdoc.createAttribute("version")
         attr.nodeValue = '1.0'
         top_element.setAttributeNode(attr)
-        
+
         # File name
         element = newdoc.createElement("filename")
@@ -709,5 +705,5 @@
             element.appendChild(newdoc.createTextNode(str(file)))
         top_element.appendChild(element)
-        
+
         element = newdoc.createElement("timestamp")
         element.appendChild(newdoc.createTextNode(time.ctime(self.timestamp)))
@@ -719,5 +715,5 @@
         inputs = newdoc.createElement("Attributes")
         top_element.appendChild(inputs)
-       
+
         if self.data is not None and hasattr(self.data, "group_id"):
             self.data_group_id = self.data.group_id
@@ -728,15 +724,15 @@
         if self.data is not None and hasattr(self.data, "id"):
             self.data_id = self.data.id
-       
+
         for item in list_of_data_attributes:
             element = newdoc.createElement(item[0])
             exec "element.setAttribute(item[0], str(self.%s))" % (item[1])
             inputs.appendChild(element)
-        
+
         for item in list_of_state_attributes:
             element = newdoc.createElement(item[0])
             exec "element.setAttribute(item[0], str(self.%s))" % (item[1])
             inputs.appendChild(element)
-            
+
         # For self.values ={ disp_param_name: [vals,...],...}
         # and for self.weights ={ disp_param_name: [weights,...],...}
@@ -752,8 +748,8 @@
                     com += "(newdoc.createTextNode(str(%s)))"
                     exec com % val
-                   
+
                 element.appendChild(sub_element)
             inputs.appendChild(element)
-        
+
         # Create doc for the dictionary of self._disp_obj_dic
         for item in list_of_obj_dic:
@@ -767,5 +763,5 @@
                 element.appendChild(sub_element)
             inputs.appendChild(element)
-                 
+
         for item in list_of_state_parameters:
             element = newdoc.createElement(item[0])
@@ -774,5 +770,5 @@
             exec com % item[1]
             inputs.appendChild(element)
-        
+
         # Save the file
         if doc is None:
@@ -783,5 +779,5 @@
         else:
             return newdoc
-        
+
     def _fromXML_helper(self, node, list):
         """
@@ -833,12 +829,12 @@
                          [minimum_displayed, minimum_value],
                          [maximum_displayed, maximum_value], unit])
-       
+
     def fromXML(self, file=None, node=None):
         """
         Load fitting state from a file
-        
+
         :param file: .fitv file
         :param node: node of a XML document to read from
-        
+
         """
         if file is not None:
@@ -846,12 +842,12 @@
             msg += " format for fitting files"
             raise RuntimeError, msg
-            
+
         if node.get('version')and node.get('version') == '1.0':
-            
+
             # Get file name
             entry = get_content('ns:filename', node)
             if entry is not None:
                 self.file = entry.text.strip()
-                
+
             # Get time stamp
             entry = get_content('ns:timestamp', node)
@@ -863,5 +859,5 @@
                     msg += " read timestamp\n %s" % sys.exc_value
                     logging.error(msg)
-            
+
             # Parse fitting attributes
             entry = get_content('ns:Attributes', node)
@@ -870,10 +866,10 @@
                 try:
                     exec "self.%s = parse_entry_helper(node, item)" % item[0]
-                    
+
                 except:
                     raise
 
             if entry is not None:
-                
+
                 for item in list_of_state_attributes:
                     node = get_content('ns:%s' % item[0], entry)
@@ -883,10 +879,10 @@
                     except:
                         raise
-                    
+
                 for item in list_of_state_parameters:
                     node = get_content("ns:%s" % item[0], entry)
                     exec "self._fromXML_helper(node=node, list=self.%s)" % \
                                                                     item[1]
-                
+
                 # Recover _disp_obj_dict from xml file
                 self._disp_obj_dict = {}
@@ -910,5 +906,5 @@
                         except:
                             pass
-                        
+
                 # get self.values and self.weights dic. if exists
                 for item in list_of_model_attributes:
@@ -929,5 +925,5 @@
                     dic[name] = numpy.array(list)
                     exec "self.%s = dic" % item[1]
-                    
+
     def set_plot_state(self, figs, canvases):
         """
@@ -943,9 +939,9 @@
         self.imgRAM = None
         wx.MemoryFSHandler()
-        
+
         # For no figures in the list, prepare empty plot
         if figs == None or len(figs) == 0:
             figs = [None]
-            
+
         # Loop over the list of figures
         # use wx.MemoryFSHandler
@@ -955,18 +951,18 @@
                 ind = figs.index(fig)
                 canvas = canvases[ind]
-                
+
             #store the image in wx.FileSystem Object 
             wx.FileSystem.AddHandler(wx.MemoryFSHandler())
-            
+
             # index of the fig
             ind = figs.index(fig)
-            
+
             #AddFile, image can be retrieved with 'memory:filename'
             self.imgRAM.AddFile('img_fit%s.png' % ind,
                                 canvas.bitmap, wx.BITMAP_TYPE_PNG)
-            
+
             #append figs
             images.append(fig)
-            
+
         return images
 
@@ -978,5 +974,5 @@
     ## File type
     type_name = "Fitting"
-    
+
     ## Wildcards
     type = ["Fitting files (*.fitv)|*.fitv"
@@ -984,5 +980,5 @@
     ## List of allowed extensions
     ext = ['.fitv', '.FITV', '.svs', 'SVS']
-    
+
     def __init__(self, call_back=None, cansas=True):
         CansasReader.__init__(self)
@@ -990,9 +986,9 @@
         Initialize the call-back method to be called
         after we load a file
-        
+
         :param call_back: call-back method
         :param cansas:  True = files will be written/read in CanSAS format
                         False = write CanSAS format
-            
+
         """
         ## Call back method to be executed after a file is read
@@ -1001,28 +997,28 @@
         self.cansas = cansas
         self.state = None
-        
+
     def get_state(self):
         return self.state
-        
+
     def read(self, path):
         """
         Load a new P(r) inversion state from file
-        
+
         :param path: file path
-        
+
         """
         if self.cansas == True:
             return self._read_cansas(path)
-     
+
     def _data2d_to_xml_doc(self, datainfo):
         """
         Create an XML document to contain the content of a Data2D
-        
+
         :param datainfo: Data2D object
-        
+
         """
         if not issubclass(datainfo.__class__, Data2D):
             raise RuntimeError, "The cansas writer expects a Data2D instance"
-        
+
         doc = xml.dom.minidom.Document()
         main_node = doc.createElement("SASroot")
@@ -1031,10 +1027,10 @@
         main_node.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
         main_node.setAttribute("xsi:schemaLocation", "cansas1d/%s http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd" % self.version)
-        
+
         doc.appendChild(main_node)
-        
+
         entry_node = doc.createElement("SASentry")
         main_node.appendChild(entry_node)
-       
+
         write_node(doc, entry_node, "Title", datainfo.title)
         if datainfo is not None:
@@ -1042,5 +1038,5 @@
         for item in datainfo.run:
             runname = {}
-            if datainfo.run_name.has_key(item) and len(str(datainfo.run_name[item]))>1:
+            if datainfo.run_name.has_key(item) and len(str(datainfo.run_name[item])) > 1:
                 runname = {'name': datainfo.run_name[item] }
             write_node(doc, entry_node, "Run", item, runname)
@@ -1052,5 +1048,5 @@
             exec "element.setAttribute(item[0], str(datainfo.%s))" % (item[1])
             new_node.appendChild(element)
-            
+
         for item in list_of_data2d_values:
             root_node = doc.createElement(item[0])
@@ -1059,5 +1055,5 @@
             exec "temp_list = datainfo.%s" % item[1]
 
-            if temp_list is None or len(temp_list)== 0:
+            if temp_list is None or len(temp_list) == 0:
                 element = doc.createElement(item[0])
                 exec "element.appendChild(doc.createTextNode(str(%s)))" % temp_list
@@ -1068,5 +1064,5 @@
                     exec "element.setAttribute(item[0], str(%s))" % value
                     root_node.appendChild(element)
-       
+
         # Sample info
         sample = doc.createElement("SASsample")
@@ -1080,8 +1076,8 @@
         write_node(doc, sample, "temperature", datainfo.sample.temperature,
                    {"unit": datainfo.sample.temperature_unit})
-        
+
         for item in datainfo.sample.details:
             write_node(doc, sample, "details", item)
-        
+
         pos = doc.createElement("position")
         written = write_node(doc, pos, "x", datainfo.sample.position.x,
@@ -1095,5 +1091,5 @@
         if written == True:
             sample.appendChild(pos)
-        
+
         ori = doc.createElement("orientation")
         written = write_node(doc, ori, "roll", datainfo.sample.orientation.x,
@@ -1107,11 +1103,11 @@
         if written == True:
             sample.appendChild(ori)
-        
+
         # Instrument info
         instr = doc.createElement("SASinstrument")
         entry_node.appendChild(instr)
-        
+
         write_node(doc, instr, "name", datainfo.instrument)
-        
+
         #   Source
         source = doc.createElement("SASsource")
@@ -1119,5 +1115,5 @@
             source.setAttribute("name", str(datainfo.source.name))
         instr.appendChild(source)
-        
+
         write_node(doc, source, "radiation", datainfo.source.radiation)
         write_node(doc, source, "beam_shape", datainfo.source.beam_shape)
@@ -1135,5 +1131,5 @@
         if written == True:
             source.appendChild(size)
-            
+
         write_node(doc, source, "wavelength", datainfo.source.wavelength,
                    {"unit": datainfo.source.wavelength_unit})
@@ -1147,5 +1143,5 @@
                    datainfo.source.wavelength_spread,
                    {"unit": datainfo.source.wavelength_spread_unit})
-        
+
         #   Collimation
         for item in datainfo.collimation:
@@ -1154,8 +1150,8 @@
                 coll.setAttribute("name", str(item.name))
             instr.appendChild(coll)
-            
+
             write_node(doc, coll, "length", item.length,
                        {"unit": item.length_unit})
-            
+
             for apert in item.aperture:
                 ap = doc.createElement("aperture")
@@ -1165,8 +1161,8 @@
                     ap.setAttribute("type", str(apert.type))
                 coll.appendChild(ap)
-                
+
                 write_node(doc, ap, "distance", apert.distance,
                            {"unit": apert.distance_unit})
-                
+
                 size = doc.createElement("size")
                 if apert.size_name is not None:
@@ -1192,5 +1188,5 @@
             if written == True:
                 instr.appendChild(det)
-            
+
             off = doc.createElement("offset")
             written = write_node(doc, off, "x", item.offset.x,
@@ -1202,5 +1198,5 @@
             if written == True:
                 det.appendChild(off)
-            
+
             center = doc.createElement("beam_center")
             written = write_node(doc, center, "x", item.beam_center.x,
@@ -1214,5 +1210,5 @@
             if written == True:
                 det.appendChild(center)
-                
+
             pix = doc.createElement("pixel_size")
             written = write_node(doc, pix, "x", item.pixel_size.x,
@@ -1224,5 +1220,5 @@
             if written == True:
                 det.appendChild(pix)
-                
+
             ori = doc.createElement("orientation")
             written = write_node(doc, ori, "roll", item.orientation.x,
@@ -1235,5 +1231,5 @@
             if written == True:
                 det.appendChild(ori)
-                
+
         # Processes info
         for item in datainfo.process:
@@ -1253,15 +1249,15 @@
         # the data we just wrote
         return doc, entry_node
-   
+
     def _parse_state(self, entry):
         """
         Read a fit result from an XML node
-        
+
         :param entry: XML node to read from
-        
+
         :return: PageState object
         """
         # Create an empty state
-        state = None   
+        state = None
         # Locate the P(r) node
         try:
@@ -1272,18 +1268,18 @@
                 state = PageState()
                 state.fromXML(node=nodes[0])
-                
+
         except:
             logging.info("XML document does not contain fitting information.\n %s" % sys.exc_value)
-            
+
         return state
-      
+
     def _parse_save_state_entry(self, dom):
         """
         Parse a SASentry
-        
+
         :param node: SASentry node
-        
+
         :return: Data1D/Data2D object
-        
+
         """
         node = dom.xpath('ns:data_class', namespaces={'ns': CANSAS_NS})
@@ -1305,13 +1301,13 @@
                 numpy.trim_zeros(return_value.dxl)
                 numpy.trim_zeros(return_value.dxw)
-                            
+
             return return_value, _
-        
+
         #Parse 2D
         data_info = Data2D()
-        
+
         # Look up title
         self._store_content('ns:Title', dom, 'title', data_info)
-        
+
         # Look up run number
         nodes = dom.xpath('ns:Run', namespaces={'ns': CANSAS_NS})
@@ -1323,5 +1319,5 @@
                     if item.get('name') is not None:
                         data_info.run_name[value] = item.get('name')
-                           
+
         # Look up instrument name
         self._store_content('ns:SASinstrument/ns:name', dom,
@@ -1340,10 +1336,10 @@
                 self.errors.append(err_mess)
                 logging.error(err_mess)
-        
+
         # Sample info ###################
         entry = get_content('ns:SASsample', dom)
         if entry is not None:
             data_info.sample.name = entry.get('name')
-            
+
         self._store_content('ns:SASsample/ns:ID',
                      dom, 'ID', data_info.sample)
@@ -1354,5 +1350,5 @@
         self._store_float('ns:SASsample/ns:temperature',
                      dom, 'temperature', data_info.sample)
-        
+
         nodes = dom.xpath('ns:SASsample/ns:details',
                           namespaces={'ns': CANSAS_NS})
@@ -1367,5 +1363,5 @@
                 self.errors.append(err_mess)
                 logging.error(err_mess)
-        
+
         # Position (as a vector)
         self._store_float('ns:SASsample/ns:position/ns:x',
@@ -1375,5 +1371,5 @@
         self._store_float('ns:SASsample/ns:position/ns:z',
                      dom, 'position.z', data_info.sample)
-        
+
         # Orientation (as a vector)
         self._store_float('ns:SASsample/ns:orientation/ns:roll',
@@ -1383,10 +1379,10 @@
         self._store_float('ns:SASsample/ns:orientation/ns:yaw',
                      dom, 'orientation.z', data_info.sample)
-       
+
         # Source info ###################
         entry = get_content('ns:SASinstrument/ns:SASsource', dom)
         if entry is not None:
             data_info.source.name = entry.get('name')
-        
+
         self._store_content('ns:SASinstrument/ns:SASsource/ns:radiation',
                      dom, 'radiation', data_info.source)
@@ -1401,10 +1397,10 @@
         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_spread',
                      dom, 'wavelength_spread', data_info.source)
-        
+
         # Beam size (as a vector)
         entry = get_content('ns:SASinstrument/ns:SASsource/ns:beam_size', dom)
         if entry is not None:
             data_info.source.beam_size_name = entry.get('name')
-            
+
         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:x',
                      dom, 'beam_size.x', data_info.source)
@@ -1413,5 +1409,5 @@
         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:z',
                      dom, 'beam_size.z', data_info.source)
-        
+
         # Collimation info ###################
         nodes = dom.xpath('ns:SASinstrument/ns:SAScollimation',
@@ -1422,5 +1418,5 @@
                 collim.name = item.get('name')
             self._store_float('ns:length', item, 'length', collim)
-            
+
             # Look for apertures
             apert_list = item.xpath('ns:aperture',
@@ -1428,38 +1424,38 @@
             for apert in apert_list:
                 aperture = Aperture()
-                
+
                 # Get the name and type of the aperture
                 aperture.name = apert.get('name')
                 aperture.type = apert.get('type')
-                    
+
                 self._store_float('ns:distance', apert, 'distance', aperture)
-                
+
                 entry = get_content('ns:size', apert)
                 if entry is not None:
                     aperture.size_name = entry.get('name')
-                
+
                 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)
-                
+
             data_info.collimation.append(collim)
-        
+
         # Detector info ######################
         nodes = dom.xpath('ns:SASinstrument/ns:SASdetector',
                           namespaces={'ns': CANSAS_NS})
         for item in nodes:
-            
+
             detector = Detector()
-            
+
             self._store_content('ns:name', item, 'name', detector)
             self._store_float('ns:SDD', item, 'distance', detector)
-            
+
             # Detector offset (as a vector)
             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)
             self._store_float('ns:orientation/ns:roll', item,
@@ -1469,5 +1465,5 @@
             self._store_float('ns:orientation/ns:yaw', item,
                               'orientation.z', detector)
-            
+
             # Beam center (as a vector)
             self._store_float('ns:beam_center/ns:x', item,
@@ -1477,5 +1473,5 @@
             self._store_float('ns:beam_center/ns:z', item,
                               'beam_center.z', detector)
-            
+
             # Pixel size (as a vector)
             self._store_float('ns:pixel_size/ns:x', item,
@@ -1485,7 +1481,7 @@
             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)
 
@@ -1497,5 +1493,5 @@
             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})
             for term in term_list:
@@ -1511,5 +1507,5 @@
                     self.errors.append(err_mess)
                     logging.error(err_mess)
-            
+
             note_list = item.xpath('ns:SASprocessnote',
                                    namespaces={'ns': CANSAS_NS})
@@ -1517,12 +1513,12 @@
                 if note.text is not None:
                     process.notes.append(note.text.strip())
-            
+
             data_info.process.append(process)
-            
+
         # Data info ######################
         nodes = dom.xpath('ns:SASdata', namespaces={'ns': CANSAS_NS})
         if len(nodes) > 1:
             raise RuntimeError, "CanSAS reader is not compatible with multiple SASdata entries"
-       
+
         for entry in nodes:
             for item in list_of_data_2d_attr:
@@ -1530,5 +1526,5 @@
                 node = get_content('ns:%s' % item[0], entry)
                 exec "data_info.%s = parse_entry_helper(node, item)" % item[1]
-                    
+
             for item in list_of_data2d_values:
                 field = get_content('ns:%s' % item[0], entry)
@@ -1540,5 +1536,5 @@
                 else:
                     exec "data_info.%s = numpy.array(list)" % item[0]
-        
+
         return data_info
 
@@ -1546,14 +1542,14 @@
         """
         Load data and P(r) information from a CanSAS XML file.
-        
+
         :param path: file path
-        
+
         :return: Data1D object if a single SASentry was found,
                     or a list of Data1D objects if multiple entries were found,
                     or None of nothing was found
-                    
+
         :raise RuntimeError: when the file can't be opened
         :raise ValueError: when the length of the data vectors are inconsistent
-        
+
         """
         output = []
@@ -1563,10 +1559,10 @@
         try:
             if os.path.isfile(path):
-                
+
                 #TODO: eventually remove the check for .xml once
                 # the P(r) writer/reader is truly complete.
                 if  ext in self.ext or \
                     ext == '.xml':
-                    
+
                     tree = etree.parse(path, parser=etree.ETCompatXMLParser())
                     # Check the format version number
@@ -1581,5 +1577,5 @@
                             raise
                         fitstate = self._parse_state(entry)
-                        
+
                         #state could be None when .svs file is loaded
                         #in this case, skip appending to output
@@ -1608,8 +1604,8 @@
                     original_fname = state.file[0:max_char]
                     state.file = original_fname + ' [' + time_str + ']'
-                     
+
                     if state is not None and state.is_data is not None:
                         exec 'output[%d].is_data = state.is_data' % ind
-                     
+
                     output[ind].filename = state.file
                     state.data = output[ind]
@@ -1629,18 +1625,18 @@
                     self.state = state
                 return output
-              
+
         except:
             self.call_back(format=ext)
             #self.state= state
             raise
-           
+
     def write(self, filename, datainfo=None, fitstate=None):
         """
         Write the content of a Data1D as a CanSAS XML file only for standalone
-        
+
         :param filename: name of the file to write
         :param datainfo: Data1D object
         :param fitstate: PageState object
-        
+
         """
         # Sanity check
@@ -1651,15 +1647,15 @@
         else:
             doc = fitstate.toXML(file=filename)
-        
+
         # Save the document no matter the type
         fd = open(filename, 'w')
         fd.write(doc.toprettyxml())
         fd.close()
-        
+
     def write_toXML(self, datainfo=None, state=None):
         """
         Write toXML, a helper for write(),
         could be used by guimanager._on_save()
-        
+
         : return: xml doc
         """
@@ -1677,5 +1673,5 @@
                 state.data.run = [str(state.data.name)]
                 state.data.run_name[0] = state.data.name
-            
+
             if issubclass(state.data.__class__,
                           sas.dataloader.data_info.Data1D):
@@ -1685,10 +1681,10 @@
                 data = state.data
                 doc, sasentry = self._data2d_to_xml_doc(data)
-            
+
         if state is not None:
             doc = state.toXML(doc=doc, file=data.filename, entry_node=sasentry)
-        
+
         return doc
-    
+
 # Simple html report templet
 HEADER = "<html>\n"
@@ -1736,5 +1732,5 @@
     #state.toXML()
     """
-    
+
     file = open("test_state", "w")
     pickle.dump(state, file)
@@ -1769,4 +1765,4 @@
     db.keys().sort()
     print pickle.loads(db['state2'])
-  
+
     db.close()
