Index: calculatorview/src/sans/perspectives/calculator/__init__.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/__init__.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/__init__.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,49 @@
+PLUGIN_ID = "Calculator plug-in 1.0"
+from calculator import *
+
+import os
+from distutils.filelist import findall
+
+N_DIR = 12
+def get_data_path(media):
+    """
+    """
+    # Check for data path in the package
+    path = os.path.join(os.path.dirname(__file__), media)
+    if os.path.isdir(path):
+        return path
+    # Check for data path next to exe/zip file.
+    # If we are inside a py2exe zip file, we need to go up
+    # two levels to get to the directory containing the exe
+    # We will check if the exe and the xsf are in the same
+    # directory.
+    path = os.path.dirname(__file__)
+    #Look for maximum n_dir up of the current dir to find media
+   
+    #for i in range(n_dir):
+    i = 0
+    while(i < N_DIR):
+        path, _ = os.path.split(path)
+        media_path = os.path.join(path, media)
+        if os.path.isdir(media_path):
+             module_media_path = os.path.join(media_path,'calculator_media')
+             if os.path.isdir(module_media_path):
+                 return module_media_path
+             return media_path
+        i += 1
+   
+    raise RuntimeError('Could not find calculator media files')
+
+def data_files():
+    """
+    Return the data files associated with media calculator.
+    
+    The format is a list of (directory, [files...]) pairs which can be
+    used directly in setup(...,data_files=...) for setup.py.
+
+    """
+    data_files = []
+    path = get_data_path(media="media")
+    for f in findall(path):
+        data_files.append(('media/calculator_media', [f]))
+    return data_files
Index: calculatorview/src/sans/perspectives/calculator/aperture_editor.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/aperture_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/aperture_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,411 @@
+
+import wx
+import sys
+from copy import deepcopy
+from DataLoader.loader import Loader
+from sans.guiframe.utils import check_float
+
+_BOX_WIDTH = 60
+if sys.platform.count("win32")>0:
+    _STATICBOX_WIDTH = 450
+    PANEL_WIDTH = 500
+    PANEL_HEIGHT = 290
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 480
+    PANEL_WIDTH = 530
+    PANEL_HEIGHT = 320
+    FONT_VARIANT = 1
+    
+class ApertureDialog(wx.Dialog):
+    def __init__(self, parent=None, manager=None, aperture=None, *args, **kwds):
+        """
+        Dialog allows to enter values for aperture
+        """
+        kwds['size'] = (PANEL_WIDTH, PANEL_HEIGHT)
+        kwds['title'] = "Aperture Editor"
+        wx.Dialog.__init__(self, parent=parent, *args, **kwds)
+        self.parent = parent
+        self.manager = manager
+        self._aperture = aperture
+        self._reset_aperture = deepcopy(aperture)
+        self._notes = ""
+        #self_description = "Edit aperture"
+        
+        #Attributes for panel
+        self.aperture_name_tcl = None
+        self.main_sizer = None
+        self.box_aperture = None
+        self.boxsizer_aperture = None
+        self.name_sizer = None
+        self.name_sizer = None
+        self.size_name_tcl  = None
+        self.type_sizer = None
+        self.distance_sizer = None
+        self.size_name_sizer = None
+        self.aperture_size_unit_tcl = None
+        self.aperture_size_sizer = None
+        self.button_sizer = None
+        self.aperture_name_tcl = None
+        self.type_tcl = None
+        self.distance_tcl = None
+        self.distance_unit_tcl = None
+        self.x_aperture_size_tcl = None
+        self.y_aperture_size_tcl = None
+        self.z_aperture_size_tcl = None
+        self.bt_apply = None
+        self.bt_cancel = None
+        self.bt_close = None
+        
+        self._do_layout()
+        self.set_values()
+      
+    def _define_structure(self):
+        """
+        define initial sizer 
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.box_aperture = wx.StaticBox(self, -1, str("Aperture"))
+        self.boxsizer_aperture = wx.StaticBoxSizer(self.box_aperture, 
+                                                   wx.VERTICAL)
+       
+        self.name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.type_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.distance_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.size_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.aperture_size_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ 
+    def _layout_name(self):
+        """
+        Do the layout for aperture name related widgets
+        """
+        #Aperture name [string]
+        aperture_name_txt = wx.StaticText(self, -1, 'Aperture Name : ')  
+        self.aperture_name_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH*5, 20),
+                                              style=0) 
+        self.name_sizer.AddMany([(aperture_name_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                       (self.aperture_name_tcl, 0, wx.EXPAND)])
+    def _layout_type(self):
+        """
+        Do the  layout for aperture type  related widgets
+        """
+        #Aperture type [string]
+        type_txt = wx.StaticText(self, -1, 'Type: ')  
+        self.type_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0)
+        self.type_sizer.AddMany([(type_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.type_tcl, 0, wx.LEFT, 20)])
+        
+    def _layout_distance(self):
+        """
+        Do the  layout for aperture distance related widgets
+        """
+        #Aperture distance [float]
+        distance_txt = wx.StaticText(self, -1, 'Distance:') 
+        self.distance_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20), 
+                                        style=0)   
+        distance_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.distance_unit_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20),
+                                             style=0)  
+        self.distance_sizer.AddMany([(distance_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.distance_tcl, 0, wx.LEFT, 10),
+                                (distance_unit_txt, 0,  wx.LEFT|wx.RIGHT, 10),
+                                     (self.distance_unit_tcl, 0, wx.EXPAND)])  
+    def _layout_size_name(self):
+        """
+        Do the  layout for size name related widgets
+        """
+        # Size name [string]
+        size_name_txt = wx.StaticText(self, -1, 'Size Name : ')  
+        self.size_name_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH*5, 20),
+                                          style=0) 
+        self.size_name_sizer.AddMany([(size_name_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                       (self.size_name_tcl, 0, wx.EXPAND)])
+        
+    def _layout_size(self):
+        """
+        Do the  layout for aperture size related widgets
+        """
+        #Aperture size [Vector]
+        aperture_size_txt = wx.StaticText(self, -1, 'Size:') 
+        x_aperture_size_txt = wx.StaticText(self, -1, 'x = ')  
+        self.x_aperture_size_tcl = wx.TextCtrl(self, -1, 
+                                               size=(_BOX_WIDTH,20), style=0) 
+        y_aperture_size_txt = wx.StaticText(self, -1, 'y = ')  
+        self.y_aperture_size_tcl = wx.TextCtrl(self, -1,
+                                                size=(_BOX_WIDTH,20), style=0) 
+        z_aperture_size_txt = wx.StaticText(self, -1, 'z = ')  
+        self.z_aperture_size_tcl = wx.TextCtrl(self, -1,
+                                                size=(_BOX_WIDTH,20), style=0)  
+        aperture_size_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.aperture_size_unit_tcl = wx.TextCtrl(self, -1, 
+                                                size=(_BOX_WIDTH,20), style=0)  
+        self.aperture_size_sizer.AddMany([(aperture_size_txt,
+                                         0, wx.LEFT|wx.RIGHT, 10),
+                                     (x_aperture_size_txt, 0, wx.LEFT, 17),
+                                (self.x_aperture_size_tcl, 0, wx.RIGHT, 10),
+                                     (y_aperture_size_txt, 0, wx.EXPAND),
+                                (self.y_aperture_size_tcl, 0, wx.RIGHT, 10),
+                                     (z_aperture_size_txt, 0, wx.EXPAND),
+                                (self.z_aperture_size_tcl, 0, wx.RIGHT, 10),
+                                     (aperture_size_unit_txt, 0, wx.EXPAND),
+                            (self.aperture_size_unit_tcl, 0, wx.RIGHT, 10)])
+        
+    def _layout_button(self):  
+        """
+        Do the layout for the button widgets
+        """ 
+        self.bt_apply = wx.Button(self, -1,'Apply')
+        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
+        self.bt_apply.SetToolTipString("Apply current changes to aperture.")
+        self.bt_cancel = wx.Button(self, -1,'Cancel')
+        self.bt_cancel.SetToolTipString("Cancel current changes.")
+        self.bt_cancel.Bind(wx.EVT_BUTTON, self.on_click_cancel)
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.SetToolTipString("Close window.")
+        self.button_sizer.AddMany([(self.bt_apply, 0, wx.LEFT, 200),
+                                   (self.bt_cancel, 0, wx.LEFT, 10),
+                                   (self.bt_close, 0, wx.LEFT, 10)])
+        
+    def _do_layout(self ):#, data=None):
+        """
+        Draw the current panel
+        """
+        self._define_structure()
+        self._layout_name()
+        self._layout_type()
+        self._layout_distance()
+        self._layout_size_name()
+        self._layout_size()
+        self._layout_button()
+        self.boxsizer_aperture.AddMany([(self.name_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.type_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.distance_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.size_name_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.aperture_size_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.main_sizer.AddMany([(self.boxsizer_aperture, 0, wx.ALL, 10),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+    
+    def set_manager(self, manager):
+        """    
+        Set manager of this window
+        """
+        self.manager = manager
+        
+    def reset_aperture(self):
+        """
+        put the default value of the detector back to the current aperture
+        """
+        self._aperture.name = self._reset_aperture.name
+        self._aperture.type = self._reset_aperture.type
+        self._aperture.size_name = self._reset_aperture.size_name
+        self._aperture.size.x = self._reset_aperture.size.x
+        self._aperture.size.y = self._reset_aperture.size.y
+        self._aperture.size.z = self._reset_aperture.size.z
+        self._aperture.size_unit = self._reset_aperture.size_unit
+        self._aperture.distance = self._reset_aperture.distance
+        self._aperture.distance_unit = self._reset_aperture.distance_unit
+        
+    def set_values(self):
+        """
+        take the aperture values of the current data and display them
+        through the panel
+        """
+        aperture = self._aperture
+        #Name
+        self.aperture_name_tcl.SetValue(str(aperture.name))
+        #Type
+        self.type_tcl.SetValue(str(aperture.type))
+        #distance
+        self.distance_tcl.SetValue(str(aperture.distance))
+        #distance unit
+        self.distance_unit_tcl.SetValue(str(aperture.distance_unit))
+        #Size name 
+        self.size_name_tcl.SetValue(str(aperture.size_name))
+        #Aperture size as a vector
+        x, y, z = aperture.size.x, aperture.size.y, aperture.size.z
+        self.x_aperture_size_tcl.SetValue(str(x))  
+        self.y_aperture_size_tcl.SetValue(str(y)) 
+        self.z_aperture_size_tcl.SetValue(str(z))  
+        self.aperture_size_unit_tcl.SetValue(str(aperture.size_unit))
+    
+    def get_aperture(self):
+        """
+        return the current aperture
+        """
+        return self._aperture
+    
+    def get_notes(self):
+        """
+        return notes
+        """
+        return self._notes
+    
+    def on_change_name(self):
+        """
+        Change name
+        """
+        #Change the name of the aperture
+        name = self.aperture_name_tcl.GetValue().lstrip().rstrip()
+        if name == "":
+            name = str(None)
+        if self._aperture.name != name:
+            self._notes += "Change sample 's "
+            self._notes += "name from %s to %s \n"% (self._aperture.name, name)
+            self._aperture.name = name
+            
+    def on_change_type(self):
+        """
+        Change aperture type
+        """
+        #Change type 
+        type = self.type_tcl.GetValue().lstrip().rstrip()
+        self._aperture.type = type
+        self._notes += " Change type from"
+        self._notes += " %s to %s \n"% (self._aperture.type, type)
+        
+    def on_change_distance(self):
+        """
+        Change distance of the aperture
+        """
+        #Change distance
+        distance = self.distance_tcl.GetValue().lstrip().rstrip()
+        if distance == "" or distance == str(None):
+            distance = None
+            self._aperture.distance = distance
+        else:
+            if check_float(self.distance_tcl):
+                if self._aperture.distance != float(distance):
+                    self._notes += "Change distance from "
+                    self._notes += "%s to %s \n"% (self._aperture.distance, 
+                                                  distance)
+                    self._aperture.distance  = float(distance)
+            else:
+                self._notes += "Error: Expected a float for distance  "
+                self._notes += "won't changes distance from "
+                self._notes += "%s to %s"% (self._aperture.distance, distance)
+        #change the distance unit
+        unit = self.distance_unit_tcl.GetValue().lstrip().rstrip()
+        if self._aperture.distance_unit != unit:
+            self._notes += " Change distance 's unit from "
+            self._notes += "%s to %s"% (self._aperture.distance_unit, unit)
+        
+    def on_change_size_name(self):
+        """
+        Change the size's name
+        """
+        #Change size name
+        size_name = self.size_name_tcl.GetValue().lstrip().rstrip()
+        self._aperture.size_name = size_name
+        self._notes += " Change size name from"
+        self._notes += " %s to %s \n"% (self._aperture.size_name, size_name)
+   
+    def on_change_size(self):
+        """
+        Change aperture size
+        """
+        #Change x coordinate
+        x_aperture_size = self.x_aperture_size_tcl.GetValue().lstrip().rstrip()
+        if x_aperture_size == "" or x_aperture_size == str(None):
+            x_aperture_size = None
+        else:
+            if check_float(self.x_aperture_size_tcl):
+                if self._aperture.size.x != float(x_aperture_size) :
+                    self._notes += "Change x of aperture size from "
+                    self._notes += "%s to %s \n"% (self._aperture.size.x,
+                                                   x_aperture_size)
+                    self._aperture.aperture_size.x  = float(x_aperture_size)
+            else:
+                self._notes += "Error: Expected a"
+                self._notes += " float for the aperture size 's x "
+                self._notes += "won't changes x aperture size from "
+                self._notes += "%s to %s"% (self._aperture.size.x, 
+                                           x_aperture_size)
+        #Change y coordinate
+        y_aperture_size = self.y_aperture_size_tcl.GetValue().lstrip().rstrip()
+        if y_aperture_size == "" or y_aperture_size == str(None):
+            y_aperture_size = None
+            self._aperture.size.y = y_aperture_size
+        else:
+            if check_float(self.y_aperture_size_tcl):
+                if self._aperture.size.y != float(y_aperture_size):
+                    self._notes += "Change y of aperture size from "
+                    self._notes += "%s to %s \n"% (self._aperture.size.y,
+                                                   y_aperture_size)
+                    self._aperture.size.y  = float(y_aperture_size)
+            else:
+                self._notes += "Error: Expected a float for the"
+                self._notes += " aperture size's y "
+                self._notes += "won't changes y aperture size from "
+                self._notes += "%s to %s"% (self._aperture.size.y,
+                                            y_aperture_size)
+        #Change z coordinate
+        z_aperture_size = self.z_aperture_size_tcl.GetValue().lstrip().rstrip()
+        if z_aperture_size == "" or z_aperture_size == str(None):
+            z_aperture_size = None
+            self._aperture.size.z = z_aperture_size
+        else:
+            if check_float(self.z_aperture_size_tcl):
+                if self._aperture.size.z != float(z_aperture_size):
+                    self._notes += "Change z of aperture size from "
+                    self._notes += "%s to %s \n"% (self._aperture.size.z,
+                                                   z_aperture_size)
+                    self._aperture.size.z  = float(z_aperture_size)
+            else:
+                self._notes += "Error: Expected a float for the offset 's x "
+                self._notes += "won't changes z aperture size from "
+                self._notes += "%s to %s"% (self._aperture.size.z,
+                                            z_aperture_size)
+        #change the aperture center unit
+        unit = self.aperture_size_unit_tcl.GetValue().lstrip().rstrip()
+        if self._aperture.size_unit != unit:
+            self._notes += " Change aperture size's unit from "
+            self._notes += "%s to %s"% (self._aperture.size_unit, unit)
+            self._aperture.size_unit = unit
+                 
+    def on_click_apply(self, event):
+        """
+        Apply user values to the aperture
+        """
+        self.on_change_name()
+        self.on_change_type()
+        self.on_change_distance()
+        self.on_change_size_name()
+        self.on_change_size()
+        self.set_values()
+        if self.manager is not None:
+            self.manager.set_aperture(self._aperture)
+        if event is not None:
+            event.Skip()
+            
+    def on_click_cancel(self, event):
+        """
+        reset the current aperture to its initial values
+        """
+        self.reset_aperture()
+        self.set_values()
+        if self.manager is not None:
+             self.manager.set_aperture(self._aperture)
+        if event is not None:
+            event.Skip()
+ 
+if __name__ == "__main__":
+   
+    app  = wx.App()
+    # Instantiate a loader 
+    loader = Loader()
+    # Load data 
+    from DataLoader.data_info import Aperture
+    ap = Aperture()
+    dlg = ApertureDialog(aperture=ap)
+    dlg.ShowModal()
+    app.MainLoop()
+ 
Index: calculatorview/src/sans/perspectives/calculator/calculator.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/calculator.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/calculator.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,118 @@
+"""
+Calculator Module
+"""
+################################################################################
+#This software was developed by the University of Tennessee as part of the
+#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+#project funded by the US National Science Foundation. 
+#
+#See the license text in license.txt
+#
+#copyright 2010, University of Tennessee
+################################################################################
+
+
+from sans.guiframe.plugin_base import PluginBase
+import logging
+
+class Plugin(PluginBase):
+    """
+    This class defines the interface for a Plugin class
+    for calculator perspective
+    """
+    def __init__(self, standalone=True):
+        PluginBase.__init__(self, name="Calculator", standalone=standalone)
+        # Log startup
+        logging.info("Calculator plug-in started")   
+  
+    def help(self, evt):
+        """
+        Show a general help dialog. 
+        
+        :TODO: replace the text with a nice image
+            provide more hint on the SLD calculator
+        """
+        from help_panel import  HelpWindow
+        frame = HelpWindow(None, -1)    
+        frame.Show(True)
+
+    def get_tools(self):
+        """
+        Returns a set of menu entries for tools
+        """
+        kiessig_help = "Approximately computes the "
+        kiessig_help += "thickness of a shell or the size of "
+        kiessig_help += "particles \n from the width of a Kiessig fringe."
+        sld_help = "Computes the Scattering Length Density."
+        slit_length_help = "Computes the slit length from the beam profile."
+        resolution_help = "Approximately estimates the "
+        resolution_help += "resolution of Q in 2D based on the SANS "
+        resolution_help += "instrumental parameter values."
+        #data_editor_help = "Meta Data Editor"
+        return [("SLD Calculator", sld_help, self.on_calculate_sld),
+                ("Slit Size Calculator", slit_length_help,
+                        self.on_calculate_slit_size),
+                ("Kiessig Thickness Calculator", 
+                        kiessig_help, self.on_calculate_kiessig),
+                          ("SANS Resolution Estimator", 
+                        resolution_help, self.on_calculate_resoltuion)]#,
+                #("Data Editor", data_editor_help, self.on_edit_data)]
+              
+    def on_edit_data(self, event):
+        """
+        Edit meta data 
+        """
+        from data_editor import DataEditorWindow
+        frame = DataEditorWindow(parent=self.parent, data=[],
+                                  title="Data Editor")
+        frame.Show(True)
+        event.Skip()
+
+    def on_calculate_kiessig(self, event):
+        """
+        Compute the Kiessig thickness
+        """
+        from kiessig_calculator_panel import KiessigWindow
+        frame = KiessigWindow()
+        frame.Show(True) 
+    
+    def on_calculate_sld(self, event):
+        """
+        Compute the scattering length density of molecula
+        """
+        from sld_panel import SldWindow
+        frame = SldWindow(base=self.parent)
+        frame.Show(True) 
+       
+    def on_calculate_slit_size(self, event):
+        """
+        Compute the slit size a given data
+        """
+        from slit_length_calculator_panel import SlitLengthCalculatorWindow
+        frame = SlitLengthCalculatorWindow(parent=self.parent)    
+        frame.Show(True)
+        
+    def on_calculate_resoltuion(self, event):
+        """
+        Estimate the instrumental resolution
+        """
+        from resolution_calculator_panel import ResolutionWindow
+        frame = ResolutionWindow(parent=self.parent)
+        frame.Show(True) 
+  
+        #def on_perspective(self, event):
+        """
+        Call back function for the perspective menu item.
+        We notify the parent window that the perspective
+        has changed.
+        
+        :param event: menu event
+        
+        """
+        #self.parent.set_perspective(self.perspective)
+        #if event != None:
+        #    event.Skip()
+
+    
+  
+    
Index: calculatorview/src/sans/perspectives/calculator/calculator_widgets.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/calculator_widgets.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/calculator_widgets.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,94 @@
+"""
+This software was developed by the University of Tennessee as part of the
+Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+project funded by the US National Science Foundation. 
+
+See the license text in license.txt
+
+copyright 2009, University of Tennessee
+"""
+import wx
+#import os
+
+class InputTextCtrl(wx.TextCtrl):
+    """
+        Text control for model and fit parameters.
+        Binds the appropriate events for user interactions.
+    """
+    def __init__(self, parent = None, *args, **kwds):
+        
+        wx.TextCtrl.__init__(self, parent, *args, **kwds)
+        
+        ## Set to True when the mouse is clicked while the whole 
+        #string is selected
+        self.full_selection = False
+        ## Call back for EVT_SET_FOCUS events
+        _on_set_focus_callback = None
+        # Bind appropriate events
+        self.Bind(wx.EVT_LEFT_UP, self._highlight_text)
+        self.Bind(wx.EVT_SET_FOCUS, self._on_set_focus)
+        self.Bind(wx.EVT_TEXT_ENTER, parent._onparamEnter )
+
+    def _on_set_focus(self, event):
+        """
+            Catch when the text control is set in focus to highlight the whole
+            text if necessary
+            @param event: mouse event
+        """
+        event.Skip()
+        self.full_selection = True
+        
+    def _highlight_text(self, event):
+        """
+            Highlight text of a TextCtrl only of no text has be selected
+            @param event: mouse event
+        """
+        # Make sure the mouse event is available to other listeners
+        event.Skip()
+        control  = event.GetEventObject()
+        if self.full_selection:
+            self.full_selection = False
+            # Check that we have a TextCtrl
+            if issubclass(control.__class__, wx.TextCtrl):
+                # Check whether text has been selected, 
+                # if not, select the whole string
+                (start, end) = control.GetSelection()
+                if start == end:
+                    control.SetSelection(-1, -1)
+
+    
+class InterActiveOutputTextCtrl(wx.TextCtrl):
+    """
+        Text control used to display outputs.
+        No editing allowed. The background is 
+        grayed out. User can't select text.
+    """
+    def __init__(self, *args, **kwds):
+        wx.TextCtrl.__init__(self, *args, **kwds)
+        self.SetEditable(False)
+        self.SetBackgroundColour(self.GetParent().GetBackgroundColour())
+        
+class OutputTextCtrl(InterActiveOutputTextCtrl):
+    """
+        Text control used to display outputs.
+        No editing allowed. The background is 
+        grayed out. User can't select text.
+    """
+    def __init__(self, *args, **kwds):
+        InterActiveOutputTextCtrl.__init__(self, *args, **kwds)
+        self.SetEditable(False)
+        self.SetBackgroundColour(self.GetParent().GetBackgroundColour())
+        
+        # Bind to mouse event to avoid text highlighting
+        # The event will be skipped once the call-back
+        # is called.
+        self.Bind(wx.EVT_MOUSE_EVENTS, self._click)
+        
+    def _click(self, event):
+        """
+            Prevent further handling of the mouse event
+            by not calling Skip().
+        """ 
+        pass
+
+      
Index: calculatorview/src/sans/perspectives/calculator/collimation_editor.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/collimation_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/collimation_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,548 @@
+"""
+"""
+import wx
+import sys
+from copy import deepcopy
+from DataLoader.loader import Loader
+from DataLoader.data_info import Aperture, Collimation
+from aperture_editor import ApertureDialog
+
+from sans.guiframe.utils import check_float
+_BOX_WIDTH = 60
+
+if sys.platform.count("win32")>0:
+    _STATICBOX_WIDTH = 500
+    PANEL_WIDTH = 530
+    PANEL_HEIGHT = 430
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 550
+    PANEL_WIDTH = 600
+    PANEL_HEIGHT = 480
+    FONT_VARIANT = 1
+    
+class CollimationDialog(wx.Dialog):
+    """
+    """
+    def __init__(self, parent=None, manager=None,
+                 collimation=[], *args, **kwds):
+        """
+        """
+        kwds['size'] = (PANEL_WIDTH, PANEL_HEIGHT)
+        kwds['title'] = "Collimation Editor"
+        wx.Dialog.__init__(self, parent=parent, *args, **kwds)
+        self.parent = parent
+        self.manager = manager 
+        self._collimation = collimation
+        self._reset_collimation = deepcopy(collimation)
+        self._notes = ""
+        self._description = "Edit collimation"
+        #layout attributes
+        self.main_sizer = None
+        self.box_collimation = None
+        self.boxsizer_collimation = None
+        
+        
+        self._do_layout()
+        self.set_values()
+ 
+    def _define_structure(self):
+        """
+        define initial sizer 
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.box_collimation = wx.StaticBox(self, -1,
+                                            str("Edit Selected Collimation"))
+        self.boxsizer_collimation = wx.StaticBoxSizer(self.box_collimation,
+                                                       wx.VERTICAL)
+        
+        collimation_box = wx.StaticBox(self, -1, "Edit Number of Collimations")
+        self.collimation_sizer = wx.StaticBoxSizer(collimation_box, wx.VERTICAL)
+        self.collimation_sizer.SetMinSize((_STATICBOX_WIDTH, -1))
+        self.collimation_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.collimation_hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        
+        self.name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.length_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        
+        aperture_box = wx.StaticBox(self, -1, "Edit Aperture")
+        self.aperture_sizer = wx.StaticBoxSizer(aperture_box, wx.VERTICAL)
+        self.aperture_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.aperture_hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
+      
+    def _layout_collimation(self):
+        """
+        Do the layout for collimation related widgets
+        """
+        collimation_name_txt = wx.StaticText(self, -1, "Collimation:") 
+        hint_collimation_txt = 'Current available collimation.'
+        collimation_name_txt.SetToolTipString(hint_collimation_txt) 
+        self.collimation_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
+        wx.EVT_COMBOBOX(self.collimation_cbox, -1, self.on_select_collimation) 
+        hint_collimation_name_txt = 'Name of collimations.'
+        self.collimation_cbox.SetToolTipString(hint_collimation_name_txt) 
+   
+        self.bt_add_collimation = wx.Button(self, -1, "Add")
+        self.bt_add_collimation.SetToolTipString("Edit data's collimation.")
+        self.bt_add_collimation.Bind(wx.EVT_BUTTON, self.add_collimation)
+        
+        self.bt_remove_collimation = wx.Button(self, -1, "Remove")
+        hint = "Remove data's collimation."
+        self.bt_remove_collimation.SetToolTipString(hint)
+        self.bt_remove_collimation.Bind(wx.EVT_BUTTON, self.remove_collimation)
+      
+        self.collimation_button_sizer.AddMany([(collimation_name_txt, 0,
+                                                 wx.LEFT, 15),
+                                     (self.collimation_cbox, 0, wx.LEFT, 5),
+                                     (self.bt_add_collimation, 0, wx.LEFT, 10),
+                                     (self.bt_remove_collimation,
+                                       0, wx.LEFT, 5)])
+        collimation_hint_txt = 'No collimation is available for this data.'
+        self.collimation_txt = wx.StaticText(self, -1, collimation_hint_txt) 
+        self.collimation_hint_sizer.Add(self.collimation_txt, 0, wx.LEFT, 10)
+        self.collimation_sizer.AddMany([(self.collimation_button_sizer,
+                                          0, wx.ALL, 10),
+                                     (self.collimation_hint_sizer,
+                                       0, wx.ALL, 10)])
+     
+        self.fill_collimation_combox()
+        self.enable_collimation()
+        
+
+    def _layout_name(self):
+        """
+        Do the layout for collimation name related widgets
+        """
+        #Collimation name [string]
+        name_txt = wx.StaticText(self, -1, 'Name : ')  
+        self.name_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH*5, 20), style=0) 
+        self.name_sizer.AddMany([(name_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                       (self.name_tcl, 0, wx.EXPAND)])
+        
+    def _layout_length(self):
+        """
+        Do the  layout for length related widgets
+        """
+        #Collimation length
+        length_txt = wx.StaticText(self, -1, 'Length:') 
+        self.length_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0)   
+        length_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.length_unit_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20),
+                                           style=0)  
+        self.length_sizer.AddMany([(length_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.length_tcl, 0, wx.LEFT, 12),
+                                     (length_unit_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.length_unit_tcl, 0, wx.EXPAND)]) 
+   
+    def _layout_button(self):  
+        """
+        Do the layout for the button widgets
+        """ 
+        self.bt_apply = wx.Button(self, -1,'Apply')
+        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
+        self.bt_apply.SetToolTipString("Apply current changes to collimation.")
+        self.bt_cancel = wx.Button(self, -1,'Cancel')
+        self.bt_cancel.SetToolTipString("Cancel current changes.")
+        self.bt_cancel.Bind(wx.EVT_BUTTON, self.on_click_cancel)
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.SetToolTipString("Close window.")
+        self.button_sizer.AddMany([(self.bt_apply, 0, wx.LEFT, 200),
+                                   (self.bt_cancel, 0, wx.LEFT, 10),
+                                   (self.bt_close, 0, wx.LEFT, 10)])
+    def _layout_aperture(self):
+        """
+        Do the layout for aperture related widgets
+        """
+        aperture_name_txt = wx.StaticText(self, -1, "Aperture:") 
+        hint_aperture_txt = 'Current available aperture.'
+        aperture_name_txt.SetToolTipString(hint_aperture_txt) 
+        self.aperture_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
+        hint_aperture_name_txt = 'Name of apertures.'
+        self.aperture_cbox.SetToolTipString(hint_aperture_name_txt) 
+    
+        self.bt_add_aperture = wx.Button(self, -1, "Add")
+        self.bt_add_aperture.SetToolTipString("Edit data's aperture.")
+        self.bt_add_aperture.Bind(wx.EVT_BUTTON, self.add_aperture)
+        self.bt_edit_aperture = wx.Button(self, -1, "Edit")
+        self.bt_edit_aperture.SetToolTipString("Edit data's aperture.")
+        self.bt_edit_aperture.Bind(wx.EVT_BUTTON, self.edit_aperture)
+        self.bt_remove_aperture = wx.Button(self, -1, "Remove")
+        self.bt_remove_aperture.SetToolTipString("Remove data's aperture.")
+        self.bt_remove_aperture.Bind(wx.EVT_BUTTON, self.remove_aperture)
+      
+        self.aperture_button_sizer.AddMany([(aperture_name_txt, 0, wx.LEFT, 15),
+                                     (self.aperture_cbox, 0, wx.LEFT, 5),
+                                     (self.bt_add_aperture, 0, wx.LEFT, 10),
+                                     (self.bt_edit_aperture, 0, wx.LEFT, 5),
+                                     (self.bt_remove_aperture, 0, wx.LEFT, 5)])
+        aperture_hint_txt = 'No aperture is available for this data.'
+        self.aperture_txt = wx.StaticText(self, -1, aperture_hint_txt) 
+        self.aperture_hint_sizer.Add(self.aperture_txt, 0, wx.LEFT, 10)
+        self.aperture_sizer.AddMany([(self.aperture_button_sizer,
+                                       0, wx.ALL, 10),
+                                     (self.aperture_hint_sizer, 0, wx.ALL, 10)])
+        self.fill_aperture_combox()
+        self.enable_aperture()
+    
+    def _do_layout(self):
+        """
+        Draw the current panel
+        """
+        self._define_structure()
+        self._layout_collimation()
+        self._layout_name()
+        self._layout_length()
+        self._layout_aperture()
+        self._layout_button()
+     
+        self.boxsizer_collimation.AddMany([(self.name_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                          (self.length_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                     (self.aperture_sizer, 0,
+                                     wx.EXPAND|wx.ALL, 10)])
+        self.main_sizer.AddMany([(self.collimation_sizer, 0, wx.ALL, 10),
+                                  (self.boxsizer_collimation, 0, wx.ALL, 10),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+        
+    def get_current_collimation(self):
+        """
+        """
+        if not self.collimation_cbox.IsEnabled():
+            return None, None, None
+        position = self.collimation_cbox.GetSelection() 
+        if position == wx.NOT_FOUND:
+            return None, None, None
+        collimation_name = self.collimation_cbox.GetStringSelection() 
+        collimation = self.collimation_cbox.GetClientData(position)
+        return collimation, collimation_name, position
+    
+    def fill_collimation_combox(self):
+        """
+        fill the current combobox with the available collimation
+        """
+        if self._collimation is None or self._collimation == []:
+            return
+        for collimation in self._collimation:
+            pos = self.collimation_cbox.Append(str(collimation.name))
+            self.collimation_cbox.SetClientData(pos, collimation)
+            self.collimation_cbox.SetSelection(pos)
+            self.collimation_cbox.SetStringSelection(str(collimation.name)) 
+            
+    def add_collimation(self, event):
+        """
+        Append empty collimation to data's list of collimation
+        """
+        
+        if not self.collimation_cbox.IsEnabled():
+            self.collimation_cbox.Enable()
+        collimation = Collimation()
+        self._collimation.append(collimation)
+        position = self.collimation_cbox.Append(str(collimation.name))
+        self.collimation_cbox.SetClientData(position, collimation)
+        self.collimation_cbox.SetSelection(position) 
+        self.enable_collimation() 
+        self.bt_add_aperture.Enable()
+        self.fill_aperture_combox()
+        self.enable_aperture()
+        self.set_values()
+        
+    def remove_collimation(self, event):
+        """
+        Remove collimation to data's list of collimation
+        """
+        if self.collimation_cbox.IsEnabled():
+            if self.collimation_cbox.GetCount() > 0:
+                position = self.collimation_cbox.GetCurrentSelection()
+                collimation = self.collimation_cbox.GetClientData(position)
+                if collimation in self._collimation:
+                    self._collimation.remove(collimation)
+                    self.collimation_cbox.Delete(position) 
+                    #set the combo box box the next available item
+                    position = self.collimation_cbox.GetCount()
+                    if position > 0:
+                        position -= 1 
+                    self.collimation_cbox.SetSelection(position)
+        if not self._collimation and self.collimation_cbox.GetCount() == 0:       
+            self.bt_add_aperture.Disable()  
+            self.name_tcl.Clear()
+            self.length_tcl.Clear()
+            self.length_unit_tcl.Clear()
+            self.aperture_cbox.Clear()
+            self.aperture_cbox.Disable()
+        #disable or enable the combo box when necessary
+        self.enable_collimation()
+        self.enable_aperture()
+        
+    def on_select_collimation(self, event):
+        """
+        fill the control on the panel according to 
+        the current  selected collimation 
+        """
+        self.set_values()
+        self.fill_aperture_combox()
+        self.enable_aperture()
+    
+    def enable_collimation(self):
+        """
+        Enable /disable widgets related to collimation
+        """
+        if self._collimation is not None and \
+            self.collimation_cbox.GetCount() > 0:
+            self.collimation_cbox.Enable()
+            self.bt_remove_collimation.Enable()
+            n_collimation = self.collimation_cbox.GetCount()
+            collimation_hint_txt = "collimations"
+            collimation_hint_txt += " available: %s "% str(n_collimation)
+            if len(self._collimation) > 0:
+                self.bt_remove_collimation.Enable()
+            else:
+                self.bt_remove_collimation.Disable()
+        else:
+            self.collimation_cbox.Disable()
+            self.bt_remove_collimation.Disable()
+            collimation_hint_txt = 'No collimation is available for this data.'
+        self.collimation_txt.SetLabel(collimation_hint_txt)
+           
+   
+    def reset_collimation_combobox(self, edited_collimation):
+        """
+        take all edited editor and reset clientdata of collimation combo box
+        """
+        for position in range(self.collimation_cbox.GetCount()):
+            collimation = self.collimation_cbox.GetClientData(position)
+            if collimation == edited_collimation:
+                collimation = edited_collimation
+                self.collimation_cbox.SetString(position, str(collimation.name)) 
+                self.collimation_cbox.SetClientData(position, collimation)
+                self.collimation_cbox.SetStringSelection(str(collimation.name)) 
+         
+    def add_aperture(self, event):
+        """
+        Append empty aperture to data's list of aperture
+        """
+        collimation, _, _ = self.get_current_collimation()
+        if not self.aperture_cbox.IsEnabled():
+            self.aperture_cbox.Enable()
+        aperture = Aperture()
+        collimation.aperture.append(aperture)
+        position = self.aperture_cbox.Append(str(aperture.name))
+        self.aperture_cbox.SetClientData(position, aperture)
+        self.aperture_cbox.SetSelection(position) 
+        self.enable_aperture()
+        
+    def edit_aperture(self, event):
+        """
+        Edit the selected aperture
+        """
+        if self._collimation is None or not self.aperture_cbox.IsEnabled():
+            return 
+        position = self.aperture_cbox.GetSelection() 
+        if position != wx.NOT_FOUND:
+            name = self.aperture_cbox.GetStringSelection() 
+            aperture = self.aperture_cbox.GetClientData(position)
+            dlg = ApertureDialog(parent=self, aperture=aperture)
+            dlg.set_manager(self)
+            dlg.ShowModal()
+            
+    def remove_aperture(self, event):
+        """
+        Remove aperture to data's list of aperture
+        """
+        if self._collimation is None or not self._collimation:
+            return
+        collimation, _, _ = self.get_current_collimation()
+        if self.aperture_cbox.IsEnabled():
+            if self.aperture_cbox.GetCount() > 1:
+                position = self.aperture_cbox.GetCurrentSelection()
+                aperture = self.aperture_cbox.GetClientData(position)
+                if aperture in collimation.aperture:
+                    collimation.aperture.remove(aperture)
+                    self.aperture_cbox.Delete(position) 
+                    #set the combo box box the next available item
+                    position = self.aperture_cbox.GetCount()
+                    if position > 0:
+                        position -= 1 
+                    self.aperture_cbox.SetSelection(position)
+                   
+        #disable or enable the combo box when necessary
+        self.enable_aperture()
+        
+    def set_aperture(self, aperture):
+        """
+        set aperture for data
+        """
+        if self._collimation is None or not self._collimation:
+            return
+        collimation, _, _ = self.get_current_collimation()
+        if collimation.aperture:
+            for item in collimation.aperture:
+                if item == aperture:
+                    item = aperture
+                    self.reset_aperture_combobox(edited_aperture=aperture)
+                    return
+                
+    def enable_aperture(self):
+        """
+        Enable /disable widgets crelated to aperture
+        """
+        collimation, _, _ = self.get_current_collimation()
+        if  self.aperture_cbox.GetCount() > 0:
+            self.aperture_cbox.Enable()
+            self.bt_edit_aperture.Enable()
+            self.bt_remove_aperture.Enable()
+            n_aperture = self.aperture_cbox.GetCount()
+            aperture_hint_txt = 'apertures available: %s '%str(n_aperture)
+            if len(collimation.aperture) > 0:
+                self.bt_remove_aperture.Enable()
+            else:
+                self.bt_remove_aperture.Disable()
+        else:
+            self.aperture_cbox.Disable()
+            self.bt_edit_aperture.Disable()
+            self.bt_remove_aperture.Disable()
+            aperture_hint_txt = 'No aperture is available for this data.'
+        self.aperture_txt.SetLabel(aperture_hint_txt)
+    
+    def reset_aperture_combobox(self, edited_aperture):
+        """
+        take all edited editor and reset clientdata of aperture combo box
+        """
+        for position in range(self.aperture_cbox.GetCount()):
+            aperture = self.aperture_cbox.GetClientData(position)
+            if aperture == edited_aperture:
+                aperture = edited_aperture
+                self.aperture_cbox.SetString(position, str(aperture.name)) 
+                self.aperture_cbox.SetClientData(position, aperture)
+                self.aperture_cbox.SetStringSelection(str(aperture.name)) 
+                
+    def fill_aperture_combox(self):
+        """
+        fill the current combobox with the available aperture
+        """
+        self.aperture_cbox.Clear()
+        collimation, _, _ = self.get_current_collimation()
+        if collimation is None or not collimation.aperture:
+            return
+        for aperture in collimation.aperture:
+            pos = self.aperture_cbox.Append(str(aperture.name))
+            self.aperture_cbox.SetClientData(pos, aperture)
+            self.aperture_cbox.SetSelection(pos)
+            self.aperture_cbox.SetStringSelection(str(aperture.name)) 
+         
+    def set_manager(self, manager):
+        """    
+        Set manager of this window
+        """
+        self.manager = manager
+        
+    def set_values(self):
+        """
+        take the collimation values of the current data and display them
+        through the panel
+        """
+        collimation, _, _ = self.get_current_collimation()
+        if collimation is None:
+            self.bt_add_aperture.Disable()
+            self.length_tcl.SetValue("")
+            self.name_tcl.SetValue("")
+            self.length_unit_tcl.SetValue("")
+            return
+        #Name
+        self.name_tcl.SetValue(str(collimation.name))
+        #length
+        self.length_tcl.SetValue(str(collimation.length))
+        #Length unit
+        self.length_unit_tcl.SetValue(str(collimation.length_unit))
+        
+    def get_collimation(self):
+        """
+        return the current collimation
+        """
+        return self._collimation
+    
+    def get_notes(self):
+        """
+        return notes
+        """
+        return self._notes
+    
+    def on_change_name(self):
+        """
+        Change name
+        """
+        collimation, collimation_name, position = self.get_current_collimation()
+        if collimation is None: 
+            return
+        #Change the name of the collimation
+        name = self.name_tcl.GetValue().lstrip().rstrip()
+        if name == "" or name == str(None):
+            name = None
+        if collimation.name != name:
+            self._notes += "Change collimation 's "
+            self._notes += "name from %s to %s \n"%(collimation.name, name)
+            collimation.name = name
+            self.collimation_cbox.SetString(position, str(collimation.name)) 
+            self.collimation_cbox.SetClientData(position, collimation)
+            self.collimation_cbox.SetStringSelection(str(collimation.name)) 
+   
+    def on_change_length(self):
+        """
+        Change the length
+        """
+        collimation, collimation_name, position = self.get_current_collimation()
+        if collimation is None: 
+            return
+        #Change length  
+        length = self.length_tcl.GetValue().lstrip().rstrip()
+        if length == "" or length == str(None):
+            length = None
+            collimation.length = length
+        else:
+            if check_float(self.length_tcl):
+                if collimation.length != float(length):
+                    self._notes += "Change Collimation length from "
+                    self._notes += "%s to %s \n"%(collimation.length, length)
+                    collimation.length  = float(length)
+            else:
+                self._notes += "Error: Expected a float for collimation length"
+                self._notes += " won't changes length from "
+                self._notes += "%s to %s"%(collimation.length, length)
+        #change length  unit
+        unit = self.length_unit_tcl.GetValue().lstrip().rstrip()
+        if collimation.length_unit != unit:
+            self._notes += " Change length's unit from "
+            self._notes += "%s to %s"%(collimation.length_unit, unit)
+            collimation.length_unit = unit
+    
+    def on_click_apply(self, event):
+        """
+        Apply user values to the collimation
+        """
+        self.on_change_name()
+        self.on_change_length()
+        self.set_values()
+        if self.manager is not None:
+            self.manager.set_collimation(self._collimation, self._notes)
+       
+    def on_click_cancel(self, event):
+        """
+        leave the collimation as it is and close
+        """
+        self._collimation = deepcopy(self._reset_collimation)
+        self.set_values()
+        if self.manager is not None:
+            self.manager.set_collimation(self._collimation)
+       
+ 
+if __name__ == "__main__":
+
+    app  = wx.App()
+    dlg = CollimationDialog(collimation=[Collimation()])
+    dlg.ShowModal()
+    app.MainLoop()
+ 
Index: calculatorview/src/sans/perspectives/calculator/console.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/console.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/console.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,64 @@
+"""
+Console Module display message of a dialog
+"""
+import wx
+import sys
+from DataLoader.loader import Loader
+
+_BOX_WIDTH = 60
+CONSOLE_WIDTH = 340
+CONSOLE_HEIGHT = 240
+if sys.platform.count("win32")>0:
+    _STATICBOX_WIDTH = 450
+    PANEL_WIDTH = 500
+    PANEL_HEIGHT = 550
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 480
+    PANEL_WIDTH = 530
+    PANEL_HEIGHT = 560
+    FONT_VARIANT = 1
+    
+
+class ConsoleDialog(wx.Dialog):
+    def __init__(self, parent=None, manager=None, data=None,
+                    title="Data Summary", size=(PANEL_WIDTH, PANEL_HEIGHT)):
+        wx.Dialog.__init__(self, parent=parent, title=title, size=size)
+   
+        self.parent = parent
+        self._manager = manager
+        self._data = data
+        self.sizer = wx.BoxSizer(wx.VERTICAL)
+        self.msg_txt = wx.TextCtrl(self, size=(PANEL_WIDTH-40,
+                                                PANEL_HEIGHT-60), 
+                                        style=wx.TE_MULTILINE)
+        self.msg_txt.SetEditable(False)
+        self.msg_txt.SetValue('No message available')
+        self.sizer.Add(self.msg_txt, 1, wx.EXPAND|wx.ALL, 10)
+        if self._data is not None:
+            self.set_message(msg=self._data.__str__())
+            
+        self.SetSizer(self.sizer)
+        
+    def set_manager(self, manager):
+        """
+        Set the manager of this window
+        """
+        self._manager = manager
+        
+    def set_message(self, msg=""):  
+        """
+        Display the message received 
+        """
+        self.msg_txt.SetValue(str(msg))
+ 
+if __name__ == "__main__":
+   
+    app  = wx.App()
+    # Instantiate a loader 
+    loader = Loader()
+    # Load data 
+    test_data = loader.load("MAR07232_rest.ASC")
+    dlg = ConsoleDialog(data=test_data)
+    dlg.ShowModal()
+    app.MainLoop()
Index: calculatorview/src/sans/perspectives/calculator/data_editor.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/data_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/data_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,656 @@
+
+import wx
+import sys
+import os 
+from copy import deepcopy
+
+from DataLoader.loader import Loader
+#from DataLoader.data_info import DataInfo
+#from DataLoader.data_info import  Detector
+#from DataLoader.data_info import Collimation
+from DataLoader.data_info import Data2D
+from detector_editor import DetectorDialog
+from collimation_editor import CollimationDialog
+from console import ConsoleDialog
+
+#from sans.guiframe.utils import check_float
+from sans.guiframe.events import StatusEvent
+
+
+_QMIN_DEFAULT = 0.001
+_QMAX_DEFAULT = 0.13
+_NPTS_DEFAULT = 50
+#Control panel width 
+if sys.platform.count("darwin") == 0:
+    PANEL_WIDTH = 500
+    PANEL_HEIGTH = 350
+    FONT_VARIANT = 0
+    _BOX_WIDTH = 51
+    ON_MAC = False
+else:
+    _BOX_WIDTH = 76
+    PANEL_WIDTH = 550
+    PANEL_HEIGTH = 400
+    FONT_VARIANT = 1
+    ON_MAC = True
+    
+def load_error(error=None):
+    """
+        Pop up an error message.
+        
+        @param error: details error message to be displayed
+    """
+    message = "You had to try this, didn't you?\n\n"
+    message += "The data file you selected could not be loaded.\n"
+    message += "Make sure the content of your file is properly formatted.\n\n"
+    
+    if error is not None:
+        message += "When contacting the DANSE team,"
+        message += " mention the following:\n%s" % str(error)
+    
+    dial = wx.MessageDialog(None, message, 
+                            'Error Loading File', wx.OK | wx.ICON_EXCLAMATION)
+    dial.ShowModal() 
+    
+    
+class DataEditorPanel(wx.ScrolledWindow):
+    """
+    :param data: when not empty the class can 
+                same information into a dat object
+        and post event containing the changed data object to some other frame
+    """
+    def __init__(self, parent, data=[], *args, **kwds):
+        kwds['name'] = "Data Editor"
+        kwds["size"] = (PANEL_WIDTH, PANEL_HEIGTH)
+        wx.ScrolledWindow.__init__(self, parent, *args, **kwds)
+        self.parent = parent
+        self._data = data
+        self._reset_data = deepcopy(data)
+        self.reader = None
+        self._notes = ""
+        self._description = "Edit Data"
+        self._default_save_location = os.getcwd()
+        self._do_layout()
+        self.reset_panel()
+        self.bt_apply.Disable()
+        if data:
+            self.complete_loading(data=data)
+            self.bt_apply.Enable()
+             
+    def _define_structure(self):
+        """
+        define initial sizer 
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        name_box = wx.StaticBox(self, -1, "Load Data")
+        self.name_sizer = wx.StaticBoxSizer(name_box, wx.HORIZONTAL)
+        
+        self.title_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.run_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.instrument_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        
+        edit_box = wx.StaticBox(self, -1, "Edit ")
+        self.edit_sizer = wx.StaticBoxSizer(edit_box, wx.HORIZONTAL)
+        
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+      
+    def _layout_name(self):
+        """
+        Do the layout for data name related widgets
+        """
+        #data name [string]
+        data_name_txt = wx.StaticText(self, -1, 'Data : ')  
+        self.data_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
+        wx.EVT_COMBOBOX(self.data_cbox, -1, self.on_select_data) 
+        hint_data = "Loaded data."
+        self.data_cbox.SetToolTipString(hint_data)
+        id = wx.NewId()
+        self.browse_button = wx.Button(self, id, "Browse")
+        hint_on_browse = "Click on this button to import data in this panel."
+        self.browse_button.SetToolTipString(hint_on_browse)
+        self.Bind(wx.EVT_BUTTON, self.on_click_browse, id=id)
+        self.name_sizer.AddMany([(data_name_txt, 0, wx.LEFT, 15),
+                                       (self.data_cbox, 0, wx.LEFT, 10),
+                                       (self.browse_button, 0, wx.LEFT, 10)])
+        
+    def _layout_title(self):
+        """
+        Do the layout for data title related widgets
+        """
+        #title name [string]
+        data_title_txt = wx.StaticText(self, -1, 'Title : ')  
+        self.data_title_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH*3/5, -1)) 
+        self.data_title_tcl.Bind(wx.EVT_TEXT_ENTER, self.on_change_title)
+        hint_title = "Data's title."
+        self.data_title_tcl.SetToolTipString(hint_title)
+        self.title_sizer.AddMany([(data_title_txt, 0, wx.LEFT, 15),
+                                       (self.data_title_tcl, 0, wx.LEFT, 10)])
+        
+    def _layout_run(self):
+        """
+        Do the layout for data run related widgets
+        """
+        data_run_txt = wx.StaticText(self, -1, 'Run : ') 
+        data_run_txt.SetToolTipString('') 
+        self.data_run_tcl = wx.TextCtrl(self, -1, size=(PANEL_WIDTH*3/5, -1),
+                                         style=wx.TE_MULTILINE)
+        hint_run = "Data's run."
+        self.data_run_tcl.SetToolTipString(hint_run)
+        self.run_sizer.AddMany([(data_run_txt, 0, wx.LEFT, 15),
+                                       (self.data_run_tcl, 0, wx.LEFT, 10)])
+        
+    def _layout_instrument(self):
+        """
+        Do the layout for instrument related widgets
+        """
+        instrument_txt = wx.StaticText(self, -1, 'Instrument : ') 
+        hint_instrument_txt = ''
+        instrument_txt.SetToolTipString(hint_instrument_txt) 
+        self.instrument_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH*5, 20)) 
+        hint_instrument = "Instrument."
+        self.instrument_tcl.SetToolTipString(hint_instrument)
+        self.instrument_sizer.AddMany([(instrument_txt, 0, wx.LEFT, 15),
+                                (self.instrument_tcl, 0, wx.LEFT, 10)])
+        
+    def _layout_editor(self):
+        """
+        Do the layout for sample related widgets
+        """
+        self.detector_rb = wx.RadioButton(self, -1, "Detector",
+                                           style=wx.RB_GROUP)
+        self.sample_rb = wx.RadioButton(self, -1, "Sample")
+        self.source_rb = wx.RadioButton(self, -1, "Source")
+        self.collimation_rb = wx.RadioButton(self, -1, "Collimation")
+       
+        self.bt_edit = wx.Button(self, -1, "Edit")
+        self.bt_edit.SetToolTipString("Edit data.")
+        self.bt_edit.Bind(wx.EVT_BUTTON, self.on_edit)
+        self.edit_sizer.AddMany([(self.detector_rb, 0, wx.ALL, 10),
+                        (self.sample_rb, 0, wx.RIGHT|wx.BOTTOM|wx.TOP, 10),
+                        (self.source_rb, 0, wx.RIGHT|wx.BOTTOM|wx.TOP, 10),
+                    (self.collimation_rb, 0, wx.RIGHT|wx.BOTTOM|wx.TOP, 10),
+                    (self.bt_edit, 0,
+                                  wx.RIGHT|wx.BOTTOM|wx.TOP, 10)])
+        self.reset_radiobox()
+   
+    
+    def _layout_source(self):
+        """
+            Do the layout for source related widgets
+        """
+        source_txt = wx.StaticText(self, -1, 'Source ') 
+        hint_source_txt = ''
+        source_txt.SetToolTipString(hint_source_txt) 
+        self.bt_edit_source = wx.Button(self, -1, "Edit")
+        self.bt_edit_source.SetToolTipString("Edit data's sample.")
+        self.bt_edit_source.Bind(wx.EVT_BUTTON, self.edit_source)
+        self.source_sizer.AddMany([(source_txt, 0, wx.ALL, 10),
+                                (self.bt_edit_source, 0,
+                                  wx.RIGHT|wx.BOTTOM|wx.TOP, 10)])
+
+    def _layout_summary(self):
+        """
+            Layout widgets related to data's summary
+        """
+        self.data_summary = wx.TextCtrl(self, -1,
+                                         style=wx.TE_MULTILINE|wx.HSCROLL,
+                                        size=(-1, 200))
+        summary = 'No data info available...'
+        self.data_summary.SetValue(summary)
+        self.summary_sizer.Add(self.data_summary, 1, wx.EXPAND|wx.ALL, 10)  
+                    
+    def _layout_button(self):  
+        """
+            Do the layout for the button widgets
+        """ 
+        self.bt_summary = wx.Button(self, -1, "View", size=(_BOX_WIDTH, -1))
+        self.bt_summary.SetToolTipString("View final changes on data.")
+        self.bt_summary.Bind(wx.EVT_BUTTON, self.on_click_view)
+        
+        self.bt_save = wx.Button(self, -1, "Save As", size=(_BOX_WIDTH, -1))
+        self.bt_save.SetToolTipString("Save changes in a file.")
+        self.bt_save.Bind(wx.EVT_BUTTON, self.on_click_save)
+        
+        self.bt_apply = wx.Button(self, -1, "Apply", size=(_BOX_WIDTH, -1))
+        self.bt_apply.SetToolTipString("Save changes into the imported data.")
+        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
+      
+        self.bt_reset = wx.Button(self, -1, 'Reset', size=(_BOX_WIDTH, -1))
+        self.bt_reset.Bind(wx.EVT_BUTTON, self.on_click_reset)
+        self.bt_reset.SetToolTipString("Reset data to its initial state.")
+        
+        self.bt_close = wx.Button(self, -1, 'Close', size=(_BOX_WIDTH, -1))
+        self.bt_close.Bind(wx.EVT_BUTTON, self.on_close)
+        self.bt_close.SetToolTipString("Close this panel.")
+        
+        self.button_sizer.AddMany([(self.bt_save, 0, wx.LEFT, 120),
+                                   (self.bt_apply, 0, wx.LEFT, 10),
+                                   (self.bt_reset, 0, wx.LEFT|wx.RIGHT, 10),
+                                   (self.bt_summary, 0, wx.RIGHT, 10),
+                                   (self.bt_close, 0, wx.RIGHT, 10)])
+        
+    def _do_layout(self):
+        """
+        Draw the current panel
+        """
+        self._define_structure()
+        self._layout_name()
+        self._layout_title()
+        self._layout_run()
+        self._layout_editor()
+        self._layout_button()
+        self.main_sizer.AddMany([(self.name_sizer, 0, wx.EXPAND|wx.ALL, 10),
+                                (self.title_sizer, 0,
+                                         wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                (self.run_sizer, 0,
+                                         wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                (self.instrument_sizer, 0,
+                                         wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                (self.edit_sizer, 0,
+                                        wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP,10),
+                                (self.button_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.SetSizer(self.main_sizer)
+        self.SetScrollbars(20, 20, 25, 65)
+        self.SetAutoLayout(True)
+        
+    def fill_data_combox(self):
+        """
+        fill the current combobox with the available data
+        """
+        if not self._data:
+            return
+        self.data_cbox.Clear()
+        for data in self._data:
+            name = data.title
+            if data.run:
+                name = data.run[0]
+            if name.lstrip().rstrip() =="":
+                name = data.filename
+            pos = self.data_cbox.Append(str(name))
+            self.data_cbox.SetClientData(pos, data)
+            self.data_cbox.SetSelection(pos)
+            self.data_cbox.SetStringSelection(str(name)) 
+       
+    def reset_panel(self):
+        """
+        """
+        self.enable_data_cbox()
+        self.data_title_tcl.SetValue("")
+        self.data_run_tcl.SetValue("")
+        
+    def on_select_data(self, event=None):
+        """
+        """
+        data, _, _ = self.get_current_data()
+        self.reset_panel()
+        if data is None:
+            return
+        self.data_title_tcl.SetValue(str(data.title))
+        text = ""
+        if data.run:
+            for item in data.run:
+                text += item+"\n"
+        self.data_run_tcl.SetValue(str(text))
+            
+    def get_current_data(self):
+        """
+        """
+        position = self.data_cbox.GetSelection() 
+        if position == wx.NOT_FOUND:
+            return None, None, None
+        data_name = self.data_cbox.GetStringSelection() 
+        data = self.data_cbox.GetClientData(position)
+        return data, data_name, position
+    
+    def enable_data_cbox(self):
+        """
+        """
+        if self._data:
+            self.data_cbox.Enable()
+            self.bt_summary.Enable()
+            self.bt_reset.Enable()
+            self.bt_save.Enable()
+            self.bt_edit.Enable()
+        else:
+            self.data_cbox.Disable()
+            self.bt_summary.Disable()
+            self.bt_reset.Disable()
+            self.bt_save.Disable()
+            self.bt_edit.Disable()
+            
+    def reset_radiobox(self):
+        """
+        """
+        self.detector_rb.SetValue(True)
+        self.source_rb.SetValue(False)
+        self.sample_rb.SetValue(False)
+        self.collimation_rb.SetValue(False)
+    
+    def set_sample(self, sample, notes=None):
+        """
+        set sample for data
+        """
+        data, _, _ = self.get_current_data()
+        if data is None:
+            return 
+        data.sample = sample
+        if notes is not None:
+            data.process.append(notes)
+    
+    def set_source(self, source, notes=None):
+        """
+        set source for data
+        """
+        data, data_name, position = self.get_current_data()
+        if data is None:
+            return 
+        data.source = source
+        if notes is not None:
+            data.process.append(notes)
+        
+    def set_detector(self, detector, notes=None):
+        """
+        set detector for data
+        """
+        data, data_name, position = self.get_current_data()
+        if data is None:
+            return 
+        data.detector = detector
+        if notes is not None:
+            data.process.append(notes)
+        
+    def set_collimation(self, collimation, notes=None):
+        """
+        set collimation for data
+        """
+        data, data_name, position = self.get_current_data()
+        if data is None:
+            return 
+        data.collimation = collimation
+        if notes is not None:
+            data.process.append(notes)
+                
+    def edit_collimation(self):
+        """
+        Edit the selected collimation
+        """
+        data, data_name, position = self.get_current_data()
+        if data is None:
+            return 
+        dlg = CollimationDialog(collimation=data.collimation)
+        dlg.set_manager(self)
+        dlg.ShowModal()
+            
+    def edit_detector(self):
+        """
+        Edit the selected detector
+        """
+        data, data_name, position = self.get_current_data()
+        if data is None:
+            return 
+        dlg = DetectorDialog(detector=data.detector)
+        dlg.set_manager(self)
+        dlg.ShowModal()
+
+    def edit_sample(self):
+        """
+        Open the dialog to edit the sample of the current data
+        """
+        data, _, _ = self.get_current_data()
+        if data is None:
+            return
+        from sample_editor import SampleDialog
+        dlg = SampleDialog(parent=self, sample=data.sample)
+        dlg.set_manager(self)
+        dlg.ShowModal()
+        
+    def edit_source(self):
+        """
+        Open the dialog to edit the saource of the current data
+        """
+        data, data_name, position = self.get_current_data()
+        if data is None:
+            return
+        from source_editor import SourceDialog
+        dlg = SourceDialog(parent=self, source=data.source)
+        dlg.set_manager(self)
+        dlg.ShowModal()
+        
+    def choose_data_file(self, location=None):
+        """
+        Open a file dialog to allow loading a file
+        """
+        path = None
+        if location == None:
+            location = os.getcwd()
+        
+        l = Loader()
+        cards = l.get_wildcards()
+        wlist = '|'.join(cards)
+        
+        dlg = wx.FileDialog(self, "Choose a file", location, "", wlist, wx.OPEN)
+        if dlg.ShowModal() == wx.ID_OK:
+            path = dlg.GetPath()
+            mypath = os.path.basename(path)
+        dlg.Destroy()
+        return path
+    
+    
+    def complete_loading(self, data=None, filename=''):
+        """
+        Complete the loading and compute the slit size
+        """
+        self.done = True
+        self._data = []
+        if data is None:
+            msg = "Couldn't load data"
+            wx.PostEvent(self.parent.parent, StatusEvent(status=msg,
+                                             info="warning",type='stop'))
+            return 
+        if not  data.__class__.__name__ == "list":
+            self._data.append(data)
+            self._reset_data.append(deepcopy(data))
+        else:
+            self._data = deepcopy(data)
+            self._reset_data = deepcopy(data)
+        self.set_values()
+        if self.parent.parent is None:
+            return 
+        msg = "Load Complete"
+        wx.PostEvent(self.parent.parent, StatusEvent(status=msg,
+                                                info="info",type='stop'))
+  
+    def set_values(self):
+        """
+        take the aperture values of the current data and display them
+        through the panel
+        """
+        if self._data:
+            self.fill_data_combox()
+            self.on_select_data(event=None)
+        
+    def get_data(self):
+        """
+        return the current data
+        """
+        return self._data
+    
+    def get_notes(self):
+        """
+        return notes
+        """
+        return self._notes
+    
+    def on_change_run(self, event=None):
+        """
+        Change run
+        """
+        run = []
+        data, _, _ = self.get_current_data()
+        for i in range(self.data_run_tcl.GetNumberOfLines()):
+            text = self.data_run_tcl.GetLineText(i).lstrip().rstrip()
+            if text != "":
+                run.append(text)
+        if data.run != run:
+            self._notes += "Change data 's "
+            self._notes += "run from %s to %s \n" % (data.run, str(run))
+            data.run = run
+        if event is not None:
+            event.Skip()
+                 
+    def on_change_title(self, event=None):
+        """
+        Change title
+        """
+        data, _, _ = self.get_current_data()
+        #Change data's name
+        title = self.data_title_tcl.GetValue().lstrip().rstrip()
+        
+        if data.title != title:
+            self._notes += "Change data 's "
+            self._notes += "title from %s to %s \n" % (data.title, str(title))
+            data.title = title
+        if event is not None:
+            event.Skip()
+            
+    def on_click_browse(self, event):
+        """
+        Open a file dialog to allow the user to select a given file.
+        Display the loaded data if available.
+        """
+        path = self.choose_data_file(location=self._default_save_location)
+        if path is None:
+            return 
+        if self.parent.parent is not None:
+            wx.PostEvent(self.parent.parent, StatusEvent(status="Loading...",
+                                        info="info", type="progress"))
+        
+        self.done = False
+        self._default_save_location = path
+        try:
+            #Load data
+            from load_thread import DataReader
+            ## If a thread is already started, stop it
+            if self.reader is not None and self.reader.isrunning():
+                self.reader.stop()
+            self.reader = DataReader(path=path,
+                                    completefn=self.complete_loading,
+                                    updatefn=None)
+            self.reader.queue()
+        except:
+            msg = "Data Editor: %s" % (sys.exc_value)
+            load_error(msg)
+            return 
+        event.Skip()
+         
+    def on_edit(self, event):
+        """
+        """
+        if self.detector_rb.GetValue():
+            self.edit_detector()
+        if self.sample_rb.GetValue():
+            self.edit_sample()
+        if self.source_rb.GetValue():
+            self.edit_source()
+        if self.collimation_rb.GetValue():
+            self.edit_collimation()
+        event.Skip()
+            
+    def on_click_apply(self, event):
+        """   
+        changes are saved in data object imported to edit
+        """
+        data, _, _ = self.get_current_data()
+        if data is None:
+            return
+        self.on_change_run(event=None)
+        self.on_change_title(event=None)
+        #must post event here
+        event.Skip()
+        
+    def on_click_save(self, event):
+        """
+        Save change into a file
+        """
+        if not self._data:
+            return
+        self.on_change_run(event=None)
+        self.on_change_title(event=None)
+        path = None
+        wildcard = "CanSAS 1D files(*.xml)|*.xml" 
+        dlg = wx.FileDialog(self, "Choose a file",
+                            self._default_save_location, "",wildcard , wx.SAVE)
+       
+        for data in self._data:
+            if issubclass(data.__class__, Data2D):
+                msg = "No conventional writing format for \n\n"
+                msg += "Data2D at this time.\n"
+                dlg = wx.MessageDialog(None, msg, 'Error Loading File',
+                                             wx.OK | wx.ICON_EXCLAMATION)
+                dlg.ShowModal()   
+            else:
+                if dlg.ShowModal() == wx.ID_OK:
+                    path = dlg.GetPath()
+                    mypath = os.path.basename(path)
+                    loader = Loader() 
+                    format = ".xml"
+                    if os.path.splitext(mypath)[1].lower() == format:
+                        loader.save( path, data, format)
+                    try:
+                        self._default_save_location = os.path.dirname(path)
+                    except:
+                        pass    
+                    dlg.Destroy()
+        event.Skip()
+        
+    def on_click_view(self, event):
+        """
+        Display data info 
+        """
+        data, data_name, position = self.get_current_data()
+        if data is None:
+            return
+        self.on_change_run(event=None)
+        self.on_change_title(event=None)
+        dlg = ConsoleDialog(data=data)
+        dlg.ShowModal()
+        event.Skip()
+    
+    def on_click_reset(self, event):
+        """
+        """
+        data, data_name, position = self.get_current_data()
+        if data is None:
+            return
+        self._data[position] = deepcopy(self._reset_data[position])
+        self.set_values()
+        event.Skip()
+        
+    def on_close(self, event):
+        """
+        leave data as it is and close
+        """
+        self.parent.Close()
+        event.Skip()
+        
+class DataEditorWindow(wx.Frame):
+    def __init__(self, parent, data=None, *args, **kwds):
+        kwds["size"] = (PANEL_WIDTH, PANEL_HEIGTH)
+        wx.Frame.__init__(self, parent, *args, **kwds)
+        self.parent = parent
+        self.panel = DataEditorPanel(parent=self, data=data)
+        self.Show()
+        
+    def get_data(self):
+        """
+            return the current data
+        """
+        return self.panel.get_data()
+    
+if __name__ == "__main__":
+   
+    app  = wx.App()
+    window = DataEditorWindow(parent=None, data=[], title="Data Editor")
+    app.MainLoop()
+ 
Index: calculatorview/src/sans/perspectives/calculator/detector_editor.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/detector_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/detector_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,860 @@
+
+import wx
+import sys
+from copy import deepcopy
+from DataLoader.data_info import Detector
+from sans.guiframe.utils import check_float
+
+_BOX_WIDTH = 60
+if sys.platform.count("win32") > 0:
+    _STATICBOX_WIDTH = 465
+    PANEL_WIDTH = 500
+    PANEL_HEIGHT = 450
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 480
+    PANEL_WIDTH = 550
+    PANEL_HEIGHT = 480
+    FONT_VARIANT = 1
+    
+class DetectorDialog(wx.Dialog):
+    def __init__(self, parent=None, manager=None, detector=None,
+                        title="Detector Editor",
+                        size=(PANEL_WIDTH, PANEL_HEIGHT)):
+        wx.Dialog.__init__(self, parent=parent, id=id, title=title, size=size)
+        try:
+            self.parent = parent
+            self.manager = manager 
+            self._detector = detector
+          
+            self._reset_detector = deepcopy(detector)
+            self._notes = ""
+            self._description = "Edit Detector"
+            self._do_layout()
+            self.set_values()
+        except:
+            print "error", sys.exc_value
+           
+    def _define_structure(self):
+        """
+            define initial sizer 
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.box_detector = wx.StaticBox(self, -1,str("Edit Selected Detector"))
+        self.boxsizer_detector = wx.StaticBoxSizer(self.box_detector,
+                                                    wx.VERTICAL)
+        detector_box = wx.StaticBox(self, -1, "Edit Number of Detectors")
+        self.detector_sizer = wx.StaticBoxSizer(detector_box, wx.VERTICAL)
+        self.detector_sizer.SetMinSize((_STATICBOX_WIDTH, -1))
+        self.detector_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.detector_hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        
+        self.detector_button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.detector_hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.instrument_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.distance_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.offset_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.orientation_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.beam_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.pixel_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.slit_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+       
+    def _layout_detector(self):
+        """
+            Do the layout for detector related widgets
+        """
+        detector_name_txt = wx.StaticText(self, -1, "Detector:") 
+        hint_detector_txt = 'Current available detector.'
+        detector_name_txt.SetToolTipString(hint_detector_txt) 
+        self.detector_cbox = wx.ComboBox(self, -1, style=wx.CB_READONLY)
+        hint_detector_name_txt = 'Name of detectors.'
+        self.detector_cbox.SetToolTipString(hint_detector_name_txt) 
+   
+        self.bt_add_detector = wx.Button(self, -1, "Add")
+        self.bt_add_detector.SetToolTipString("Add data's detector.")
+        self.bt_add_detector.Bind(wx.EVT_BUTTON, self.add_detector)
+        
+        self.bt_remove_detector = wx.Button(self, -1, "Remove")
+        self.bt_remove_detector.SetToolTipString("Remove data's detector.")
+        self.bt_remove_detector.Bind(wx.EVT_BUTTON, self.remove_detector)
+      
+        self.detector_button_sizer.AddMany([(detector_name_txt, 0, wx.LEFT, 15),
+                                     (self.detector_cbox, 0, wx.LEFT, 5),
+                                     (self.bt_add_detector, 0, wx.LEFT, 10),
+                                     (self.bt_remove_detector, 0, wx.LEFT, 5)])
+        detector_hint_txt = 'No detector is available for this data.'
+        self.detector_txt = wx.StaticText(self, -1, detector_hint_txt) 
+        self.detector_hint_sizer.Add(self.detector_txt, 0, wx.LEFT, 10)
+        self.detector_sizer.AddMany([(self.detector_button_sizer, 0,
+                                       wx.ALL, 10),
+                                     (self.detector_hint_sizer, 0, wx.ALL, 10)])
+     
+        self.fill_detector_combox()
+        self.enable_detector()
+        
+    def _layout_instrument_sizer(self):
+        """
+            Do the layout for instrument related widgets
+        """
+        #Instrument
+        instrument_name_txt = wx.StaticText(self, -1, 'Instrument Name : ')  
+        self.instrument_name_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH*5, 20), style=0) 
+        self.instrument_sizer.AddMany([(instrument_name_txt, 0, 
+                                        wx.LEFT|wx.RIGHT, 10),
+                                    (self.instrument_name_tcl, 0, wx.EXPAND)])
+    def _layout_distance(self):
+        """
+            Do the  layout for distance related widgets
+        """
+        distance_txt = wx.StaticText(self, -1, 'Sample to Detector Distance : ')  
+        self.distance_tcl = wx.TextCtrl(self, -1,
+                                         size=(_BOX_WIDTH, 20), style=0)
+        distance_unit_txt = wx.StaticText(self, -1, 'Unit: ')  
+        self.distance_unit_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH, 20), style=0)  
+        self.distance_sizer.AddMany([(distance_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.distance_tcl, 0, wx.RIGHT, 10),
+                                     (distance_unit_txt, 0, wx.EXPAND),
+                                     (self.distance_unit_tcl, 0, wx.RIGHT, 10)])
+        
+    def _layout_offset(self):
+        """
+            Do the  layout for offset related widgets
+        """
+        #Offset
+        offset_txt = wx.StaticText(self, -1, 'Offset:') 
+        x_offset_txt = wx.StaticText(self, -1, 'x = ')  
+        self.x_offset_tcl = wx.TextCtrl(self, -1, 
+                                        size=(_BOX_WIDTH, 20), style=0) 
+        y_offset_txt = wx.StaticText(self, -1, 'y = ')  
+        self.y_offset_tcl = wx.TextCtrl(self, -1,
+                                         size=(_BOX_WIDTH, 20), style=0) 
+        z_offset_txt = wx.StaticText(self, -1, 'z = ')  
+        self.z_offset_tcl = wx.TextCtrl(self, -1,
+                                         size=(_BOX_WIDTH, 20), style=0)  
+        offset_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.offset_unit_tcl = wx.TextCtrl(self, -1, 
+                                           size=(_BOX_WIDTH, 20), style=0)
+        self.offset_sizer.AddMany([(offset_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (x_offset_txt, 0, wx.LEFT, 30),
+                                     (self.x_offset_tcl, 0, wx.RIGHT, 10),
+                                     (y_offset_txt, 0, wx.EXPAND),
+                                     (self.y_offset_tcl, 0, wx.RIGHT, 10),
+                                     (z_offset_txt, 0, wx.EXPAND),
+                                     (self.z_offset_tcl, 0, wx.RIGHT, 10),
+                                     (offset_unit_txt, 0, wx.EXPAND),
+                                     (self.offset_unit_tcl, 0, wx.RIGHT, 10)])
+         
+    def _layout_orientation(self):
+        """
+            Do the  layout for orientation related widgets
+        """
+        #Orientation
+        orientation_txt = wx.StaticText(self, -1, 'Orientation:') 
+        x_orientation_txt = wx.StaticText(self, -1, 'x = ')  
+        self.x_orientation_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH, 20), style=0) 
+        y_orientation_txt = wx.StaticText(self, -1, 'y = ')  
+        self.y_orientation_tcl = wx.TextCtrl(self, -1, 
+                                             size=(_BOX_WIDTH, 20), style=0) 
+        z_orientation_txt = wx.StaticText(self, -1, 'z = ')  
+        self.z_orientation_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH, 20), style=0)  
+        orientation_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.orientation_unit_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH, 20), style=0)  
+        self.orientation_sizer.AddMany([(orientation_txt, 0,
+                                          wx.LEFT|wx.RIGHT, 10),
+                                     (x_orientation_txt, 0, wx.LEFT, 7),
+                                     (self.x_orientation_tcl, 0, wx.RIGHT, 10),
+                                     (y_orientation_txt, 0, wx.EXPAND),
+                                     (self.y_orientation_tcl, 0, wx.RIGHT, 10),
+                                     (z_orientation_txt, 0, wx.EXPAND),
+                                     (self.z_orientation_tcl, 0, wx.RIGHT, 10),
+                                     (orientation_unit_txt, 0, wx.EXPAND),
+                            (self.orientation_unit_tcl, 0, wx.RIGHT, 10)]) 
+        
+    def _layout_beam_center(self):
+        """
+            Do the  layout for beam center related widgets
+        """
+        #Beam center
+        beam_center_txt = wx.StaticText(self, -1, 'Beam Center:') 
+        x_beam_center_txt = wx.StaticText(self, -1, 'x = ')  
+        self.x_beam_center_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH, 20), style=0) 
+        y_beam_center_txt = wx.StaticText(self, -1, 'y = ')  
+        self.y_beam_center_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH, 20), style=0) 
+        z_beam_center_txt = wx.StaticText(self, -1, 'z = ')  
+        self.z_beam_center_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH, 20), style=0)  
+        beam_center_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.beam_center_unit_tcl = wx.TextCtrl(self, -1,
+                                                 size=(_BOX_WIDTH, 20), style=0)
+        self.beam_sizer.AddMany([(beam_center_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (x_beam_center_txt, 0, wx.EXPAND),
+                                     (self.x_beam_center_tcl, 0, wx.RIGHT, 10),
+                                     (y_beam_center_txt, 0, wx.EXPAND),
+                                     (self.y_beam_center_tcl, 0, wx.RIGHT, 10),
+                                     (z_beam_center_txt, 0, wx.EXPAND),
+                                     (self.z_beam_center_tcl, 0, wx.RIGHT, 10),
+                                     (beam_center_unit_txt, 0, wx.EXPAND),
+                                (self.beam_center_unit_tcl, 0,wx.RIGHT, 10)])   
+    
+    def _layout_pixel_size(self):
+        """
+            Do the  layout for pixel size related widgets
+        """
+        #Pixel Size
+        pixel_size_txt = wx.StaticText(self, -1, 'Pixel Size:') 
+        x_pixel_size_txt = wx.StaticText(self, -1, 'x = ')  
+        self.x_pixel_size_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH,20), style=0) 
+        y_pixel_size_txt = wx.StaticText(self, -1, 'y = ')  
+        self.y_pixel_size_tcl = wx.TextCtrl(self, -1, 
+                                            size=(_BOX_WIDTH,20), style=0) 
+        z_pixel_size_txt = wx.StaticText(self, -1, 'z = ')  
+        self.z_pixel_size_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH,20), style=0)  
+        pixel_size_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.pixel_size_unit_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH,20), style=0)  
+        self.pixel_sizer.AddMany([(pixel_size_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (x_pixel_size_txt, 0, wx.LEFT, 17),
+                                     (self.x_pixel_size_tcl, 0, wx.RIGHT, 10),
+                                     (y_pixel_size_txt, 0, wx.EXPAND),
+                                     (self.y_pixel_size_tcl, 0, wx.RIGHT, 10),
+                                     (z_pixel_size_txt, 0, wx.EXPAND),
+                                     (self.z_pixel_size_tcl, 0, wx.RIGHT, 10),
+                                     (pixel_size_unit_txt, 0, wx.EXPAND),
+                                (self.pixel_size_unit_tcl, 0, wx.RIGHT, 10)])
+    
+    def _layout_slit_length(self):
+        """
+            Do the  layout for slit length related widgets
+        """
+        #slit length
+        slit_length_txt = wx.StaticText(self, -1, 'Slit Length: ')  
+        self.slit_length_tcl = wx.TextCtrl(self, -1,
+                                            size=(_BOX_WIDTH,20), style=0)
+        slit_length_unit_txt = wx.StaticText(self, -1, 'Unit: ')  
+        self.slit_length_unit_tcl = wx.TextCtrl(self, -1,
+                                                 size=(_BOX_WIDTH,20), style=0)   
+        self.slit_sizer.AddMany([(slit_length_txt, 0, wx.LEFT, 10),
+                                     (self.slit_length_tcl, 0, wx.RIGHT, 10),
+                                     (slit_length_unit_txt, 0, wx.EXPAND),
+                            (self.slit_length_unit_tcl, 0,wx.RIGHT, 10)])
+        
+    def _layout_button(self):  
+        """
+            Do the layout for the button widgets
+        """ 
+        self.bt_apply = wx.Button(self, -1,'Apply')
+        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
+        self.bt_apply.SetToolTipString("Apply current changes to the detector.")
+        self.bt_cancel = wx.Button(self, -1,'Cancel')
+        self.bt_cancel.SetToolTipString("Cancel current changes.")
+        self.bt_cancel.Bind(wx.EVT_BUTTON, self.on_click_cancel)
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.SetToolTipString("Close window.")
+        self.button_sizer.AddMany([(self.bt_apply, 0, wx.LEFT, 200),
+                                   (self.bt_cancel, 0, wx.LEFT, 10),
+                                   (self.bt_close, 0, wx.LEFT, 10)])
+        
+    def _do_layout(self, data=None):
+        """
+             Draw the current panel
+        """
+        self._define_structure()
+        self._layout_detector()
+        self._layout_instrument_sizer()
+        self._layout_distance()
+        self._layout_offset()
+        self._layout_orientation()
+        self._layout_beam_center()
+        self._layout_pixel_size()
+        self._layout_slit_length()
+        self._layout_button()
+     
+        self.boxsizer_detector.AddMany([(self.instrument_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.distance_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.offset_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.orientation_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.beam_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.pixel_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.slit_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.main_sizer.AddMany([(self.detector_sizer, 0, wx.ALL, 10),
+                                 (self.boxsizer_detector, 0, wx.ALL, 10),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+        
+    def reset_detector(self):
+        """
+            put the default value of the detector back to the current detector
+        """
+        self._detector = deepcopy(self._reset_detector)
+        self.detector_cbox.Clear()
+        self.fill_detector_combox()
+        self.set_values()
+        
+    def set_manager(self, manager):
+        """    
+            Set manager of this window
+        """
+        self.manager = manager
+        
+    def fill_detector_combox(self):
+        """
+            fill the current combobox with the available detector
+        """
+        for detector in self._detector:
+            pos = self.detector_cbox.Append(str(detector.name))
+            self.detector_cbox.SetClientData(pos, detector)
+            self.detector_cbox.SetSelection(pos)
+            self.detector_cbox.SetStringSelection(str(detector.name)) 
+            
+    def reset_detector_combobox(self, edited_detector):
+        """
+            take all edited editor and reset clientdata of detector combo box
+        """
+        for position in range(self.detector_cbox.GetCount()):
+            detector = self.detector_cbox.GetClientData(position)
+            if detector == edited_detector:
+                detector = edited_detector
+                self.detector_cbox.SetString(position, str(detector.name)) 
+                self.detector_cbox.SetClientData(position, detector)
+                self.detector_cbox.SetStringSelection(str(detector.name)) 
+         
+    def add_detector(self, event):
+        """
+            Append empty detector to data's list of detector
+        """
+        
+        if not self.detector_cbox.IsEnabled():
+            self.detector_cbox.Enable()
+        detector = Detector()
+        self._detector.append(detector)
+        position = self.detector_cbox.Append(str(detector.name))
+        self.detector_cbox.SetClientData(position, detector)
+        self.detector_cbox.SetSelection(position) 
+        self.enable_detector() 
+        self.set_values()
+        
+    def remove_detector(self, event):
+        """
+            Remove detector to data's list of detector
+        """
+        if self.detector_cbox.IsEnabled():
+            if self.detector_cbox.GetCount() > 1:
+                position = self.detector_cbox.GetCurrentSelection()
+                detector = self.detector_cbox.GetClientData(position)
+                if detector in self._detector:
+                    self._detector.remove(detector)
+                    self.detector_cbox.Delete(position) 
+                    #set the combo box box the next available item
+                    position = self.detector_cbox.GetCount()
+                    if position > 0:
+                        position -= 1 
+                    self.detector_cbox.SetSelection(position)
+                    self.set_values()
+        #disable or enable the combo box when necessary
+        self.enable_detector()
+        
+    def enable_detector(self):
+        """
+            Enable /disable widgets crelated to detector
+        """
+        if self._detector is not None and self.detector_cbox.GetCount() > 0:
+            self.detector_cbox.Enable()
+            self.bt_remove_detector.Enable()
+            n_detector = self.detector_cbox.GetCount()
+            detector_hint_txt = 'Detectors available: %s '%str(n_detector)
+            if len(self._detector) > 1:
+                self.bt_remove_detector.Enable()
+            else:
+                self.bt_remove_detector.Disable()
+        else:
+            self.detector_cbox.Disable()
+            self.bt_remove_detector.Disable()
+            detector_hint_txt = 'No detector is available for this data.'
+        self.detector_txt.SetLabel(detector_hint_txt)
+           
+    def set_detector(self, detector):
+        """
+            set detector for data
+        """
+        if self._detector is None:
+            return
+        if self._detector:
+            for item in self._detector:
+                if item == detector:
+                    item = detector
+                    self.reset_detector_combobox(edited_detector=detector)
+                    return
+                
+    def get_current_detector(self):
+        """
+        """
+        if not self.detector_cbox.IsEnabled():
+            return None, None, None
+        position = self.detector_cbox.GetSelection() 
+        if position == wx.NOT_FOUND:
+            return None, None, None
+        detector_name = self.detector_cbox.GetStringSelection() 
+        detector = self.detector_cbox.GetClientData(position)
+        return detector, detector_name, position
+    
+    def set_values(self):
+        """
+            take the detector values of the current data and display them
+            through the panel
+        """
+        detector, _, _ = self.get_current_detector()
+        if detector is None:
+            return
+        self.instrument_name_tcl.SetValue(str(detector.name))
+        #Distance
+        distance = detector.distance
+        self.distance_tcl.SetValue(str(distance))
+        self.distance_unit_tcl.SetValue(str(detector.distance_unit))
+        #Offset
+        x, y, z = detector.offset.x, detector.offset.y , detector.offset.z
+        self.x_offset_tcl.SetValue(str(x))  
+        self.y_offset_tcl.SetValue(str(y)) 
+        self.z_offset_tcl.SetValue(str(z))  
+        self.offset_unit_tcl.SetValue(str(detector.offset_unit))
+        #Orientation
+        x, y = detector.orientation.x, detector.orientation.y
+        z = detector.orientation.z
+        self.x_orientation_tcl.SetValue(str(x))  
+        self.y_orientation_tcl.SetValue(str(y)) 
+        self.z_orientation_tcl.SetValue(str(z))  
+        self.orientation_unit_tcl.SetValue(str(detector.orientation_unit))
+        #Beam center
+        x, y = detector.beam_center.x, detector.beam_center.y
+        z  =   detector.beam_center.z
+        self.x_beam_center_tcl.SetValue(str(x))  
+        self.y_beam_center_tcl.SetValue(str(y)) 
+        self.z_beam_center_tcl.SetValue(str(z))  
+        self.beam_center_unit_tcl.SetValue(str(detector.beam_center_unit))
+        #Pixel size 
+        x, y = detector.pixel_size.x, detector.pixel_size.y
+        z = detector.pixel_size.z
+        self.x_pixel_size_tcl.SetValue(str(x))  
+        self.y_pixel_size_tcl.SetValue(str(y)) 
+        self.z_pixel_size_tcl.SetValue(str(z))  
+        self.pixel_size_unit_tcl.SetValue(str(detector.pixel_size_unit))
+        #Slit length
+        slit_length = detector.slit_length
+        self.slit_length_tcl.SetValue(str(detector.slit_length))
+        self.slit_length_unit_tcl.SetValue(str(detector.slit_length_unit))
+        
+    def get_detector(self):
+        """
+            return the current detector
+        """
+        return self._detector
+    
+    def get_notes(self):
+        """
+            return notes
+        """
+        return self._notes
+    
+    def on_change_instrument(self):
+        """
+            Change instrument
+        """
+        detector, detector_name, position = self.get_current_detector()
+        if detector is None: 
+            return
+        #Change the name of the detector
+        name = self.instrument_name_tcl.GetValue().lstrip().rstrip()
+        if name == "" or name == str(None):
+            name = None
+        if detector_name != name:
+            self._notes += " Instrument's "
+            self._notes += "name from %s to %s \n"%(detector_name, name)
+            detector.name = name
+            self.detector_cbox.SetString(position, str(detector.name)) 
+            self.detector_cbox.SetClientData(position, detector)
+            self.detector_cbox.SetStringSelection(str(detector.name)) 
+        
+    def on_change_distance(self):
+        """
+            Change distance of the sample to the detector
+        """
+        detector, _, position = self.get_current_detector()
+        if detector is None:
+            return
+        #Change the distance
+        distance = self.distance_tcl.GetValue().lstrip().rstrip()
+        if distance == "" or distance  == str(None):
+            distance = None
+            detector.distance = distance
+        else:
+            if check_float(self.distance_tcl):
+                if detector.distance != float(distance):
+                    self._notes += " Change Distance from"
+                    self._notes += " %s to %s \n"%(detector.distance, distance)
+                    detector.distance = float(distance)
+            else:
+                self._notes += "Error: Expected a float for "
+                self._notes += " the distance won't changes "
+                self._notes += "%s to %s"%(detector.distance, distance)
+        #change the distance unit
+        unit = self.distance_unit_tcl.GetValue().lstrip().rstrip()
+        if detector.distance_unit != unit:
+            self._notes += " Change distance's unit from "
+            self._notes += "%s to %s"%(detector.distance_unit, unit)
+            
+        self.detector_cbox.SetString(position, str(detector.name)) 
+        self.detector_cbox.SetClientData(position, detector)
+        self.detector_cbox.SetStringSelection(str(detector.name)) 
+        
+    def on_change_offset(self):
+        """
+            Change the detector offset
+        """
+        detector, _, position = self.get_current_detector()
+        if detector is None:
+            return
+        #Change x coordinate
+        x_offset = self.x_offset_tcl.GetValue().lstrip().rstrip()
+        if x_offset == "" or x_offset == str(None):
+            x_offset = None
+            detector.offset.x = x_offset
+        else:
+            if check_float(self.x_offset_tcl):
+                if detector.offset.x != float(x_offset):
+                    self._notes += "Change x of offset from"
+                    self._notes += " %s to %s \n" % (detector.offset.x,
+                                                      x_offset)
+                    detector.offset.x = float(x_offset)
+            else:
+                self._notes += "Error: Expected a float for the offset 's x "
+                self._notes += "won't changes x offset"
+                self._notes += " from %s to %s" % (detector.offset.x, x_offset)
+        #Change y coordinate
+        y_offset = self.y_offset_tcl.GetValue().lstrip().rstrip()
+        if y_offset == "" or y_offset == str(None):
+            y_offset = None
+            detector.offset.y = y_offset
+        else:
+            if check_float(self.y_offset_tcl):
+                if detector.offset.y != float(y_offset):
+                    self._notes += "Change y of offset from "
+                    self._notes += "%s to %s \n"%(detector.offset.y, y_offset)
+                    detector.offset.y = float(y_offset)
+            else:
+                self._notes += "Error: Expected a float for the offset 's y "
+                self._notes += "won't changes y "
+                self._notes += "offset from %s to %s"%(detector.offset.y,
+                                                         y_offset)
+        #Change z coordinate
+        z_offset = self.z_offset_tcl.GetValue().lstrip().rstrip()
+        if z_offset == "" or z_offset == str(None):
+            z_offset = None
+            detector.offset.z = z_offset
+        else:
+            if check_float(self.z_offset_tcl):
+                if detector.offset.z != float(z_offset):
+                    self._notes += "Change z of offset from"
+                    self._notes += " %s to %s \n" % (detector.offset.z,
+                                                              z_offset)
+                    detector.offset.z  = float(z_offset)
+            else:
+                self._notes += "Error: Expected a float for the offset 's x "
+                self._notes += "won't changes z"
+                self._notes += "offset from %s to %s" % (detector.offset.z, 
+                                                       z_offset)
+        #change the offset unit
+        unit = self.offset_unit_tcl.GetValue().lstrip().rstrip()
+        if detector.offset_unit != unit:
+            self._notes += " Change Offset's"
+            self._notes += "unit from %s to %s" % (detector.offset_unit, unit)
+            
+        self.detector_cbox.SetString(position, str(detector.name)) 
+        self.detector_cbox.SetClientData(position, detector)
+        self.detector_cbox.SetStringSelection(str(detector.name)) 
+        
+    def on_change_orientation(self):
+        """
+            Change the detector orientation
+        """
+        detector, _, position = self.get_current_detector()
+        if detector is None:
+            return
+        #Change x coordinate
+        x_orientation = self.x_orientation_tcl.GetValue().lstrip().rstrip()
+        if x_orientation == "" or x_orientation == str(None):
+            x_orientation = None
+            detector.orientation.x = x_orientation
+        else:
+            if check_float(self.x_orientation_tcl):
+                if detector.orientation.x != float(x_orientation):
+                    self._notes += "Change x of orientation from "
+                    self._notes += "%s to %s \n" % (detector.orientation.x,
+                                                   x_orientation)
+                    detector.orientation.x  = float(x_orientation)
+            else:
+                self._notes += "Error: Expected a float for the orientation "
+                self._notes += "'s x  won't changes x orientation from "
+                self._notes += "%s to %s" % (detector.orientation.x,
+                                              x_orientation)
+        #Change y coordinate
+        y_orientation = self.y_orientation_tcl.GetValue().lstrip().rstrip()
+        if y_orientation == "" or y_orientation == str(None):
+            y_orientation = None
+            detector.orientation.y = y_orientation
+        else:
+            if check_float(self.y_orientation_tcl):
+                if detector.orientation.y != float(y_orientation):
+                    self._notes += "Change y of orientation from "
+                    self._notes += "%s to %s \n" % (detector.orientation.y,
+                                                     y_orientation)
+                    detector.orientation.y  = float(y_orientation)
+            else:
+                self._notes += "Error: Expected a float for the orientation's "
+                self._notes += " y won't changes y orientation from "
+                self._notes += "%s to %s" % (detector.orientation.y,
+                                            y_orientation)
+        #Change z coordinate
+        z_orientation = self.z_orientation_tcl.GetValue().lstrip().rstrip()
+        if z_orientation == "" or z_orientation  == str(None):
+            z_orientation = None
+            detector.orientation.z = z_orientation
+        else:
+            if check_float(self.z_orientation_tcl):
+                if detector.orientation.z != float(z_orientation):
+                    self._notes += "Change z of offset from "
+                    self._notes += "%s to %s \n"%(detector.orientation.z,
+                                                   z_orientation)
+                    detector.orientation.z  = float(z_orientation)
+            else:
+                self._notes += "Error: Expected a float for the orientation 's"
+                self._notes += " x won't changes z orientation from "
+                self._notes += "%s to %s" % (detector.orientation.z,
+                                              z_orientation)
+        #change the orientation unit
+        unit = self.orientation_unit_tcl.GetValue().lstrip().rstrip()
+        if detector.orientation_unit != unit:
+            self._notes += " Change orientation's unit from "
+            self._notes += "%s to %s"%(detector.orientation_unit, unit)
+            
+        self.detector_cbox.SetString(position, str(detector.name)) 
+        self.detector_cbox.SetClientData(position, detector)
+        self.detector_cbox.SetStringSelection(str(detector.name)) 
+        
+    def on_change_beam_center(self):
+        """
+            Change the detector beam center
+        """
+       
+        detector, _, position = self.get_current_detector()
+        if detector is None:
+            return
+        #Change x coordinate
+        x_beam_center = self.x_beam_center_tcl.GetValue().lstrip().rstrip()
+        if x_beam_center == "" or x_beam_center == str(None):
+            x_beam_center = None
+            detector.beam_center.x = x_beam_center
+        else:
+            if check_float(self.x_beam_center_tcl):
+                if detector.beam_center.x != float(x_beam_center):
+                    self._notes += "Change x of offset from "
+                    self._notes += "%s to %s \n" % (detector.beam_center.x,
+                                                     x_beam_center)
+                    detector.beam_center.x  = float(x_beam_center)
+            else:
+                self._notes += "Error: Expected a float for the beam "
+                self._notes += "center 's x won't changes x beam center from "
+                self._notes += "%s to %s" % (detector.beam_center.x,
+                                            x_beam_center)
+        #Change y coordinate
+        y_beam_center = self.y_beam_center_tcl.GetValue().lstrip().rstrip()
+        if y_beam_center == "" or y_beam_center == str(None):
+            y_beam_center = None
+            detector.beam_center.y  = y_beam_center
+        else:
+            if check_float(self.y_beam_center_tcl):
+                if detector.beam_center.y != float(y_beam_center):
+                    self._notes += "Change y of beam center from "
+                    self._notes += "%s to %s \n" % (detector.beam_center.y,
+                                                     y_beam_center)
+                    detector.beam_center.y  = float(y_beam_center)
+            else:
+                self._notes += "Error: Expected a float for the beam "
+                self._notes += "center 's y won't changes y beam center from "
+                self._notes += "%s to %s" % (detector.beam_center.y,
+                                              y_beam_center)
+        #Change z coordinate
+        z_beam_center = self.z_beam_center_tcl.GetValue().lstrip().rstrip()
+        if z_beam_center == "" or z_beam_center == str(None):
+            z_beam_center = None
+            detector.beam_center.z = z_beam_center
+        else:
+            if check_float(self.z_beam_center_tcl):
+                if detector.beam_center.z != float(z_beam_center):
+                    self._notes += "Change z of beam center from "
+                    self._notes += "%s to %s \n" % (detector.beam_center.z,
+                                                     z_beam_center)
+                    detector.beam_center.z  = float(z_beam_center)
+            else:
+                self._notes += "Error: Expected a float for the offset 's x "
+                self._notes += "won't changes z beam center from "
+                self._notes += "%s to %s"%(detector.beam_center.z,
+                                            z_beam_center)
+        #change the beam center unit
+        unit = self.beam_center_unit_tcl.GetValue().lstrip().rstrip()
+        if detector.beam_center_unit != unit:
+            self._notes += " Change beam center's unit from "
+            self._notes += "%s to %s"%(detector.beam_center_unit, unit)
+        
+        self.detector_cbox.SetString(position, str(detector.name)) 
+        self.detector_cbox.SetClientData(position, detector)
+        self.detector_cbox.SetStringSelection(str(detector.name)) 
+        
+    def on_change_pixel_size(self):
+        """
+            Change the detector pixel size
+        """
+        detector, _, position = self.get_current_detector()
+        if detector is None:
+            return
+        #Change x coordinate
+        x_pixel_size = self.x_pixel_size_tcl.GetValue().lstrip().rstrip()
+        if x_pixel_size == "" or x_pixel_size == str(None):
+            x_pixel_size = None
+        else:
+            if check_float(self.x_pixel_size_tcl):
+                if detector.pixel_size.x != float(x_pixel_size) :
+                    self._notes += "Change x of pixel size from "
+                    self._notes += "%s to %s \n"%(detector.pixel_size.x,
+                                                   x_pixel_size)
+                    detector.pixel_size.x  = float(x_pixel_size)
+            else:
+                self._notes += "Error: Expected a float for the pixel"
+                self._notes += " size 's x  won't changes x pixel size from "
+                self._notes += "%s to %s" % (detector.pixel_size.x, 
+                                             x_pixel_size)
+        #Change y coordinate
+        y_pixel_size = self.y_pixel_size_tcl.GetValue().lstrip().rstrip()
+        if y_pixel_size == "" or y_pixel_size == str(None):
+            y_pixel_size = None
+            detector.pixel_size.y = y_pixel_size
+        else:
+            if check_float(self.y_pixel_size_tcl):
+                if detector.pixel_size.y != float(y_pixel_size):
+                    self._notes += "Change y of pixel size from "
+                    self._notes += "%s to %s \n"%(detector.pixel_size.y,
+                                                   y_pixel_size)
+                    detector.pixel_size.y  = float(y_pixel_size)
+            else:
+                self._notes += "Error: Expected a float for the pixel "
+                self._notes += "size's y  won't changes y pixel size from "
+                self._notes += "%s to %s" % (detector.pixel_size.y,
+                                              y_pixel_size)
+        #Change z coordinate
+        z_pixel_size = self.z_pixel_size_tcl.GetValue().lstrip().rstrip()
+        if z_pixel_size == "" or z_pixel_size == str(None):
+            z_pixel_size = None
+            detector.pixel_size.z = z_pixel_size
+        else:
+            if check_float(self.z_pixel_size_tcl):
+                if detector.pixel_size.z != float(z_pixel_size):
+                    self._notes += "Change z of pixel size from "
+                    self._notes += "%s to %s \n"%(detector.pixel_size.z,
+                                                   z_pixel_size)
+                    detector.pixel_size.z  = float(z_pixel_size)
+            else:
+                self._notes += "Error: Expected a float for the offset 's x "
+                self._notes += "won't changes z pixel size from "
+                self._notes += "%s to %s"%(detector.pixel_size.z, z_pixel_size)
+        #change the beam center unit
+        unit = self.pixel_size_unit_tcl.GetValue().lstrip().rstrip()
+        if detector.pixel_size_unit != unit:
+            self._notes += " Change pixel size's unit from "
+            self._notes += "%s to %s"%(detector.pixel_size_unit, unit)
+            
+        self.detector_cbox.SetString(position, str(detector.name)) 
+        self.detector_cbox.SetClientData(position, detector)
+        self.detector_cbox.SetStringSelection(str(detector.name)) 
+           
+    def on_change_slit_length(self):
+        """
+            Change slit length of the detector
+        """
+        detector, _, position = self.get_current_detector()
+        if detector is None:
+            return
+        #Change the distance
+        slit_length = self.slit_length_tcl.GetValue().lstrip().rstrip()
+        if slit_length == "" or slit_length == str(None):
+            slit_length = None
+            detector.slit_length = slit_length
+        else:
+            if check_float(self.slit_length_tcl):
+                if detector.slit_length != float(slit_length):
+                    self._notes += " Change slit length from"
+                    self._notes += " %s to %s \n"%(detector.slit_length,
+                                                    slit_length)
+                    detector.slit_length = float(slit_length)
+            else:
+                self._notes += "Error: Expected a float"
+                self._notes += " for the slit length won't changes "
+                self._notes += "%s to %s" % (detector.slit_length, slit_length)
+        #change the distance unit
+        unit = self.slit_length_unit_tcl.GetValue().lstrip().rstrip()
+        if detector.slit_length_unit != unit:
+            self._notes += " Change slit length's unit from "
+            self._notes += "%s to %s"%(detector.slit_length_unit_tcl, unit) 
+            
+        self.detector_cbox.SetString(position, str(detector.name)) 
+        self.detector_cbox.SetClientData(position, detector)
+        self.detector_cbox.SetStringSelection(str(detector.name)) 
+            
+    def on_click_cancel(self, event):
+        """
+            reset the current detector to its initial values
+        """
+        self.reset_detector()
+        self.set_values()
+        if self.manager is not None:
+             self.manager.set_detector(self._detector)
+             
+    def on_click_apply(self, event):
+        """
+            Apply user values to the detector
+        """
+        self.on_change_instrument()
+        self.on_change_distance()
+        self.on_change_instrument()
+        self.on_change_beam_center()
+        self.on_change_offset()
+        self.on_change_orientation()
+        self.on_change_pixel_size()
+        self.on_change_slit_length()
+        for detector in self._detector:
+            self.manager.set_detector(self._detector, self._notes)
+            
+if __name__ == "__main__":
+    app = wx.App()
+    test_detector = Detector()
+    dlg = DetectorDialog(detector=[test_detector])
+    dlg.ShowModal()
+    app.MainLoop()
+ 
Index: calculatorview/src/sans/perspectives/calculator/help_panel.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/help_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/help_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+"""
+Help panel for calculator
+"""
+import os
+import wx
+import wx.html as html
+from wx.lib.splitter import MultiSplitterWindow
+import sans.perspectives.calculator as calculator
+
+
+class HelpWindow(wx.Frame):
+    """
+    """
+    def __init__(self, parent, title='HelpWindow', pageToOpen=None):
+        wx.Frame.__init__(self, parent, title, size=(700, 450))
+        """
+             contains help info
+        """
+        splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE)
+        rpanel = wx.Panel(splitter, -1)
+        lpanel = wx.Panel(splitter, -1, style=wx.BORDER_SUNKEN)
+        
+        vbox = wx.BoxSizer(wx.VERTICAL)
+        header = wx.Panel(rpanel, -1)
+        header.SetBackgroundColour('#6666FF')
+        header.SetForegroundColour('WHITE')
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        st = wx.StaticText(header, -1, 'Contents', (5, 5))
+        font = st.GetFont()
+        font.SetPointSize(10)
+        st.SetFont(font)
+        hbox.Add(st, 1, wx.TOP | wx.BOTTOM | wx.LEFT, 5)
+        header.SetSizer(hbox)
+        vbox.Add(header, 0, wx.EXPAND)
+       
+        vboxl = wx.BoxSizer(wx.VERTICAL)
+        headerl = wx.Panel(lpanel, -1, size=(-1, 20))
+       
+        headerl.SetBackgroundColour('#6666FF')
+        headerl.SetForegroundColour('WHITE')
+        hboxl = wx.BoxSizer(wx.HORIZONTAL)
+        lst = wx.StaticText(headerl, -1, 'Menu', (5, 5))
+        fontl = lst.GetFont()
+        fontl.SetPointSize(10)
+        lst.SetFont(fontl)
+        hboxl.Add(lst, 1, wx.TOP | wx.BOTTOM | wx.LEFT, 5)
+        headerl.SetSizer(hboxl)
+        vboxl.Add(headerl, 0, wx.EXPAND)
+        self.lhelp = html.HtmlWindow(lpanel, -1, style=wx.NO_BORDER)
+        self.rhelp = html.HtmlWindow(rpanel, -1, style=wx.NO_BORDER, 
+                                     size=(500,-1))
+        
+        self.path = calculator.get_data_path(media='media')
+       
+        page1 = """<html>
+            <body>
+             <p>Select topic on Menu</p>
+            </body>
+            </html>"""
+        self.rhelp.SetPage(page1)
+        page = """<html>
+            <body>
+            <ul>
+            <li><a href ="sld_calculator_help.html" 
+            target ="showframe">SLD Calculator</a><br></li>
+            <li><a href ="slit_calculator_help.html" 
+            target ="showframe">Slit Size Calculator</a><br></li>
+            <li><a href ="kiessig_calculator_help.html" 
+            target ="showframe">Kiessig Thickness Calculator</a><br></li>
+            <li><a href ="resolution_calculator_help.html" 
+            target ="showframe">Resolution Estimator</a><br></li>
+            </ul>
+            </body>
+            </html>"""
+
+        self.lhelp.SetPage(page)
+        self.lhelp.Bind(wx.html.EVT_HTML_LINK_CLICKED, self.OnLinkClicked)
+        
+        vbox.Add(self.rhelp, 1, wx.EXPAND)
+        vboxl.Add(self.lhelp, 1, wx.EXPAND)
+        rpanel.SetSizer(vbox)
+        lpanel.SetSizer(vboxl)
+        lpanel.SetFocus()
+        
+        vbox1 = wx.BoxSizer(wx.HORIZONTAL)
+        vbox1.Add(splitter, 1, wx.EXPAND)
+        splitter.AppendWindow(lpanel, 200)
+        splitter.AppendWindow(rpanel)
+        self.SetSizer(vbox1)
+       
+        self.Centre()
+        self.Show(True)
+        
+    def OnLinkClicked(self, event):
+        """
+            Function to diplay html page related to the hyperlinktext selected
+        """
+        link = event.GetLinkInfo().GetHref()
+        link = os.path.join(self.path, link)
+        self.rhelp.LoadPage(link)
+        
+        
+class ViewApp(wx.App):
+    def OnInit(self):
+        frame = HelpWindow(None, -1, 'HelpWindow')    
+        frame.Show(True)
+        self.SetTopWindow(frame)
+        return True
+        
+if __name__ == "__main__": 
+    app = ViewApp(0)
+    app.MainLoop()     
Index: calculatorview/src/sans/perspectives/calculator/kiessig_calculator_panel.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/kiessig_calculator_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/kiessig_calculator_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,207 @@
+"""
+   This software was developed by the University of Tennessee as part of the
+Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+project funded by the US National Science Foundation. 
+
+See the license text in license.txt
+
+copyright 2008, 2009, University of Tennessee
+"""
+
+import wx
+import sys
+
+from sans.guiframe.panel_base import PanelBase
+from sans.calculator.kiessig_calculator import KiessigThicknessCalculator 
+from calculator_widgets import OutputTextCtrl
+from calculator_widgets import InputTextCtrl
+
+_BOX_WIDTH = 77
+#Slit length panel size 
+if sys.platform.count("win32") > 0:
+    PANEL_WIDTH = 500
+    PANEL_HEIGHT = 210
+    FONT_VARIANT = 0
+else:
+    PANEL_WIDTH = 560
+    PANEL_HEIGHT = 230
+    FONT_VARIANT = 1
+ 
+class KiessigThicknessCalculatorPanel(wx.Panel, PanelBase):
+    """
+    Provides the Kiessig thickness calculator GUI.
+    """
+    ## Internal nickname for the window, used by the AUI manager
+    window_name = "Kiessig Thickness Calculator"
+    ## Name to appear on the window title bar
+    window_caption = "Kiessig Thickness Calculator"
+    ## Flag to tell the AUI manager to put this panel in the center pane
+    CENTER_PANE = True
+    
+    def __init__(self, parent, *args, **kwds):
+        wx.Panel.__init__(self, parent, *args, **kwds)
+        PanelBase.__init__(self)
+        #Font size 
+        self.SetWindowVariant(variant=FONT_VARIANT)  
+        # Object that receive status event
+        self.parent = parent
+        self.kiessig = KiessigThicknessCalculator()
+        #layout attribute
+        self.hint_sizer = None
+        self._do_layout()
+       
+    def _define_structure(self):
+        """
+        Define the main sizers building to build this application.
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.box_source = wx.StaticBox(self, -1,
+                                str("Kiessig Thickness Calculator"))
+        self.boxsizer_source = wx.StaticBoxSizer(self.box_source,
+                                                    wx.VERTICAL)
+        self.dq_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.thickness_size_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+       
+    def _layout_dq_name(self):
+        """
+        Fill the sizer containing dq name
+        """
+        # get the default dq
+        dq_value = str(self.kiessig.get_deltaq())
+        dq_unit_txt = wx.StaticText(self, -1, '[1/A]')
+        dq_name_txt = wx.StaticText(self, -1, 
+                                'Kiessig Fringe Width (Delta Q): ')
+        self.dq_name_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        dq_hint = "Type the Kiessig Fringe Width (Delta Q)"
+        self.dq_name_tcl.SetValue(dq_value)
+        self.dq_name_tcl.SetToolTipString(dq_hint)
+        #control that triggers importing data
+        id = wx.NewId()
+        self.compute_button = wx.Button(self, id, "Compute")
+        hint_on_compute = "Compute the diameter/thickness in the real space."
+        self.compute_button.SetToolTipString(hint_on_compute)
+        self.Bind(wx.EVT_BUTTON, self.on_compute, id=id)
+        self.dq_name_sizer.AddMany([(dq_name_txt, 0, wx.LEFT, 15),
+                                    (self.dq_name_tcl, 0, wx.LEFT, 15),
+                                    (dq_unit_txt,0, wx.LEFT, 10),
+                                (self.compute_button, 0, wx.LEFT, 30)])
+    def _layout_thickness_size(self):
+        """
+        Fill the sizer containing thickness information
+        """
+        thick_unit = '['+self.kiessig.get_thickness_unit() +']'
+        thickness_size_txt = wx.StaticText(self, -1, 
+                                           'Thickness (or Diameter): ')
+        self.thickness_size_tcl = OutputTextCtrl(self, -1, 
+                                                 size=(_BOX_WIDTH,-1))
+        thickness_size_hint = " Estimated Size in Real Space"
+        self.thickness_size_tcl.SetToolTipString(thickness_size_hint)
+        thickness_size_unit_txt = wx.StaticText(self, -1, thick_unit)
+        
+        self.thickness_size_sizer.AddMany([(thickness_size_txt, 0, wx.LEFT, 15),
+                                    (self.thickness_size_tcl, 0, wx.LEFT, 15),
+                                    (thickness_size_unit_txt, 0, wx.LEFT, 10)])
+    
+    def _layout_hint(self):
+        """
+        Fill the sizer containing hint 
+        """
+        hint_msg = "This tool is to approximately estimate "
+        hint_msg += "the thickness of a layer"
+        hint_msg += " or the diameter of particles\n "
+        hint_msg += "from the Kiessig fringe width in SANS/NR data."
+        hint_msg += ""
+        self.hint_txt = wx.StaticText(self, -1, hint_msg)
+        self.hint_sizer.AddMany([(self.hint_txt, 0, wx.LEFT, 15)])
+    
+    def _layout_button(self):  
+        """
+        Do the layout for the button widgets
+        """ 
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.Bind(wx.EVT_BUTTON, self.on_close)
+        self.bt_close.SetToolTipString("Close this window.")
+        self.button_sizer.AddMany([(self.bt_close, 0, wx.LEFT, 390)])
+        
+    def _do_layout(self):
+        """
+            Draw window content
+        """
+        self._define_structure()
+        self._layout_dq_name()
+        self._layout_thickness_size()
+        self._layout_hint()
+        self._layout_button()
+        self.boxsizer_source.AddMany([(self.dq_name_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.thickness_size_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                     (self.hint_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.main_sizer.AddMany([(self.boxsizer_source, 0, wx.ALL, 10),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+
+    def on_close(self, event):
+        """
+        close the window containing this panel
+        """
+        self.parent.Close()
+        if event is not None:
+            event.Skip()
+        
+    def on_compute(self, event):
+        """
+        Execute the computation of thickness
+        """
+        # skip for another event
+        if event != None:
+            event.Skip()
+        dq = self.dq_name_tcl.GetValue()
+        self.kiessig.set_deltaq(dq)
+        # calculate the thickness 
+        output = self.kiessig.compute_thickness()
+        thickness = self.format_number(output)
+        # set tcl
+        self.thickness_size_tcl.SetValue(str(thickness))
+        
+    def format_number(self, value=None):
+        """
+        Return a float in a standardized, human-readable formatted string 
+        """
+        try: 
+            value = float(value)
+        except:
+            output = None
+            return output
+
+        output = "%-7.4g" % value
+        return output.lstrip().rstrip()   
+    
+    def _onparamEnter(self, event = None):
+        """
+        On Text_enter_callback, perform compute
+        """
+        self.on_compute(event)
+             
+class KiessigWindow(wx.Frame):
+    def __init__(self, parent=None, title="Kiessig Thickness Calculator",
+                  size=(PANEL_WIDTH,PANEL_HEIGHT), *args, **kwds):
+        kwds['title'] = title
+        kwds['size'] = size
+        wx.Frame.__init__(self, parent, *args, **kwds)
+        self.parent = parent
+        self.panel = KiessigThicknessCalculatorPanel(parent=self)
+        self.Centre()
+        self.Show(True)
+        
+if __name__ == "__main__": 
+    app = wx.PySimpleApp()
+    frame = KiessigWindow()    
+    frame.Show(True)
+    app.MainLoop()     
Index: calculatorview/src/sans/perspectives/calculator/load_thread.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/load_thread.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/load_thread.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,51 @@
+
+import time
+import sys
+
+
+from data_util.calcthread import CalcThread
+from DataLoader.loader import Loader
+        
+
+class DataReader(CalcThread):
+    """
+            Load a data given a filename
+    """
+    def __init__(self, path, completefn=None,
+                 updatefn   = None,
+                 yieldtime  = 0.01,
+                 worktime   = 0.01
+                 ):
+        CalcThread.__init__(self, completefn,
+                 updatefn,
+                 yieldtime,
+                 worktime)
+        self.path = path
+        #Instantiate a loader 
+        self.loader = Loader()
+        self.starttime = 0  
+        
+    def isquit(self):
+        """
+             @raise KeyboardInterrupt: when the thread is interrupted
+        """
+        try:
+            CalcThread.isquit(self)
+        except KeyboardInterrupt:
+            raise KeyboardInterrupt   
+        
+        
+    def compute(self):
+        """
+            read some data
+        """
+        self.starttime = time.time()
+        try:
+            data =  self.loader.load(self.path)
+            elapsed = time.time() - self.starttime
+            self.complete(data=data)
+        except KeyboardInterrupt:
+            # Thread was interrupted, just proceed and re-raise.
+            # Real code should not print, but this is an example...
+            raise
+      
Index: calculatorview/src/sans/perspectives/calculator/resolcal_thread.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/resolcal_thread.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/resolcal_thread.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,60 @@
+"""
+Thread for Resolution computation
+""" 
+import time
+from data_util.calcthread import CalcThread
+import sys
+
+class CalcRes(CalcThread):
+    """
+    Compute Resolution
+    """
+    def __init__(self,
+                 id=-1,
+                 func = None,
+                 qx = None,
+                 qy = None,
+                 qx_min = None,
+                 qx_max = None,
+                 qy_min = None,
+                 qy_max = None,
+                 image = None,
+                 completefn = None,
+                 updatefn   = None,
+                 elapsed = 0,
+                 yieldtime  = 0.01,
+                 worktime   = 0.01
+                 ):
+        """
+        """
+        CalcThread.__init__(self,completefn,
+                 updatefn,
+                 yieldtime,
+                 worktime)
+        self.starttime = 0
+        self.id = id 
+        self.func = func
+        self.qx = qx
+        self.qy = qy
+        self.qx_min = qx_min
+        self.qx_max = qx_max
+        self.qy_min = qy_min
+        self.qy_max = qy_max
+        self.image = image
+        
+        
+    def compute(self):
+        """
+        excuting computation
+        """
+        self.image = map(self.func, self.qx, self.qy, 
+                        self.qx_min, self.qx_max, 
+                        self.qy_min, self.qy_max)[0]
+        elapsed = time.time() - self.starttime
+       
+        self.complete(image = self.image,
+                      elapsed = elapsed)
+        
+        
+        
+        
Index: calculatorview/src/sans/perspectives/calculator/resolution_calculator_panel.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/resolution_calculator_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/resolution_calculator_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,1387 @@
+"""
+   This software was developed by the University of Tennessee as part of the
+Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+project funded by the US National Science Foundation. 
+
+See the license text in license.txt
+
+copyright 2008, 2009, 2010 University of Tennessee
+"""
+import wx
+import sys
+import os
+import matplotlib
+import math
+#Use the WxAgg back end. The Wx one takes too long to render
+matplotlib.use('WXAgg')
+from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
+from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as Toolbar
+from matplotlib.backend_bases import FigureManagerBase
+# Wx-Pylab magic for displaying plots within an application's window.
+from matplotlib import _pylab_helpers
+# The Figure object is used to create backend-independent plot representations.
+from matplotlib.figure import Figure
+
+#from sans.guicomm.events import StatusEvent  
+from sans.calculator.resolution_calculator import ResolutionCalculator 
+from sans.guiframe.events import StatusEvent  
+from calculator_widgets import OutputTextCtrl
+from calculator_widgets import InputTextCtrl
+from wx.lib.scrolledpanel import ScrolledPanel
+from math import fabs
+_BOX_WIDTH = 100
+_Q_DEFAULT = 0.0
+#Slit length panel size 
+if sys.platform.count("win32") > 0:
+    PANEL_WIDTH = 525
+    PANEL_HEIGHT = 653
+    FONT_VARIANT = 0
+    IS_WIN = True
+else:
+    PANEL_WIDTH = 540
+    PANEL_HEIGHT = 662
+    FONT_VARIANT = 1
+    IS_WIN = False
+
+_SOURCE_MASS = {'Alpha':6.64465620E-24,
+                'Deuteron':3.34358320E-24,
+                'Neutron':1.67492729E-24, 
+                'Photon': 0.0,
+                'Proton':1.67262137E-24,
+                'Triton':5.00826667E-24}
+
+class ResolutionCalculatorPanel(ScrolledPanel):
+    """
+    Provides the Resolution calculator GUI.
+    """
+    ## Internal nickname for the window, used by the AUI manager
+    window_name = "SANS Resolution Estimator"
+    ## Name to appear on the window title bar
+    window_caption = ""
+    ## Flag to tell the AUI manager to put this panel in the center pane
+    CENTER_PANE = True
+    
+    def __init__(self, parent,  *args, **kwds):
+        kwds["size"]= (PANEL_WIDTH * 2, PANEL_HEIGHT)
+        kwds["style"]= wx.FULL_REPAINT_ON_RESIZE
+        ScrolledPanel.__init__(self, parent, *args, **kwds)
+        self.SetupScrolling()
+        self.parent = parent
+        
+        # input defaults
+        self.qx = []
+        self.qy = []
+        # dQ defaults
+        self.sigma_r = None
+        self.sigma_phi = None
+        self.sigma_1d = None
+        # monchromatic or polychromatic
+        self.wave_color = 'mono'
+        self.num_wave = 10
+        self.spectrum_dic = {}
+        # dQ 2d image
+        self.image = None
+        #Font size 
+        self.SetWindowVariant(variant=FONT_VARIANT)
+        # Object that receive status event
+        self.resolution = ResolutionCalculator()
+        # Source selection dic
+        self.source_mass = _SOURCE_MASS
+        #layout attribute
+        self.hint_sizer = None
+        # detector coordinate of estimation of sigmas
+        self.det_coordinate = 'cartesian'
+        self.source_cb = None
+        self._do_layout()
+
+    def _define_structure(self):
+        """
+        Define the main sizers building to build this application.
+        """
+        self.main_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.vertical_l_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.vertical_r_spacer = wx.BoxSizer(wx.VERTICAL)
+        self.vertical_r_frame = wx.StaticBox(self, -1, '')
+        self.vertical_r_sizer = wx.StaticBoxSizer(self.vertical_r_frame,
+                                                  wx.VERTICAL)
+        self.box_source = wx.StaticBox(self, -1,
+                                str(self.window_caption))
+        self.boxsizer_source = wx.StaticBoxSizer(self.box_source,
+                                                    wx.VERTICAL)
+        self.mass_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.intensity_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.wavelength_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.wavelength_spread_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.source_aperture_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.sample_aperture_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.source2sample_distance_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.sample2sample_distance_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.sample2detector_distance_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.detector_size_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.detector_pix_size_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        #self.detector_offset_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.input_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.output_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        
+    def _layout_mass(self):
+        """
+        Fill the sizer containing mass
+        """
+        # get the mass
+        mass_value = str(self.resolution.mass)
+        self.mass_txt = wx.StaticText(self, -1, 
+                                'Source: ')
+        self.mass_hint = "Mass of Neutrons m = %s [g]"\
+                                 % str(self.resolution.mass)
+        self.source_cb = wx.ComboBox(self, -1,
+                                style=wx.CB_READONLY,
+                                name = '%s'%mass_value)
+        # Sort source name because wx2.9 on Mac does not support CB_SORT
+        # Custom sorting
+        source_list = []
+        for key, value in self.source_mass.iteritems():
+            name_source = str(key)
+            source_list.append(name_source)
+        source_list.sort()
+        for idx in range(len(source_list)):
+            self.source_cb.Append(source_list[idx],idx)
+        self.source_cb.SetStringSelection("Neutron") 
+        wx.EVT_COMBOBOX(self.source_cb,-1, self._on_source_selection) 
+        
+        # combo box for color
+        self.wave_color_cb =  wx.ComboBox(self, -1,
+                                style=wx.CB_READONLY,
+                                name = 'color')
+        # two choices
+        self.wave_color_cb.Append('Monochromatic')
+        self.wave_color_cb.Append('Polychromatic')
+        self.wave_color_cb.SetStringSelection("Monochromatic") 
+        wx.EVT_COMBOBOX(self.wave_color_cb,-1, self._on_source_color) 
+        
+        source_hint = "Source Selection: Affect on"
+        source_hint += " the gravitational contribution.\n"
+        source_hint += "Mass of %s: m = %s [g]" % \
+                            ('Neutron', str(self.resolution.mass))
+        self.mass_txt.SetToolTipString(source_hint)
+        self.mass_sizer.AddMany([(self.mass_txt, 0, wx.LEFT, 15),
+                                    (self.source_cb, 0, wx.LEFT, 15),
+                                    (self.wave_color_cb, 0, wx.LEFT, 15)])   
+        
+    def _layout_intensity(self):
+        """
+        Fill the sizer containing intensity
+        """
+        # get the intensity
+        intensity_value = str(self.resolution.intensity)
+        intensity_unit_txt = wx.StaticText(self, -1, '[counts/s]')
+        intensity_txt = wx.StaticText(self, -1, 
+                                'Intensity: ')
+        self.intensity_tcl = InputTextCtrl(self, -1, 
+                                        size=(_BOX_WIDTH,-1))
+        intensity_hint = "Intensity of Neutrons"
+        self.intensity_tcl.SetValue(intensity_value)
+        self.intensity_tcl.SetToolTipString(intensity_hint)
+        self.intensity_sizer.AddMany([(intensity_txt, 0, wx.LEFT, 15),
+                                    (self.intensity_tcl, 0, wx.LEFT, 15),
+                                    (intensity_unit_txt,0, wx.LEFT, 10)])   
+
+        
+    def _layout_wavelength(self):
+        """
+        Fill the sizer containing wavelength
+        """
+        # get the wavelength
+        wavelength_value = str(self.resolution.get_wavelength())
+        wavelength_unit_txt = wx.StaticText(self, -1, '[A]')
+        wavelength_txt = wx.StaticText(self, -1, 
+                                'Wavelength: ')
+        self.wavelength_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        wavelength_hint = "Wavelength of Neutrons"
+        self.wavelength_tcl.SetValue(wavelength_value)
+        self.wavelength_tcl.SetToolTipString(wavelength_hint)
+
+        # get the spectrum
+        spectrum_value = self.resolution.get_default_spectrum()
+        self.spectrum_dic['Add new'] = ''
+        self.spectrum_dic['Flat'] = spectrum_value
+        
+        self.spectrum_txt = wx.StaticText(self, -1, 
+                                'Spectrum: ')
+        self.spectrum_cb = wx.ComboBox(self, -1,
+                                style=wx.CB_READONLY,
+                                size=(_BOX_WIDTH,-1),
+                                name = 'spectrum')
+        self.spectrum_cb.Append('Add new')
+        self.spectrum_cb.Append('Flat')
+        wx.EVT_COMBOBOX(self.spectrum_cb, -1, self._on_spectrum_cb) 
+        spectrum_hint = "Wavelength Spectrum: Intensity vs. wavelength"
+        #self.spectrum_cb.SetValue(spectrum_value)
+        self.spectrum_cb.SetStringSelection('Flat') 
+        self.spectrum_cb.SetToolTipString(spectrum_hint)
+        self.wavelength_sizer.AddMany([(wavelength_txt, 0, wx.LEFT, 15),
+                                    (self.wavelength_tcl, 0, wx.LEFT, 5),
+                                    (wavelength_unit_txt,0, wx.LEFT, 5),
+                                    (self.spectrum_txt, 0, wx.LEFT, 20),
+                                    (self.spectrum_cb, 0, wx.LEFT, 5)])   
+        self.spectrum_txt.Show(False)
+        self.spectrum_cb.Show(False)
+        
+    def _layout_wavelength_spread(self):
+        """
+        Fill the sizer containing wavelength
+        """
+        # get the wavelength
+        wavelength_spread_value = str(self.resolution.get_wavelength_spread())
+        wavelength_spread_unit_txt = wx.StaticText(self, -1, '')
+        wavelength_spread_txt = wx.StaticText(self, -1, 
+                                'Wavelength Spread: ')
+        self.wavelength_spread_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        wavelength_spread_hint = "Wavelength  Spread of Neutrons"
+        self.wavelength_spread_tcl.SetValue(wavelength_spread_value)
+        self.wavelength_spread_tcl.SetToolTipString(wavelength_spread_hint)
+        self.wavelength_spread_sizer.AddMany([(wavelength_spread_txt, 0, 
+                                               wx.LEFT, 15),
+                                (self.wavelength_spread_tcl, 0, wx.LEFT, 15),
+                                (wavelength_spread_unit_txt,0, wx.LEFT, 10)])      
+         
+        
+    def _layout_source_aperture(self):
+        """
+        Fill the sizer containing source aperture size
+        """
+        # get the wavelength
+        source_aperture_value = str(self.resolution.source_aperture_size[0])
+        if len(self.resolution.source_aperture_size)>1:
+            source_aperture_value += ", "
+            source_aperture_value += str(\
+                                    self.resolution.source_aperture_size[1])
+        source_aperture_unit_txt = wx.StaticText(self, -1, '[cm]')
+        source_aperture_txt = wx.StaticText(self, -1, 
+                                'Source Aperture Size: ')
+        self.source_aperture_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        source_aperture_hint = "Source Aperture Size"
+        self.source_aperture_tcl.SetValue(source_aperture_value)
+        self.source_aperture_tcl.SetToolTipString(source_aperture_hint)
+        self.source_aperture_sizer.AddMany([(source_aperture_txt, 0, 
+                                               wx.LEFT, 15),
+                                (self.source_aperture_tcl, 0, wx.LEFT, 15),
+                                    (source_aperture_unit_txt,0, wx.LEFT, 10)])  
+
+        
+    def _layout_sample_aperture(self):
+        """
+        Fill the sizer containing sample aperture size
+        """
+        # get the wavelength
+        sample_aperture_value = str(self.resolution.sample_aperture_size[0])
+        if len(self.resolution.sample_aperture_size)>1:
+            sample_aperture_value += ", "
+            sample_aperture_value += str(\
+                                    self.resolution.sample_aperture_size[1])
+        sample_aperture_unit_txt = wx.StaticText(self, -1, '[cm]')
+        sample_aperture_txt = wx.StaticText(self, -1, 
+                                'Sample Aperture Size: ')
+        self.sample_aperture_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        sample_aperture_hint = "Sample Aperture Size"
+        self.sample_aperture_tcl.SetValue(sample_aperture_value)
+        self.sample_aperture_tcl.SetToolTipString(sample_aperture_hint)
+        self.sample_aperture_sizer.AddMany([(sample_aperture_txt, 0, 
+                                               wx.LEFT, 15),
+                                (self.sample_aperture_tcl, 0, wx.LEFT, 15),
+                                    (sample_aperture_unit_txt,0, wx.LEFT, 10)])  
+
+
+    def _layout_source2sample_distance(self):
+        """
+        Fill the sizer containing souce2sample_distance
+        """
+        # get the wavelength
+        source2sample_distance_value = str(\
+                                    self.resolution.source2sample_distance[0])
+
+        source2sample_distance_unit_txt = wx.StaticText(self, -1, '[cm]')
+        source2sample_distance_txt = wx.StaticText(self, -1, 
+                                'Source to Sample Aperture Distance: ')
+        self.source2sample_distance_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        source2sample_distance_hint = "Source to Sample Aperture Distance"
+        self.source2sample_distance_tcl.SetValue(source2sample_distance_value)
+        self.source2sample_distance_tcl.SetToolTipString(\
+                                                source2sample_distance_hint)
+        self.source2sample_distance_sizer.AddMany([(source2sample_distance_txt, 
+                                               0, wx.LEFT, 15),
+                            (self.source2sample_distance_tcl, 0, wx.LEFT, 15),
+                            (source2sample_distance_unit_txt,0, wx.LEFT, 10)])  
+
+    def _layout_sample2sample_distance(self):
+        """
+        Fill the sizer containing sampleslit2sample_distance
+        """
+        # get the distance
+        sample2sample_distance_value = str(\
+                                    self.resolution.sample2sample_distance[0])
+
+        sample2sample_distance_unit_txt = wx.StaticText(self, -1, '[cm]')
+        sample2sample_distance_txt = wx.StaticText(self, -1, 
+                                'Sample Offset: ')
+        self.sample2sample_distance_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        sample2sample_distance_hint = "Sample Aperture to Sample Distance"
+        self.sample2sample_distance_tcl.SetValue(sample2sample_distance_value)
+        self.sample2sample_distance_tcl.SetToolTipString(\
+                                                sample2sample_distance_hint)
+        self.sample2sample_distance_sizer.AddMany([(sample2sample_distance_txt, 
+                                               0, wx.LEFT, 15),
+                            (self.sample2sample_distance_tcl, 0, wx.LEFT, 15),
+                            (sample2sample_distance_unit_txt,0, wx.LEFT, 10)])  
+
+
+
+    def _layout_sample2detector_distance(self):
+        """
+        Fill the sizer containing sample2detector_distance
+        """
+        # get the wavelength
+        sample2detector_distance_value = str(\
+                                    self.resolution.sample2detector_distance[0])
+
+        sample2detector_distance_unit_txt = wx.StaticText(self, -1, '[cm]')
+        sample2detector_distance_txt = wx.StaticText(self, -1, 
+                                'Sample Aperture to Detector Distance: ')
+        self.sample2detector_distance_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        sample2detector_distance_hint = \
+                                "Sample Aperture to Detector Distance"
+        self.sample2detector_distance_tcl.SetValue(\
+                                                sample2detector_distance_value)
+        self.sample2detector_distance_tcl.SetToolTipString(\
+                                                sample2detector_distance_hint)
+        self.sample2detector_distance_sizer.AddMany([\
+                            (sample2detector_distance_txt, 0, wx.LEFT, 15),        
+                            (self.sample2detector_distance_tcl, 0, wx.LEFT, 15),
+                            (sample2detector_distance_unit_txt,0, wx.LEFT, 10)])  
+        
+    def _layout_detector_size(self):
+        """
+        Fill the sizer containing detector size
+        """
+        # get the wavelength
+        detector_size_value = str(self.resolution.detector_size[0])
+        if len(self.resolution.detector_size)>1:
+            detector_size_value += ", "
+            detector_size_value += str(self.resolution.detector_size[1])
+        detector_size_unit_txt = wx.StaticText(self, -1, '')
+        detector_size_txt = wx.StaticText(self, -1, 
+                                'Number of Pixels on Detector: ')
+        self.detector_size_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        detector_size_hint = "Number of Pixels on Detector"
+        self.detector_size_tcl.SetValue(detector_size_value)
+        self.detector_size_tcl.SetToolTipString(detector_size_hint)
+        self.detector_size_sizer.AddMany([(detector_size_txt, 0, 
+                                               wx.LEFT, 15),
+                                (self.detector_size_tcl, 0, wx.LEFT, 15),
+                                    (detector_size_unit_txt,0, wx.LEFT, 10)])  
+
+        
+    def _layout_detector_pix_size(self):
+        """
+        Fill the sizer containing detector pixel size
+        """
+        # get the detector_pix_size
+        detector_pix_size_value = str(self.resolution.detector_pix_size[0])
+        if len(self.resolution.detector_pix_size)>1:
+            detector_pix_size_value += ", "
+            detector_pix_size_value += str(self.resolution.detector_pix_size[1])
+        detector_pix_size_unit_txt = wx.StaticText(self, -1, '[cm]')
+        detector_pix_size_txt = wx.StaticText(self, -1, 
+                                'Detector Pixel Size: ')
+        self.detector_pix_size_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH,-1))
+        detector_pix_size_hint = "Detector Pixel Size"
+        self.detector_pix_size_tcl.SetValue(detector_pix_size_value)
+        self.detector_pix_size_tcl.SetToolTipString(detector_pix_size_hint)
+        self.detector_pix_size_sizer.AddMany([(detector_pix_size_txt, 0, 
+                                               wx.LEFT, 15),
+                                (self.detector_pix_size_tcl, 0, wx.LEFT, 15),
+                                (detector_pix_size_unit_txt,0, wx.LEFT, 10)])
+        
+    def _layout_input(self):
+        """
+        Fill the sizer containing inputs; qx, qy
+        """
+        
+        q_title = wx.StaticText(self, -1, 
+                            "[Q Location of the Estimation]:")
+        # sizers for inputs
+        inputQx_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        inputQy_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        # get the default dq
+        qx_value = str(_Q_DEFAULT)
+        qy_value = str(_Q_DEFAULT)
+        qx_unit_txt = wx.StaticText(self, -1, '[1/A]  ')
+        qy_unit_txt = wx.StaticText(self, -1, '[1/A]  ')
+        qx_name_txt = wx.StaticText(self, -1, 
+                                'Qx: ')
+        qy_name_txt = wx.StaticText(self, -1, 
+                                'Qy: ')
+        self.qx_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH*3,-1))
+        self.qy_tcl = InputTextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH*3,-1))
+        qx_hint = "Type the Qx value."
+        qy_hint = "Type the Qy value."
+        self.qx_tcl.SetValue(qx_value)
+        self.qy_tcl.SetValue(qy_value)
+        self.qx_tcl.SetToolTipString(qx_hint)
+        self.qy_tcl.SetToolTipString(qy_hint)
+        inputQx_sizer.AddMany([(qx_name_txt, 0, wx.LEFT, 15),
+                                    (self.qx_tcl, 0, wx.LEFT, 15),
+                                    (qx_unit_txt, 0, wx.LEFT, 15)])
+        inputQy_sizer.AddMany([(qy_name_txt, 0, wx.LEFT, 15),
+                                    (self.qy_tcl, 0, wx.LEFT, 15),
+                                    (qy_unit_txt, 0, wx.LEFT, 15)])
+        self.input_sizer.AddMany([(q_title, 0, wx.LEFT, 15), 
+                                    (inputQx_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                    (inputQy_sizer, 0, 
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+                                #(self.compute_button, 0, wx.LEFT, 30)])
+        
+    def _layout_output(self):
+        """
+        Fill the sizer containing dQ|| and dQ+
+        """
+        sigma_title = wx.StaticText(self, -1, 
+                        "[Standard Deviation of the Resolution Distribution]:")
+         # sizers for inputs
+        outputQxy_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        outputQ_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        sigma_unit = '['+'1/A' +']'
+        self.sigma_r_txt = wx.StaticText(self, -1, 
+                                           'Sigma_x:   ')
+        self.sigma_r_tcl = OutputTextCtrl(self, -1, 
+                                                 size=(_BOX_WIDTH*0.8,-1))
+        self.sigma_phi_txt = wx.StaticText(self, -1, 
+                                           'Sigma_y:')
+        self.sigma_phi_tcl = OutputTextCtrl(self, -1, 
+                                                 size=(_BOX_WIDTH*0.8,-1))
+        self.sigma_lamd_txt = wx.StaticText(self, -1, 
+                                           'Sigma_lamd:')
+        self.sigma_lamd_tcl = OutputTextCtrl(self, -1, 
+                                                 size=(_BOX_WIDTH*0.7,-1))
+        sigma_1d_txt = wx.StaticText(self, -1, '( 1D:   Sigma:')
+        self.sigma_1d_tcl = OutputTextCtrl(self, -1, 
+                                                 size=(_BOX_WIDTH*0.7,-1))
+        sigmax_hint = " The x component of the geometric resolution,"
+        sigmax_hint +=  " excluding sigma_lamda."
+        sigmay_hint = " The y component of the geometric resolution,"
+        sigmay_hint +=  " excluding sigma_lamda."
+        sigma_hint_lamd = " The wavelength contribution in the radial direction"
+        sigma_hint_lamd += ".\n Note: The phi component is always zero."
+        sigma_hint_1d = " Resolution in 1-dimension (for 1D data)."
+        self.sigma_r_tcl.SetToolTipString(sigmax_hint)
+        self.sigma_phi_tcl.SetToolTipString(sigmay_hint)
+        self.sigma_lamd_tcl.SetToolTipString(sigma_hint_lamd)
+        self.sigma_1d_tcl.SetToolTipString(sigma_hint_1d)
+        sigma_r_unit_txt = wx.StaticText(self, -1, sigma_unit)
+        sigma_phi_unit_txt = wx.StaticText(self, -1, sigma_unit)
+        sigma_lamd_unit_txt = wx.StaticText(self, -1, sigma_unit)
+        sigma_1d_unit_txt = wx.StaticText(self, -1, sigma_unit+' )')
+        outputQxy_sizer.AddMany([(self.sigma_r_txt, 0, wx.LEFT, 15),
+                                    (self.sigma_r_tcl, 0, wx.LEFT, 15),
+                                    (sigma_r_unit_txt, 0, wx.LEFT, 15),
+                                    (self.sigma_phi_txt, 0, wx.LEFT, 15),
+                                    (self.sigma_phi_tcl, 0, wx.LEFT, 15),
+                                    (sigma_phi_unit_txt, 0, wx.LEFT, 15)])
+        outputQ_sizer.AddMany([(self.sigma_lamd_txt, 0, wx.LEFT, 15),
+                                    (self.sigma_lamd_tcl, 0, wx.LEFT, 15),
+                                    (sigma_lamd_unit_txt, 0, wx.LEFT, 15),
+                                    (sigma_1d_txt, 0, wx.LEFT, 15),
+                                    (self.sigma_1d_tcl, 0, wx.LEFT, 15),
+                                    (sigma_1d_unit_txt, 0, wx.LEFT, 15)])
+        self.output_sizer.AddMany([(sigma_title, 0, wx.LEFT, 15), 
+                                    (outputQxy_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                    (outputQ_sizer, 0, 
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        
+    
+    def _layout_hint(self):
+        """
+        Fill the sizer containing hint 
+        """
+        hint_msg = ""
+        #hint_msg += "This tool is to approximately compute "
+        #hint_msg += "the instrumental resolution (dQ)."
+
+        self.hint_txt = wx.StaticText(self, -1, hint_msg)
+        self.hint_sizer.AddMany([(self.hint_txt, 0, wx.LEFT, 15)])
+    
+    def _layout_button(self):  
+        """
+        Do the layout for the button widgets
+        """ 
+        # coordinate selction removed
+        #outerbox_txt = wx.StaticText(self, -1, 'Outer Box')
+        #self.x_y_rb = wx.RadioButton(self, -1,"Cartesian")
+        #self.Bind(wx.EVT_RADIOBUTTON,
+        #          self._on_xy_coordinate, id=self.x_y_rb.GetId())
+        #self.r_phi_rb = wx.RadioButton(self, -1,"Polar")
+        #self.Bind(wx.EVT_RADIOBUTTON,
+        #          self._on_rp_coordinate, id=self.r_phi_rb.GetId())
+        #self.r_phi_rb.SetValue(True)
+        #reset button
+        id = wx.NewId()
+        self.reset_button = wx.Button(self, id, "Reset")
+        hint_on_reset = "..."
+        self.reset_button.SetToolTipString(hint_on_reset)
+        self.Bind(wx.EVT_BUTTON, self.on_reset, id=id)
+        #compute button
+        id = wx.NewId()
+        self.compute_button = wx.Button(self, id, "Compute")
+        hint_on_compute = "Compute... Please wait until finished."
+        self.compute_button.SetToolTipString(hint_on_compute)
+        self.Bind(wx.EVT_BUTTON, self.on_compute, id=id)
+        # close button
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.Bind(wx.EVT_BUTTON, self.on_close)
+        self.bt_close.SetToolTipString("Close this window.")
+        """
+        self.button_sizer.AddMany([(self.r_phi_rb,  0, wx.LEFT, 15),
+                                   (self.x_y_rb,  0, wx.LEFT, 15),
+                                   (self.reset_button, 0, wx.LEFT, 50),
+                                   (self.compute_button, 0, wx.LEFT, 15),
+                                   (self.bt_close, 0, wx.LEFT, 15)])#370)])
+        """
+        self.button_sizer.Add((110, -1))
+        self.button_sizer.AddMany([(self.reset_button, 0, wx.LEFT, 50),
+                                   (self.compute_button, 0, wx.LEFT, 15),
+                                   (self.bt_close, 0, wx.LEFT, 15)])
+        self.compute_button.SetFocus()
+        
+    def _layout_image(self):
+        """
+        Layout for image plot
+        """
+        color = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
+
+        # Contribution by James C.
+        # Instantiate a figure object that will contain our plots.
+        # Make the fig a little smaller than the default
+        self.figure = Figure(figsize=(6.5, 6), facecolor = 'white')
+        
+        # Initialize the figure canvas, mapping the figure object to the plot
+        # engine backend.
+        self.canvas = FigureCanvas(self, wx.ID_ANY, self.figure)
+
+        # Wx-Pylab magic ...
+        # Make our canvas the active figure manager for pylab so that when
+        # pylab plotting statements are executed they will operate on our
+        # canvas and not create a new frame and canvas for display purposes.
+        # This technique allows this application to execute code that uses
+        # pylab stataments to generate plots and embed these plots in our
+        # application window(s).
+        self.fm = FigureManagerBase(self.canvas, 1)
+        _pylab_helpers.Gcf.set_active(self.fm)
+        
+        # Instantiate the matplotlib navigation toolbar and explicitly show it.
+        mpl_toolbar = Toolbar(self.canvas)
+        # Diable pan
+        mpl_toolbar.DeleteToolByPos(3)
+
+        # Add a toolbar into the frame
+        mpl_toolbar.Realize()
+
+        # Compute before adding the canvas to the sizer
+        self.on_compute()
+        
+        # Fill up the sizer
+        if IS_WIN:
+            gap = 27
+        else:
+            gap = 13
+        self.vertical_r_sizer.Add(self.canvas, 0, 
+                                       wx.ALL|wx.EXPAND, 2) 
+        self.vertical_r_spacer.Add((0, gap)) 
+        self.vertical_r_spacer.Add(self.vertical_r_sizer, 0, 
+                                       wx.ALL|wx.EXPAND, 2)
+        self.vertical_r_spacer.Add((0, gap)) 
+        self.vertical_r_spacer.Add(wx.StaticLine(self), 0, 
+                                       wx.ALL|wx.EXPAND, 2)
+        self.vertical_r_spacer.Add(mpl_toolbar, 0,  wx.ALL|wx.EXPAND, 2)
+
+        
+    def _do_layout(self):
+        """
+            Draw window layout
+        """
+        #  Title of parameters
+        instrument_txt = wx.StaticText(self, -1, 
+                                '[Instrumental Parameters]:')
+        # Build individual layouts
+        self._define_structure()
+        self._layout_mass()
+        #self._layout_intensity()
+        self._layout_wavelength()
+        self._layout_wavelength_spread()
+        self._layout_source_aperture()
+        self._layout_sample_aperture()
+        self._layout_source2sample_distance()
+        self._layout_sample2detector_distance()
+        self._layout_sample2sample_distance()
+        self._layout_detector_size()
+        self._layout_detector_pix_size()
+        self._layout_input()
+        self._layout_output()
+        self._layout_hint()
+        self._layout_button()
+        # Fill the sizers
+        self.boxsizer_source.AddMany([(instrument_txt, 0,
+                                       wx.EXPAND|wx.LEFT, 15),
+                                      (self.mass_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      #(self.intensity_sizer, 0,
+                                      #wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.wavelength_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.wavelength_spread_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.source_aperture_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.sample_aperture_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.source2sample_distance_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.sample2detector_distance_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.sample2sample_distance_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.detector_size_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (self.detector_pix_size_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (wx.StaticLine(self), 0, 
+                                       wx.ALL|wx.EXPAND, 5),
+                                      (self.input_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                      (wx.StaticLine(self), 0, 
+                                       wx.ALL|wx.EXPAND, 5),
+                                      (self.output_sizer, 0,
+                                      wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.vertical_l_sizer.AddMany([(self.boxsizer_source, 0, wx.ALL, 10),
+                                       (wx.StaticLine(self), 0, 
+                                       wx.ALL|wx.EXPAND, 5),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.main_sizer.Add(self.vertical_l_sizer, 0, wx.ALL, 10)
+        
+        # Build image plot layout                     
+        self._layout_image()
+        # Add a vertical static line
+        self.main_sizer.Add( wx.StaticLine(self, -1, (2,2), 
+                            (2,PANEL_HEIGHT * 0.94), style = wx.LI_VERTICAL))
+        # Add the plot to main sizer
+        self.main_sizer.Add(self.vertical_r_spacer, 0, wx.ALL, 10)
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+        
+
+    def on_close(self, event):
+        """
+        close the window containing this panel
+        """
+        # get ready for other events
+        if event is not None:
+            event.Skip()
+        # Clear the plot
+        if self.image != None:
+            self.image.clf()
+            #self.image.draw()
+        # Close panel
+        self.parent.Close()
+        # reset image
+        self.image = None
+    
+    def on_compute(self, event = None):  
+        """
+        Execute the computation of resolution
+        """
+        wx.CallAfter(self.on_compute_call, event)
+        
+    def on_compute_call(self, event = None):
+        """
+        Execute the computation of resolution
+        """
+        # Skip event for next event
+        if event != None:
+            event.Skip()
+            msg = "Please Check your input values "
+            msg += "before starting the computation..."
+
+        # message
+        status_type = 'progress' 
+        msg = 'Calculating...'
+        self._status_info(msg, status_type)
+
+        status_type = 'stop'           
+        # Q min max list default
+        qx_min = []   
+        qx_max = [] 
+        qy_min = [] 
+        qy_max = [] 
+        
+        try:
+            # Get all the values at set to compute
+            # default num bin of wave list
+            self.num_wave = 10
+            wavelength = self._str2longlist(self.wavelength_tcl.GetValue())
+            source = self.source_cb.GetValue()
+            mass = self.source_mass[str(source)]
+            self.resolution.set_neutron_mass(float(mass))
+            wavelength_spread = self._str2longlist(\
+                        self.wavelength_spread_tcl.GetValue().split(';')[0])
+            # Validate the wave inputs
+            wave_input = self._validate_q_input(wavelength, wavelength_spread)
+            if wave_input != None:
+                wavelength, wavelength_spread = wave_input
+    
+            #self.resolution.set_wave(float(wavelength))
+            self.resolution.set_wave(wavelength)
+            #self.resolution.set_wave_spread(float(wavelength_spread))
+            self.resolution.set_wave_spread(wavelength_spread)
+            source_aperture_size = self.source_aperture_tcl.GetValue()
+            source_aperture_size = self._string2list(source_aperture_size)
+            self.resolution.set_source_aperture_size(source_aperture_size)
+            sample_aperture_size = self.sample_aperture_tcl.GetValue()
+            sample_aperture_size = self._string2list(sample_aperture_size)
+            self.resolution.set_sample_aperture_size(sample_aperture_size)
+            source2sample_distance = self.source2sample_distance_tcl.GetValue()
+            source2sample_distance = self._string2list(source2sample_distance)
+            self.resolution.set_source2sample_distance(source2sample_distance)
+            sample2sample_distance = self.sample2sample_distance_tcl.GetValue()
+            sample2sample_distance = self._string2list(sample2sample_distance)
+            self.resolution.set_sample2sample_distance(sample2sample_distance)
+            sample2detector_distance = self.sample2detector_distance_tcl.GetValue()
+            sample2detector_distance = self._string2list(sample2detector_distance)
+            self.resolution.set_sample2detector_distance(sample2detector_distance)
+            detector_size = self.detector_size_tcl.GetValue()
+            detector_size = self._string2list(detector_size)
+            self.resolution.set_detector_size(detector_size)
+            detector_pix_size = self.detector_pix_size_tcl.GetValue()
+            detector_pix_size = self._string2list(detector_pix_size)
+            self.resolution.set_detector_pix_size(detector_pix_size)
+            self.qx = self._string2inputlist(self.qx_tcl.GetValue())
+            self.qy = self._string2inputlist(self.qy_tcl.GetValue())
+            
+            
+            # Find min max of qs
+            xmin = min(self.qx)
+            xmax = max(self.qx)
+            ymin = min(self.qy)
+            ymax = max(self.qy)
+            if not self._validate_q_input(self.qx, self.qy):
+                raise
+        except:
+            msg = "An error occured during the resolution computation."
+            msg += "Please check your inputs..."
+            self._status_info(msg, status_type)
+            wx.MessageBox(msg, 'Warning')
+            return
+            #raise ValueError, "Invalid Q Input..."
+
+        # Validate the q inputs
+        q_input = self._validate_q_input(self.qx, self.qy)
+        if q_input != None:
+            self.qx, self.qy = q_input
+        
+        # Make list of q min max for mapping
+        for length in range(len(self.qx)):
+            qx_min.append(xmin)
+            qx_max.append(xmax)
+        for length in range(len(self.qy)):
+            qy_min.append(ymin)
+            qy_max.append(ymax)
+        
+        # Compute the resolution
+        if self.image != None:
+            #_pylab_helpers.Gcf.set_active(self.fm)
+            # Clear the image before redraw
+            self.image.clf()
+            # reset the image
+            self.resolution.reset_image()
+
+        # Compute and get the image plot
+        try:
+            from .resolcal_thread import CalcRes as thread
+            cal_res = thread(func = self._map_func,
+                         qx = self.qx,
+                         qy = self.qy,
+                         qx_min = qx_min,
+                         qx_max = qx_max,
+                         qy_min = qy_min,
+                         qy_max = qy_max,
+                         image = self.image,
+                         completefn = self.complete_cal)
+            #self.image = map(self._map_func, self.qx, self.qy, 
+            #                 qx_min, qx_max, qy_min, qy_max)[0]
+            cal_res.queue()
+            msg = "Computation is in progress..."
+            #msg = "Finished the resolution computation..."
+            status_type = 'progress'
+            self._status_info(msg, status_type)
+        except:
+            raise
+            msg = "An error occured during the resolution computation."
+            msg += "Please check your inputs..."
+            status_type = 'stop'
+            self._status_info(msg, status_type)
+            wx.MessageBox(msg, 'Warning')
+            
+    def complete(self, image, elapsed=None):
+        """
+        Callafter complete: wx call after needed for stable output
+        """
+        wx.CallAfter(self.complte, image, elapsed)   
+        
+    def complete_cal(self, image, elapsed=None):
+        """
+        Complete computation
+        """
+        self.image = image
+        # Draw lines in image before drawing
+        wave_list, _ = self.resolution.get_wave_list()
+        if len(wave_list) > 1 and wave_list[-1] == max(wave_list):
+            # draw a green rectangle(limit for the longest wavelength 
+            # to be involved) for tof inputs
+            self._draw_lines(self.image, color='g')
+        self._draw_lines(self.image, color='r')
+        # Draw image
+        self.image.draw()
+        #self.vertical_r_sizer.Layout()
+        
+        # Get and format the sigmas 
+        sigma_r = self.format_number(self.resolution.sigma_1)
+        sigma_phi = self.format_number(self.resolution.sigma_2)
+        sigma_lamd = self.format_number(self.resolution.sigma_lamd)
+        sigma_1d =  self.format_number(self.resolution.sigma_1d)
+
+        # Set output values 
+        self.sigma_r_tcl.SetValue(str(sigma_r))
+        self.sigma_phi_tcl.SetValue(str(sigma_phi))
+        self.sigma_lamd_tcl.SetValue(str(sigma_lamd))
+        self.sigma_1d_tcl.SetValue(str(sigma_1d))
+        msg = "Resolution computation is finished."
+        status_type = 'stop'
+        self._status_info(msg, status_type)
+        
+    def _draw_lines(self, image=None, color='r'):
+        """
+        Draw lines in image if applicable
+        : Param image: pylab object
+        """
+        if image == None:
+            return
+        if color == 'g':
+            # Get the params from resolution
+            # ploting range for largest wavelength
+            qx_min = self.resolution.qx_min
+            qx_max = self.resolution.qx_max
+            qy_min = self.resolution.qy_min
+            qy_max = self.resolution.qy_max
+            # detector range
+            detector_qx_min = self.resolution.detector_qx_min
+            detector_qx_max = self.resolution.detector_qx_max
+            detector_qy_min = self.resolution.detector_qy_min
+            detector_qy_max = self.resolution.detector_qy_max
+        else:
+            qx_min, qx_max, qy_min, qy_max = self.resolution.get_detector_qrange()
+            # detector range
+            detector_qx_min = self.resolution.qxmin_limit
+            detector_qx_max = self.resolution.qxmax_limit
+            detector_qy_min = self.resolution.qymin_limit
+            detector_qy_max = self.resolution.qymax_limit
+        
+        # Draw zero axis lines
+        if qy_min < 0 and qy_max >= 0:
+            image.axhline(linewidth = 1)
+        if qx_min < 0 and qx_max >= 0:
+            image.axvline(linewidth = 1)
+            
+        # Find x and y ratio values to draw the detector outline
+        x_min = fabs(detector_qx_min - qx_min) / (qx_max - qx_min)
+        x_max = fabs(detector_qx_max - qx_min) / (qx_max - qx_min)
+        y_min = fabs(detector_qy_min - qy_min) / (qy_max - qy_min)
+        y_max = fabs(detector_qy_max - qy_min) / (qy_max - qy_min)
+        
+        # Draw Detector outline
+        if detector_qy_min >= qy_min:
+            image.axhline(y = detector_qy_min + 0.0002,
+                               xmin = x_min,
+                               xmax = x_max, 
+                               linewidth = 2, color=color)
+        if detector_qy_max <= qy_max:
+            image.axhline(y = detector_qy_max - 0.0002, 
+                               xmin = x_min, 
+                               xmax = x_max, 
+                               linewidth = 2, color=color)
+        if detector_qx_min >= qx_min:
+            image.axvline(x = detector_qx_min + 0.0002, 
+                               ymin = y_min, 
+                               ymax = y_max, 
+                               linewidth = 2, color=color)
+        if detector_qx_max <= qx_max:
+            image.axvline(x = detector_qx_max - 0.0002, 
+                               ymin = y_min, 
+                               ymax = y_max, 
+                               linewidth = 2, color=color)
+        xmin = min(self.qx)
+        xmax = max(self.qx)
+        ymin = min(self.qy)
+        ymax = max(self.qy)
+        if color != 'g':
+            if xmin < detector_qx_min or xmax > detector_qx_max or \
+                        ymin < detector_qy_min or ymax > detector_qy_max:
+                # message
+                status_type = 'stop' 
+                msg = 'At least one q value located out side of\n'
+                msg += " the detector range (%s < qx < %s, %s < qy < %s),\n" % \
+                        (self.format_number(detector_qx_min), 
+                         self.format_number(detector_qx_max),
+                         self.format_number(detector_qy_min), 
+                         self.format_number(detector_qy_max))
+                msg += " is ignored in computation.\n"
+                
+                self._status_info(msg, status_type)
+                wx.MessageBox(msg, 'Warning')
+        
+    def _map_func(self, qx, qy, qx_min, qx_max, qy_min, qy_max):    
+        """
+        Prepare the Mapping for the computation
+        : params qx, qy, qx_min, qx_max, qy_min, qy_max:
+        
+        : return: image (pylab)
+        """
+        try:
+            qx_value = float(qx)
+            qy_value = float(qy)
+        except:
+            raise
+        # calculate 2D resolution distribution image
+        image = self.resolution.compute_and_plot(qx_value, qy_value, 
+                                 qx_min, qx_max, qy_min, qy_max, 
+                                 self.det_coordinate)
+        
+
+        return image
+    
+    def _validate_q_input(self, qx, qy):    
+        """
+        Check if q inputs are valid
+        : params qx:  qx as a list
+        : params qy:  qy as a list
+        
+        : return: True/False
+        """
+        # check qualifications
+        if qx.__class__.__name__ != 'list':
+            return None
+        if qy.__class__.__name__ != 'list' :
+            return None
+        if len(qx) < 1:
+            return None
+        if len(qy) < 1:
+            return None
+        # allow one input
+        if len(qx) == 1 and len(qy) > 1:
+            qx = [qx[0] for ind in range(len(qy))]
+            #self.qx = qx
+        if len(qy) == 1 and len(qx) > 1:
+            qy = [qy[0] for ind in range(len(qx))]
+            #self.qy = qy
+        # check length
+        if len(qx) != len(qy):
+            return None
+        if qx == None or qy == None:
+            return None
+        return qx, qy 
+     
+    def on_reset(self, event):
+        """
+        Execute the reset
+        """
+        # skip for another event
+        if event != None:
+            event.Skip()  
+        # init resolution_calculator
+        self.resolution = ResolutionCalculator()
+        self.resolution.get_all_instrument_params()
+        # reset all param values
+        self.source_cb.SetValue('Neutron')
+        self._on_source_selection(None)
+        self.wave_color_cb.SetValue('Monochromatic')
+        self._on_source_color(None)
+        #self.intensity_tcl.SetValue(str(self.resolution.intensity))
+        self.wavelength_tcl.SetValue(str(6.0))
+        self.wavelength_spread_tcl.SetValue(str(0.125))
+        self.resolution.set_spectrum(self.spectrum_dic['Flat'])
+        self.spectrum_txt.Show(False)
+        self.spectrum_cb.Show(False)
+        source_aperture_value = str(self.resolution.source_aperture_size[0])
+        if len(self.resolution.source_aperture_size)>1:
+            source_aperture_value += ", "
+            source_aperture_value += \
+                str(self.resolution.source_aperture_size[1])
+        self.source_aperture_tcl.SetValue(str(source_aperture_value))
+        sample_aperture_value = str(self.resolution.sample_aperture_size[0])
+        if len(self.resolution.sample_aperture_size)>1:
+            sample_aperture_value += ", "
+            sample_aperture_value += \
+                str(self.resolution.sample_aperture_size[1])
+        self.sample_aperture_tcl.SetValue(sample_aperture_value)
+        source2sample_distance_value = \
+            str(self.resolution.source2sample_distance[0])
+        self.source2sample_distance_tcl.SetValue(source2sample_distance_value)
+        sample2sample_distance_value = \
+            str(self.resolution.sample2sample_distance[0])
+        self.sample2sample_distance_tcl.SetValue(sample2sample_distance_value)
+        sample2detector_distance_value = \
+            str(self.resolution.sample2detector_distance[0])
+        self.sample2detector_distance_tcl.SetValue(\
+                                            sample2detector_distance_value)
+        detector_size_value = str(self.resolution.detector_size[0])
+        if len(self.resolution.detector_size)>1:
+            detector_size_value += ", "
+            detector_size_value += str(self.resolution.detector_size[1])
+        self.detector_size_tcl.SetValue(detector_size_value)
+        detector_pix_size_value = str(self.resolution.detector_pix_size[0])
+        if len(self.resolution.detector_pix_size)>1:
+            detector_pix_size_value += ", "
+            detector_pix_size_value += str(self.resolution.detector_pix_size[1])
+        self.detector_pix_size_tcl.SetValue(detector_pix_size_value)
+        #layout attribute
+        self.hint_sizer = None
+        # reset q inputs
+        self.qx_tcl.SetValue(str(_Q_DEFAULT))
+        self.qy_tcl.SetValue(str(_Q_DEFAULT))
+        # reset sigma outputs
+        self.sigma_r_tcl.SetValue('')
+        self.sigma_phi_tcl.SetValue('')
+        self.sigma_1d_tcl.SetValue('')
+        # reset radio button
+        #self.r_phi_rb.SetValue(True)
+        # Finally re-compute
+        self.on_compute()
+        # msg on info
+        msg = " Finished the resetting..."
+        self._status_info(msg, 'stop')
+        
+    def format_number(self, value=None):
+        """
+        Return a float in a standardized, human-readable formatted string 
+        """
+        try: 
+            value = float(value)
+        except:
+            output = None
+            return output
+
+        output = "%-7.4g" % value
+        return output.lstrip().rstrip()  
+     
+    def _string2list(self, string):
+        """
+        Change NNN, NNN to list,ie. [NNN, NNN] where NNN is a number
+        """
+        new_string = []
+        # check the number of floats 
+        try:
+            strg = float(string)
+            new_string.append(strg)
+            #new_string.append(0)
+        except:
+            string_split = string.split(',')
+            if len(string_split) == 2:
+                str_1 = string_split[0]
+                str_2 = string_split[1]
+                new_string.append(float(str_1))
+                new_string.append(float(str_2))
+            elif len(string_split) == 1:
+                str_1 = string_split[0]
+                new_string.append(float(str_1))
+            else:
+                msg = "The numbers must be one or two (separated by ',')..."
+                self._status_info(msg, 'stop')
+                raise RuntimeError, msg
+
+        return new_string
+    
+    def _string2inputlist(self, string):
+        """
+        Change NNN, NNN,... to list,ie. [NNN, NNN,...] where NNN is a number
+        
+        : return new_string: string like list
+        """
+        new_string = []
+        string_split = string.split(',')
+        length = len(string_split)
+        for ind in range(length):
+            try:
+                value = float(string_split[ind])
+                new_string.append(value)
+            except:
+                pass
+        
+        return new_string
+    
+    def _str2longlist(self, string):
+        """
+        Change NNN, NNN,... to list, NNN - NNN ; NNN to list, or float to list
+        
+        : return new_string: string like list
+        """
+        new_string = []
+        msg = "Wrong format of intputs."
+        try:
+            # is float
+            out = [float(string)]
+            return out
+        except:
+            if self.wave_color.lower().count('mono') > 0:
+                wx.MessageBox(msg, 'Warning')
+            else:
+                try:
+                    # has a '-' 
+                    if string.count('-') > 0:
+                        value = string.split('-')
+                        if value[1].count(';') > 0:
+                            # has a ';'
+                            last_list = value[1].split(';')
+                            num =  math.ceil(float(last_list[1]))
+                            max = float(last_list[0])
+                            self.num_wave = num
+                        else:
+                            # default num
+                            num = self.num_wave
+                            max = float(value[1])
+                        min = float(value[0])
+                        # make a list
+                        bin_size = math.fabs(max - min) / (num - 1)
+                        out = [min + bin_size * bnum for bnum in range(num)]
+                        return out
+                    if string.count(',') > 0:
+                        out = self._string2inputlist(string)
+                        return out
+                except:
+                    pass
+                #    wx.MessageBox(msg, 'Warning')
+
+    def _on_xy_coordinate(self,event=None):
+        """
+        Set the detector coordinate for sigmas to x-y coordinate
+        """
+        if event != None:
+            event.Skip()        
+        # Set the coordinate in Cartesian       
+        self.det_coordinate = 'cartesian'
+        self.sigma_r_txt.SetLabel('Sigma_x:')
+        self.sigma_phi_txt.SetLabel('Sigma_y:')
+        self._onparamEnter()
+        
+    def _on_rp_coordinate(self,event=None):
+        """
+        Set the detector coordinate for sigmas to polar coordinate
+        """
+        if event != None:
+            event.Skip()        
+        # Set the coordinate in polar            
+        self.det_coordinate = 'polar'
+        self.sigma_r_txt.SetLabel('Sigma_r:   ')
+        self.sigma_phi_txt.SetLabel('Sigma_phi:')
+        self._onparamEnter()
+        
+    def _status_info(self, msg = '', type = "update"):
+        """
+        Status msg
+        """
+        if type == "stop":
+            label = "Compute"
+            able = True
+        else:   
+            label = "Wait..."
+            able = False
+        self.compute_button.Enable(able)
+        self.compute_button.SetLabel(label)
+        self.compute_button.SetToolTipString(label)
+        if self.parent.parent != None:
+                wx.PostEvent(self.parent.parent, 
+                             StatusEvent(status = msg, type = type ))
+
+
+    def _onparamEnter(self, event = None):
+        """
+        On Text_enter_callback, perform compute
+        """
+        self.on_compute()
+        
+    def _on_source_selection(self, event = None):
+        """
+        On source combobox selection
+        """
+        if event != None:
+            combo = event.GetEventObject()
+            event.Skip()
+        else:
+            combo = self.source_cb
+        selection = combo.GetValue()
+        mass = self.source_mass[selection]
+        self.resolution.set_neutron_mass(mass)   
+        source_hint = "Source Selection: Affect on"
+        source_hint += " the gravitational contribution.\n"
+        source_hint += "Mass of %s: m = %s [g]" % \
+                            (selection, str(self.resolution.get_neutron_mass()))
+        #source_tip.SetTip(source_hint)
+        self.mass_txt.ToolTip.SetTip(source_hint)
+        
+    def _on_source_color(self, event = None):
+        """
+        On source color combobox selection
+        """
+        if event != None:
+            #combo = event.GetEventObject()
+            event.Skip()
+        #else:
+        combo = self.wave_color_cb
+        selection = combo.GetValue()
+        self.wave_color = selection
+        if self.wave_color.lower() == 'polychromatic':
+            list = self.resolution.get_wave_list()
+            minw = min(list[0])
+            if len(list[0]) < 2:
+                maxw = 2 * minw
+            else:
+                maxw = max(list[0])
+            self.wavelength_tcl.SetValue('%s - %s' % (minw, maxw))
+            minw = min(list[1])
+            maxw = max(list[1])
+            self.wavelength_spread_tcl.SetValue('%s - %s' % (minw, maxw))
+            spectrum_val = self.spectrum_cb.GetValue()
+            self.resolution.set_spectrum(self.spectrum_dic[spectrum_val])
+            self.spectrum_txt.Show(True)
+            self.spectrum_cb.Show(True)
+          
+        else:
+            wavelength = self.resolution.get_wavelength()
+            wavelength_spread = self.resolution.get_wavelength_spread()
+            self.wavelength_tcl.SetValue(str(wavelength))
+            self.wavelength_spread_tcl.SetValue(str(wavelength_spread))
+            self.resolution.set_spectrum(self.spectrum_dic['Flat'])
+            self.spectrum_txt.Show(False)
+            self.spectrum_cb.Show(False)
+        self.wavelength_sizer.Layout() 
+        self.Layout()
+        
+    def _on_spectrum_cb(self, event=None):
+        """
+        On spectrum ComboBox event
+        """
+        if event != None:
+            combo = event.GetEventObject()
+            event.Skip()
+        else:
+            raise
+        selection = self.spectrum_cb.GetValue()
+        if selection == 'Add new':
+            path = self._selectDlg()
+            if path == None:
+                self.spectrum_cb.SetValue('Flat')
+                self.resolution.set_spectrum(self.spectrum_dic['Flat'])
+                msg = "No file has been chosen."
+                wx.MessageBox(msg, 'Info')
+                return
+            try:
+                basename  = os.path.basename(path)
+                if basename not in self.spectrum_dic.keys():
+                    self.spectrum_cb.Append(basename)
+                self.spectrum_dic[basename] = self._read_file(path)
+                self.spectrum_cb.SetValue(basename)
+                self.resolution.set_spectrum(self.spectrum_dic[basename])
+                return
+            except:
+                raise
+                msg = "Failed to load the spectrum data file."
+                wx.MessageBox(msg, 'Warning')
+                raise ValueError, "Invalid spectrum file..."
+        
+        self.resolution.set_spectrum(self.spectrum_dic[selection])
+                             
+    def _selectDlg(self):
+        """
+        open a dialog file to select a customized spectrum
+        """
+        import os
+        dlg = wx.FileDialog(self, 
+                "Choose a wavelength spectrum file: Intensity vs. wavelength",
+                self.parent.parent._default_save_location , "", 
+                "*.*", wx.OPEN)
+        path = None
+        if dlg.ShowModal() == wx.ID_OK:
+            path = dlg.GetPath()
+        dlg.Destroy()
+        return path
+        
+    def _read_file(self, path):
+        """
+        Read two columns file as tuples of numpy array
+        
+        :param path: the path to the file to read
+        
+        """
+        try:
+            if path==None:
+                wx.PostEvent(self.parent.parent, StatusEvent(status=\
+                            " Selected Distribution was not loaded: %s"%path))
+                return None, None
+            input_f = open(path, 'r')
+            buff = input_f.read()
+            lines = buff.split('\n')
+            
+            wavelength = []
+            intensity = []
+            for line in lines:
+                toks = line.split()
+                try:
+                    wave = float(toks[0])
+                    intens = float(toks[1])
+                    wavelength.append(wave)
+                    intensity.append(intens)
+                except:
+                    # Skip non-data lines
+                    pass
+                
+            return [wavelength, intensity]
+        except:
+            raise 
+        
+class ResolutionWindow(wx.Frame):
+    def __init__(self, parent = None, title = "SANS Resolution Estimator",
+                  size=(PANEL_WIDTH * 2, PANEL_HEIGHT), *args, **kwds):
+        kwds['title'] = title
+        kwds['size'] = size
+        wx.Frame.__init__(self, parent=None, *args, **kwds)
+        self.parent = parent
+        self.panel = ResolutionCalculatorPanel(parent=self)
+        self.Centre()
+        self.Show(True)
+        
+if __name__ == "__main__": 
+    app = wx.PySimpleApp()
+    frame = ResolutionWindow()    
+    frame.Show(True)
+    app.MainLoop()     
Index: calculatorview/src/sans/perspectives/calculator/sample_editor.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/sample_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/sample_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,553 @@
+
+import wx
+import sys
+from copy import deepcopy
+from sans.guiframe.utils import check_float
+
+_BOX_WIDTH = 60
+if sys.platform.count("win32") > 0:
+    _STATICBOX_WIDTH = 450
+    PANEL_WIDTH = 500
+    PANEL_HEIGHT = 430
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 480
+    PANEL_WIDTH = 550
+    PANEL_HEIGHT = 430
+    FONT_VARIANT = 1
+    
+class SampleDialog(wx.Dialog):
+    def __init__(self, parent=None, manager=None, sample=None,
+                 size=(PANEL_WIDTH, PANEL_HEIGHT),title='Sample Editor'):
+       
+        wx.Dialog.__init__(self, parent=parent, size=size, title=title)
+        self.parent = parent
+        self.manager = manager 
+        self._sample = sample
+        self._reset_sample = deepcopy(sample)
+        self._notes = ""
+        self._description = "Edit Sample"
+        self._do_layout()
+        self.set_values()
+    
+    def _define_structure(self):
+        """
+            define initial sizer 
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.box_sample = wx.StaticBox(self, -1,str("Sample"))
+        self.boxsizer_sample = wx.StaticBoxSizer(self.box_sample,
+                                                    wx.VERTICAL)
+        self.name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.id_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.thickness_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.transmission_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.temperature_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.position_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.orientation_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.details_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+       
+    def _layout_name(self):
+        """
+            Do the layout for sample name related widgets
+        """
+        ## Short name for sample [string]
+        sample_name_txt = wx.StaticText(self, -1, 'Sample Name : ')  
+        self.sample_name_tcl = wx.TextCtrl(self, -1,
+                                            size=(_BOX_WIDTH*5, 20), style=0) 
+        self.name_sizer.AddMany([(sample_name_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                       (self.sample_name_tcl, 0, wx.EXPAND)])
+    def _layout_id(self):
+        """
+            Do the layout for id related widgets
+        """
+        ## ID [String]
+        id_txt = wx.StaticText(self, -1, 'ID: ')  
+        self.id_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20), style=0)
+        self.id_sizer.AddMany([(id_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.id_tcl, 0, wx.LEFT, 55)])
+        
+    def _layout_thickness(self):
+        """
+            Do the  layout for thickness related widgets
+        """
+        ## Thickness [float] [mm]
+        thickness_txt = wx.StaticText(self, -1, 'Thickness:') 
+        self.thickness_tcl = wx.TextCtrl(self, -1,
+                                          size=(_BOX_WIDTH, 20),style=0)  
+        thickness_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.thickness_unit_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20),
+                                              style=0)  
+        self.thickness_sizer.AddMany([(thickness_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.thickness_tcl, 0, wx.LEFT, 25),
+                            (thickness_unit_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.thickness_unit_tcl, 0, wx.EXPAND)]) 
+    def _layout_transmission(self):
+        """
+            Do the  layout for transmission related widgets
+        """
+        ## Transmission [float] [fraction]
+        transmission = None
+        transmission_txt = wx.StaticText(self, -1, 'Transmission:') 
+        self.transmission_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH, 20),style=0)   
+        self.transmission_sizer.AddMany([(transmission_txt,
+                                         0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.transmission_tcl, 0, wx.LEFT, 12)]) 
+        
+    def _layout_temperature(self):
+        """
+            Do the  layout for temperature related widgets
+        """
+        ## Temperature [float] [C]
+        temperature_txt = wx.StaticText(self, -1, 'Temperature:') 
+        self.temperature_tcl = wx.TextCtrl(self, -1, 
+                                           size=(_BOX_WIDTH, 20), style=0)   
+        temperature_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.temperature_unit_tcl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, 20),
+                                                            style=0)  
+        self.temperature_sizer.AddMany([(temperature_txt, 0,
+                                          wx.LEFT|wx.RIGHT, 10),
+                                     (self.temperature_tcl, 0, wx.LEFT, 10),
+                                (temperature_unit_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.temperature_unit_tcl, 0, wx.EXPAND)])  
+    
+    def _layout_position(self):
+        """
+            Do the  layout for position related widgets
+        """
+        ## Position [Vector] [mm]
+        position_txt = wx.StaticText(self, -1, 'Position:') 
+        x_position_txt = wx.StaticText(self, -1, 'x = ')  
+        self.x_position_tcl = wx.TextCtrl(self, -1,
+                                           size=(_BOX_WIDTH,20), style=0) 
+        y_position_txt = wx.StaticText(self, -1, 'y = ')  
+        self.y_position_tcl = wx.TextCtrl(self, -1,
+                                           size=(_BOX_WIDTH,20), style=0) 
+        z_position_txt = wx.StaticText(self, -1, 'z = ')  
+        self.z_position_tcl = wx.TextCtrl(self, -1,
+                                           size=(_BOX_WIDTH,20), style=0)  
+        position_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.position_unit_tcl = wx.TextCtrl(self, -1, 
+                                             size=(_BOX_WIDTH,20), style=0)  
+        self.position_sizer.AddMany([(position_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (x_position_txt, 0, wx.LEFT, 14),
+                                     (self.x_position_tcl, 0, wx.RIGHT, 10),
+                                     (y_position_txt, 0, wx.EXPAND),
+                                     (self.y_position_tcl, 0, wx.RIGHT, 10),
+                                     (z_position_txt, 0, wx.EXPAND),
+                                     (self.z_position_tcl, 0, wx.RIGHT, 10),
+                                     (position_unit_txt, 0, wx.EXPAND),
+                                     (self.position_unit_tcl, 0, wx.RIGHT, 10)])
+    def _layout_orientation(self):
+        """
+            Do the  layout for orientation related widgets
+        """
+        ## Orientation [Vector] [degrees]
+        orientation_txt = wx.StaticText(self, -1, 'Orientation:') 
+        x_orientation_txt = wx.StaticText(self, -1, 'x = ')  
+        self.x_orientation_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH,20), style=0) 
+        y_orientation_txt = wx.StaticText(self, -1, 'y = ')  
+        self.y_orientation_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH,20), style=0) 
+        z_orientation_txt = wx.StaticText(self, -1, 'z = ')  
+        self.z_orientation_tcl = wx.TextCtrl(self, -1,
+                                              size=(_BOX_WIDTH,20), style=0)  
+        orientation_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.orientation_unit_tcl = wx.TextCtrl(self, -1,
+                                                 size=(_BOX_WIDTH,20), style=0)  
+        self.orientation_sizer.AddMany([(orientation_txt, 0,
+                                          wx.LEFT|wx.RIGHT, 10),
+                                     (x_orientation_txt, 0, wx.LEFT, 0),
+                                     (self.x_orientation_tcl, 0, wx.RIGHT, 10),
+                                     (y_orientation_txt, 0, wx.EXPAND),
+                                     (self.y_orientation_tcl, 0, wx.RIGHT, 10),
+                                     (z_orientation_txt, 0, wx.EXPAND),
+                                     (self.z_orientation_tcl, 0, wx.RIGHT, 10),
+                                     (orientation_unit_txt, 0, wx.EXPAND),
+                            (self.orientation_unit_tcl, 0, wx.RIGHT, 10)])
+        
+    def _layout_details(self):
+        """
+            Do the layout for beam size name related widgets
+        """
+        ## Details
+        details = None
+        details_txt = wx.StaticText(self, -1, 'Details: ')  
+        self.details_tcl = wx.TextCtrl(self, -1,size=(_BOX_WIDTH*5,_BOX_WIDTH),
+                                       style=wx.TE_MULTILINE | wx.HSCROLL)
+        self.details_sizer.AddMany([(details_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                       (self.details_tcl, 0, wx.EXPAND)])
+    
+    def _layout_button(self):  
+        """
+            Do the layout for the button widgets
+        """ 
+        self.bt_apply = wx.Button(self, -1,'Apply')
+        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
+        self.bt_apply.SetToolTipString("Apply current changes to the sample.")
+        self.bt_cancel = wx.Button(self, -1,'Cancel')
+        self.bt_cancel.SetToolTipString("Cancel current changes.")
+        self.bt_cancel.Bind(wx.EVT_BUTTON, self.on_click_cancel)
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.SetToolTipString("Close window.")
+        self.button_sizer.AddMany([(self.bt_apply, 0, wx.LEFT, 200),
+                                   (self.bt_cancel, 0, wx.LEFT, 10),
+                                   (self.bt_close, 0, wx.LEFT, 10)])
+        
+    def _do_layout(self, data=None):
+        """
+             Draw the current panel
+        """
+        self._define_structure()
+        self._layout_name()
+        self._layout_id()
+        self._layout_thickness()
+        self._layout_transmission()
+        self._layout_temperature()
+        self._layout_position()
+        self._layout_orientation()
+        self._layout_details()
+        self._layout_button()
+        self.boxsizer_sample.AddMany([(self.name_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.id_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.thickness_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.transmission_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.temperature_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.position_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                    (self.orientation_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.details_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.main_sizer.AddMany([(self.boxsizer_sample, 0, wx.ALL, 10),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+    
+    def reset_sample(self):
+        """
+            Put initial values of the sample back to the current sample
+        """
+        self._sample.name = self._reset_sample.name
+        self._sample.ID = self._reset_sample.ID
+        self._sample.thickness = self._reset_sample.thickness
+        self._sample.thickness_unit = self._reset_sample.thickness_unit
+        self._sample.transmission = self._reset_sample.transmission
+        self._sample.temperature = self._reset_sample.temperature
+        self._sample.temperature_unit = self._reset_sample.temperature_unit
+       
+        self._sample.position.x = self._reset_sample.position.x
+        self._sample.position.y = self._reset_sample.position.y
+        self._sample.position.z = self._reset_sample.position.x
+        self._sample.position_unit = self._reset_sample.position_unit
+        
+        self._sample.orientation.x = self._reset_sample.orientation.x
+        self._sample.orientation.y = self._reset_sample.orientation.y
+        self._sample.orientation.z = self._reset_sample.orientation.x
+        self._sample.orientation_unit = self._reset_sample.orientation_unit
+       
+        self._sample.details = self._reset_sample.details
+        
+    def set_manager(self, manager):
+        """    
+            Set manager of this window
+        """
+        self.manager = manager
+    
+    def set_values(self):
+        """
+            take the sample values of the current data and display them
+            through the panel
+        """
+        sample = self._sample
+        #Name
+        self.sample_name_tcl.SetValue(str(sample.name))
+        #id 
+        self.id_tcl.SetValue(str(sample.ID))
+        #thickness
+        self.thickness_tcl.SetValue(str(sample.thickness))
+        self.thickness_unit_tcl.SetValue(str(sample.thickness_unit))
+        #transmission
+        self.transmission_tcl.SetValue(str(sample.transmission))
+        #temperature
+        self.temperature_tcl.SetValue(str(sample.temperature))
+        self.temperature_unit_tcl.SetValue(str(sample.temperature_unit))
+        #position
+        x, y, z = sample.position.x, sample.position.y , sample.position.z
+        self.x_position_tcl.SetValue(str(x))  
+        self.y_position_tcl.SetValue(str(y)) 
+        self.z_position_tcl.SetValue(str(z))  
+        self.position_unit_tcl.SetValue(str(sample.position_unit))
+        #orientation
+        x, y = sample.orientation.x, sample.orientation.y 
+        z = sample.orientation.z
+        self.x_orientation_tcl.SetValue(str(x))  
+        self.y_orientation_tcl.SetValue(str(y)) 
+        self.z_orientation_tcl.SetValue(str(z))  
+        self.orientation_unit_tcl.SetValue(str(sample.orientation_unit))
+        
+        self.set_details(sample)
+        
+    def set_details(self, sample):
+        """
+            print details on the current sample
+        """
+        #detail
+        msg = ''
+        if sample.details is not None or sample.details:
+            for item in sample.details:
+                msg += "      %s\n" % item
+        self.details_tcl.SetValue(str(msg))
+        
+    def get_sample(self):
+        """
+            return the current sample
+        """
+        return self._sample
+    
+    def get_notes(self):
+        """
+            return notes
+        """
+        return self._notes
+    
+    def on_change_name(self):
+        """
+            Change name
+        """
+        #Change the name of the sample
+        name = self.sample_name_tcl.GetValue().lstrip().rstrip()
+        if name == "" or name == str(None):
+            name = None
+        if self._sample.name != name:
+            self._notes += "Change sample 's "
+            self._notes += "name from %s to %s \n"%(self._sample.name, name)
+            self._sample.name = name
+            
+    def on_change_id(self):
+        """
+            Change id of the sample 
+        """
+        #Change id
+        id = self.id_tcl.GetValue().lstrip().rstrip()
+        self._sample.ID = id
+        self._notes += " Change ID from"
+        self._notes += " %s to %s \n"%(self._sample.ID, id)
+        
+    def on_change_thickness(self):
+        """
+            Change thickness
+        """
+       #Change thickness
+        thickness = self.thickness_tcl.GetValue().lstrip().rstrip()
+        self._sample.thickness = thickness
+        self._notes += " Change thickness from"
+        self._notes += " %s to %s \n"%(self._sample.thickness, thickness)
+        
+    def on_change_transmission(self):
+        """
+            Change transmission
+        """
+        #Change transmission
+        transmission = self.transmission_tcl.GetValue().lstrip().rstrip()
+        if self._sample.transmission != transmission:
+            self._notes += " Change transmission from"
+            self._notes += " %s to %s \n" % (self._sample.transmission,
+                                              transmission)
+            self._sample.transmission = transmission
+            
+    def on_change_temperature(self):
+        """
+            Change temperature
+        """
+        #Change temperature
+        temperature = self.temperature_tcl.GetValue().lstrip().rstrip()
+        self._sample.temperature = temperature
+        self._notes += " Change temperature from"
+        self._notes += " %s to %s \n"%(self._sample.temperature, temperature)
+        #change temperature unit
+        unit = self.temperature_unit_tcl.GetValue().lstrip().rstrip()
+        if self._sample.temperature_unit != unit:
+            self._notes += " Change temperature's unit from "
+            self._notes += "%s to %s"%(self._sample.temperature_unit, unit)
+            self._sample.temperature_unit = unit
+            
+    def on_change_position(self):
+        """
+            Change position
+        """
+        #Change x coordinate
+        x_position = self.x_position_tcl.GetValue().lstrip().rstrip()
+        if x_position == "" or x_position == str(None):
+            x_position = None
+        else:
+            if check_float(self.x_position_tcl):
+                if self._sample.position.x != float(x_position) :
+                    self._notes += "Change x of position from "
+                    self._notes += "%s to %s \n" % (self._sample.position.x,
+                                                     x_position)
+                    self._sample.position.x  = float(x_position)
+            else:
+                self._notes += "Error: Expected a float for the position 's x "
+                self._notes += "won't changes x position from "
+                self._notes += "%s to %s"%(self._sample.position.x, x_position)
+        #Change y coordinate
+        y_position = self.y_position_tcl.GetValue().lstrip().rstrip()
+        if y_position == "" or y_position == str(None):
+            y_position = None
+            self._sample.position.y = y_position
+        else:
+            if check_float(self.y_position_tcl):
+                if self._sample.position.y != float(y_position):
+                    self._notes += "Change y of position from "
+                    self._notes += "%s to %s \n" % (self._sample.position.y, 
+                                                    y_position)
+                    self._sample.position.y  = float(y_position)
+            else:
+                self._notes += "Error: Expected a float for the beam size's y "
+                self._notes += "won't changes y position from "
+                self._notes += "%s to %s"%(self._sample.position.y, y_position)
+        #Change z coordinate
+        z_position = self.z_position_tcl.GetValue().lstrip().rstrip()
+        if z_position == "" or z_position == str(None):
+            z_position = None
+            self._sample.position.z = z_position
+        else:
+            if check_float(self.z_position_tcl):
+                if self._sample.position.z != float(z_position):
+                    self._notes += "Change z of position from "
+                    self._notes += "%s to %s \n" % (self._sample.position.z,
+                                                    z_position)
+                    self._sample.position.z  = float(z_position)
+            else:
+                self._notes += "Error: Expected a float for position's x "
+                self._notes += "won't changes z position from "
+                self._notes += "%s to %s"%(self._sample.position.z, z_position)
+        #change the beam center unit
+        unit = self.position_unit_tcl.GetValue().lstrip().rstrip()
+        if self._sample.position_unit != unit:
+            self._notes += " Change position's unit from "
+            self._notes += "%s to %s"%(self._sample.position_unit, unit)
+            
+    def on_change_orientation(self):
+        """
+            Change orientation
+        """
+        #Change x coordinate
+        x_orientation = self.x_orientation_tcl.GetValue().lstrip().rstrip()
+        if x_orientation == "" or x_orientation == str(None):
+            x_orientation = None
+        else:
+            if check_float(self.x_orientation_tcl):
+                if self._sample.orientation.x != float(x_orientation) :
+                    self._notes += "Change x of orientation from "
+                    self._notes += "%s to %s \n"%(self._sample.orientation.x,
+                                                   x_orientation)
+                    self._sample.orientation.x  = float(x_orientation)
+            else:
+                self._notes += "Error: Expected a float for orientation 's x "
+                self._notes += "won't changes x orientation from "
+                self._notes += "%s to %s" % (self._sample.orientation.x,
+                                              x_orientation)
+        #Change y coordinate
+        y_orientation = self.y_orientation_tcl.GetValue().lstrip().rstrip()
+        if y_orientation == "" or y_orientation == str(None):
+            y_orientation = None
+            self._sample.orientation.y = y_orientation
+        else:
+            if check_float(self.y_orientation_tcl):
+                if self._sample.orientation.y != float(y_orientation):
+                    self._notes += "Change y of orientation from "
+                    self._notes += "%s to %s \n" % (self._sample.orientation.y,
+                                                     y_orientation)
+                    self._sample.orientation.y  = float(y_orientation)
+            else:
+                self._notes += "Error: Expected a float for orientation's y "
+                self._notes += "won't changes y orientation from "
+                self._notes += "%s to %s" % (self._sample.orientation.y,
+                                            y_orientation)
+        #Change z coordinate
+        z_orientation = self.z_orientation_tcl.GetValue().lstrip().rstrip()
+        if z_orientation == "" or z_orientation == str(None):
+            z_orientation = None
+            self._sample.orientation.z = z_orientation
+        else:
+            if check_float(self.z_orientation_tcl):
+                if self._sample.orientation.z != float(z_orientation):
+                    self._notes += "Change z of orientation from "
+                    self._notes += "%s to %s \n" % (self._sample.orientation.z,
+                                                     z_orientation)
+                    self._sample.orientation.z = float(z_orientation)
+            else:
+                self._notes += "Error: Expected a float for orientation 's x "
+                self._notes += "won't changes z orientation from "
+                self._notes += "%s to %s" % (self._sample.orientation.z,
+                                              z_orientation)
+        #change the beam center unit
+        unit = self.orientation_unit_tcl.GetValue().lstrip().rstrip()
+        if self._sample.orientation_unit != unit:
+            self._notes += " Change orientation's unit from "
+            self._notes += "%s to %s"%(self._sample.orientation_unit, unit)
+            
+    def on_change_details(self):
+        """
+            Change details
+        """
+        #Change details
+        details = self.details_tcl.GetValue().lstrip().rstrip()
+        msg = ""
+        if self._sample.details is not None or self._sample.details:
+            for item in self._sample.details:
+                if item != details:
+                    msg += "      %s\n" % item
+                    self._notes += " Change details from"
+                    self._notes += " %s to %s \n"%(msg, details)
+                    self._sample.details.append(details)
+  
+    def on_click_apply(self, event):
+        """
+            Apply user values to the sample
+        """
+        self.on_change_name()
+        self.on_change_id()
+        self.on_change_thickness()
+        self.on_change_transmission()
+        self.on_change_temperature()
+        self.on_change_position()
+        self.on_change_orientation()
+        self.on_change_details()
+        self.set_details(self._sample)
+        if self.manager is not None:
+            self.manager.set_sample(self._sample)
+        if event is not None:
+            event.Skip()
+            
+    def on_click_cancel(self, event):
+        """
+            leave the sample as it is and close
+        """
+        self.reset_sample()
+        self.set_values()
+        if self.manager is not None:
+             self.manager.set_sample(self._sample, self._notes)
+        if event is not None:
+            event.Skip()
+
+if __name__ == "__main__":
+    app = wx.App()
+    from DataLoader.data_info import Sample
+    sample = Sample()
+    dlg = SampleDialog(sample=sample)
+    dlg.ShowModal()
+    app.MainLoop()
+ 
Index: calculatorview/src/sans/perspectives/calculator/sld_panel.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/sld_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/sld_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,467 @@
+"""
+This module provide GUI for the neutron scattering length density calculator
+
+"""
+
+import wx
+import math
+import sys
+
+from sans.guiframe.panel_base import PanelBase
+
+from sans.guiframe.utils import format_number
+from sans.guiframe.utils import check_float
+from sans.guiframe.events import StatusEvent  
+
+# the calculator default value for wavelength is 6
+#import periodictable
+from periodictable import formula
+from periodictable.xsf import xray_energy
+from periodictable.xsf import xray_sld_from_atoms
+from periodictable.nsf import neutron_scattering
+       
+WAVELENGTH = 6.0
+_BOX_WIDTH = 76
+_STATICBOX_WIDTH = 350
+_SCALE = 1e-6
+
+#SLD panel size 
+if sys.platform.count("win32") > 0:
+    _STATICBOX_WIDTH = 350
+    PANEL_SIZE = 400
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 380
+    PANEL_SIZE = 410
+    FONT_VARIANT = 1
+    
+class SldPanel(wx.Panel, PanelBase):
+    """
+    Provides the SLD calculator GUI.
+    """
+    ## Internal nickname for the window, used by the AUI manager
+    window_name = "SLD Calculator"
+    ## Name to appear on the window title bar
+    window_caption = "SLD Calculator"
+    ## Flag to tell the AUI manager to put this panel in the center pane
+    CENTER_PANE = True
+    
+    def __init__(self, parent, base=None, *args, **kwds):
+        """
+        """
+        wx.Panel.__init__(self, parent, *args, **kwds)
+        PanelBase.__init__(self)
+        #Font size 
+        self.SetWindowVariant(variant=FONT_VARIANT)
+        # Object that receive status event
+        self.base = base
+        self.wavelength = WAVELENGTH
+        #layout attribute
+        self.compound_ctl = None
+        self.density_ctl = None
+        self.wavelength_ctl = None
+        self.neutron_sld_real_ctl = None
+        self.neutron_sld_im_ctl = None
+        self.mo_ka_sld_real_ctl = None
+        self.mo_ka_sld_im_ctl = None
+        self.cu_ka_sld_real_ctl = None
+        self.cu_ka_sld_im_ctl = None
+        self.neutron_abs_ctl = None
+        self.neutron_inc_ctl = None
+        self.neutron_length_ctl = None
+        self.button_calculate = None
+        #Draw the panel
+        self._do_layout()
+        self.SetAutoLayout(True)
+        self.Layout()
+       
+    def _do_layout(self):
+        """
+        Draw window content
+        """
+        unit_a = '[A]'
+        unit_density = '[g/cm^(3)]'
+        unit_sld = '[1/A^(2)]'
+        unit_cm1 = '[1/cm]'
+        unit_cm = '[cm]'
+        sizer_input = wx.GridBagSizer(5, 5)
+        sizer_output = wx.GridBagSizer(5, 5)
+        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
+        sizer1 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer2 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer3 = wx.BoxSizer(wx.HORIZONTAL)
+        #---------inputs----------------
+        inputbox = wx.StaticBox(self, -1, "Input")
+        boxsizer1 = wx.StaticBoxSizer(inputbox, wx.VERTICAL)
+        boxsizer1.SetMinSize((_STATICBOX_WIDTH, -1))
+        
+        compound_txt = wx.StaticText(self, -1, 'Compound ')
+        self.compound_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1))
+        density_txt = wx.StaticText(self, -1, 'Density ')
+        self.density_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1))
+        unit_density_txt = wx.StaticText(self, -1, unit_density)
+        wavelength_txt = wx.StaticText(self, -1, 'Wavelength ')
+        self.wavelength_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1))
+        self.wavelength_ctl.SetValue(str(self.wavelength))
+        unit_a_txt = wx.StaticText(self, -1, unit_a)
+        iy = 0
+        ix = 0
+        sizer_input.Add(compound_txt, (iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_input.Add(self.compound_ctl, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        iy += 1
+        ix = 0
+        sizer_input.Add(density_txt, (iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_input.Add(self.density_ctl, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix +=1
+        sizer_input.Add(unit_density_txt,(iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        iy += 1
+        ix = 0
+        sizer_input.Add(wavelength_txt, (iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_input.Add(self.wavelength_ctl, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix += 1
+        sizer_input.Add(unit_a_txt, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        boxsizer1.Add(sizer_input)
+        sizer1.Add(boxsizer1, 0, wx.EXPAND | wx.ALL, 10)
+        #---------Outputs sizer--------
+        outputbox = wx.StaticBox(self, -1, "Output")
+        boxsizer2 = wx.StaticBoxSizer(outputbox, wx.VERTICAL)
+        boxsizer2.SetMinSize((_STATICBOX_WIDTH, -1))
+        
+        i_complex = '- i'
+        neutron_sld_txt = wx.StaticText(self, -1, 'Neutron SLD')
+        self.neutron_sld_real_ctl = wx.TextCtrl(self, -1,
+                                                 size=(_BOX_WIDTH, -1))
+        self.neutron_sld_real_ctl.SetEditable(False)
+        self.neutron_sld_real_ctl.SetToolTipString("Neutron SLD real.")
+        self.neutron_sld_im_ctl = wx.TextCtrl(self, -1, 
+                                              size=(_BOX_WIDTH, -1))
+        self.neutron_sld_im_ctl.SetEditable(False)
+        self.neutron_sld_im_ctl.SetToolTipString("Neutron SLD imaginary.")
+        neutron_sld_units_txt = wx.StaticText(self, -1, unit_sld)
+        
+        cu_ka_sld_txt = wx.StaticText(self, -1, 'Cu Ka SLD')
+        self.cu_ka_sld_real_ctl = wx.TextCtrl(self, -1,
+                                               size=(_BOX_WIDTH, -1))
+        self.cu_ka_sld_real_ctl.SetEditable(False)
+        self.cu_ka_sld_real_ctl.SetToolTipString("Cu Ka SLD real.")
+        self.cu_ka_sld_im_ctl = wx.TextCtrl(self, -1, 
+                                            size=(_BOX_WIDTH, -1))
+        self.cu_ka_sld_im_ctl.SetEditable(False)
+        self.cu_ka_sld_im_ctl.SetToolTipString("Cu Ka SLD imaginary.")
+        cu_ka_sld_units_txt = wx.StaticText(self, -1, unit_sld)
+        
+        mo_ka_sld_txt = wx.StaticText(self, -1, 'Mo Ka SLD')
+        self.mo_ka_sld_real_ctl = wx.TextCtrl(self, -1,
+                                               size=(_BOX_WIDTH, -1))
+        self.mo_ka_sld_real_ctl.SetEditable(False)
+        self.mo_ka_sld_real_ctl.SetToolTipString("Mo Ka SLD real.")
+        self.mo_ka_sld_im_ctl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH, -1))
+        self.mo_ka_sld_im_ctl.SetEditable(False)
+        self.mo_ka_sld_im_ctl.SetToolTipString("Mo Ka SLD imaginary.")
+        mo_ka_sld_units_txt = wx.StaticText(self, -1, unit_sld)
+        
+        neutron_inc_txt = wx.StaticText(self, -1, 'Neutron Inc. Xs')
+        self.neutron_inc_ctl = wx.TextCtrl(self, -1,
+                                            size=(_BOX_WIDTH, -1))
+        self.neutron_inc_ctl.SetEditable(False)
+        self.neutron_inc_ctl.SetToolTipString("Neutron Inc. Xs")
+        neutron_inc_units_txt = wx.StaticText(self, -1,  unit_cm1)
+       
+        neutron_abs_txt = wx.StaticText(self, -1, 'Neutron Abs. Xs')     
+        self.neutron_abs_ctl = wx.TextCtrl(self, -1, 
+                                           size=(_BOX_WIDTH, -1))
+        self.neutron_abs_ctl.SetEditable(False)
+        self.neutron_abs_ctl.SetToolTipString("Neutron Abs. Xs")
+        neutron_abs_units_txt = wx.StaticText(self, -1,  unit_cm1)
+      
+        neutron_length_txt = wx.StaticText(self, -1, 'Neutron 1/e length')
+        self.neutron_length_ctl = wx.TextCtrl(self, -1,
+                                               size=(_BOX_WIDTH, -1))
+        self.neutron_length_ctl.SetEditable(False)
+        self.neutron_length_ctl.SetToolTipString("Neutron 1/e length")
+        neutron_length_units_txt = wx.StaticText(self, -1,  unit_cm)
+      
+        iy = 0
+        ix = 0
+        sizer_output.Add(neutron_sld_txt, (iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_output.Add(self.neutron_sld_real_ctl, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix += 1
+        sizer_output.Add(wx.StaticText(self, -1, i_complex),
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix += 1
+        sizer_output.Add(self.neutron_sld_im_ctl,
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix += 1
+        sizer_output.Add(neutron_sld_units_txt,
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        iy += 1
+        ix = 0
+        sizer_output.Add(cu_ka_sld_txt, (iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_output.Add(self.cu_ka_sld_real_ctl, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix += 1
+        sizer_output.Add(wx.StaticText(self, -1, i_complex),
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        ix += 1
+        sizer_output.Add(self.cu_ka_sld_im_ctl,
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)  
+        ix += 1
+        sizer_output.Add(cu_ka_sld_units_txt,
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        iy += 1
+        ix = 0
+        sizer_output.Add(mo_ka_sld_txt,(iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_output.Add(self.mo_ka_sld_real_ctl,(iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix += 1
+        sizer_output.Add(wx.StaticText(self, -1, i_complex),
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        ix += 1
+        sizer_output.Add(self.mo_ka_sld_im_ctl,
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)  
+        ix += 1
+        sizer_output.Add(mo_ka_sld_units_txt,
+                         (iy, ix), (1, 1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        iy += 1
+        ix = 0
+        sizer_output.Add(neutron_inc_txt, (iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_output.Add(self.neutron_inc_ctl, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix += 2
+        sizer_output.Add(neutron_inc_units_txt,(iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        iy += 1
+        ix = 0
+        sizer_output.Add(neutron_abs_txt, (iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_output.Add(self.neutron_abs_ctl, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        ix += 2
+        sizer_output.Add(neutron_abs_units_txt, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
+        iy += 1
+        ix = 0
+        sizer_output.Add(neutron_length_txt, (iy, ix), (1, 1),
+                             wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
+        ix += 1
+        sizer_output.Add(self.neutron_length_ctl, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        ix += 2
+        sizer_output.Add(neutron_length_units_txt, (iy, ix), (1, 1),
+                            wx.EXPAND|wx.ADJUST_MINSIZE, 0)  
+        boxsizer2.Add(sizer_output)
+        sizer2.Add(boxsizer2, 0, wx.EXPAND|wx.ALL, 10)
+        #-----Button  sizer------------
+    
+        id = wx.NewId()
+        self.button_calculate = wx.Button(self, id, "Calculate")
+        self.button_calculate.SetToolTipString("Calculate SLD.")
+        self.Bind(wx.EVT_BUTTON, self.calculateSld, id=id)   
+        
+        sizer_button.Add((250, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        sizer_button.Add(self.button_calculate, 0, wx.RIGHT|wx.ADJUST_MINSIZE, 20)
+        sizer3.Add(sizer_button)
+        #---------layout----------------
+        vbox  = wx.BoxSizer(wx.VERTICAL)
+        vbox.Add(sizer1)
+        vbox.Add(sizer2)
+        vbox.Add(sizer3)
+        vbox.Fit(self) 
+        self.SetSizer(vbox)
+        
+    def calculate_xray_sld(self, element):
+        """
+        Get an element and compute the corresponding SLD for a given formula
+        
+        :param element:  elements a string of existing atom
+        
+        """
+        myformula = formula(str(element))
+        if len(myformula.atoms) != 1:
+            return 
+        element = myformula.atoms.keys()[0] 
+        energy = xray_energy(element.K_alpha)
+        
+        self.sld_formula = formula(str(user_formula), density=self.density)
+        atom = self.sld_formula.atoms
+        return xray_sld_from_atoms(atom, density=self.density, energy= energy)
+    
+    def check_inputs(self):
+        """Check validity user inputs"""
+        flag = True
+        msg = ""
+        if check_float(self.density_ctl):
+            self.density = float(self.density_ctl.GetValue())
+        else:
+            flag = False
+            msg += "Error for Density value :expect float"
+    
+        self.wavelength = self.wavelength_ctl.GetValue()
+        if self.wavelength.lstrip().rstrip() == "":
+            self.wavelength = WAVELENGTH
+            self.wavelength_ctl.SetValue(str(WAVELENGTH))
+            self.wavelength_ctl.SetBackgroundColour(wx.WHITE)
+            self.wavelength_ctl.Refresh()
+            msg += "Default value for wavelength is 6.0"
+        else:
+            if check_float(self.wavelength_ctl):
+                self.wavelength = float(self.wavelength)
+            else:
+                flag = False
+                msg += "Error for wavelength value :expect float"
+                
+        self.compound = self.compound_ctl.GetValue().lstrip().rstrip()
+        if self.compound != "":
+            try :
+                formula(self.compound)
+                self.compound_ctl.SetBackgroundColour(wx.WHITE)
+                self.compound_ctl.Refresh()
+            except:
+                self.compound_ctl.SetBackgroundColour("pink")
+                self.compound_ctl.Refresh()
+                flag = False
+                msg += "Enter correct formula"
+        else:
+            self.compound_ctl.SetBackgroundColour("pink")
+            self.compound_ctl.Refresh()
+            flag = False
+            msg += "Enter a formula"
+        return flag, msg
+        
+    def calculate_sld_helper(self, element, density, molecule_formula):
+        """
+        Get an element and compute the corresponding SLD for a given formula
+        
+        :param element:  elements a string of existing atom
+        
+        """
+        element_formula = formula(str(element))
+        if len(element_formula.atoms) != 1:
+            return 
+        element = element_formula.atoms.keys()[0] 
+        energy = xray_energy(element.K_alpha)
+        atom = molecule_formula.atoms
+        return xray_sld_from_atoms(atom, density=density, energy=energy)
+
+
+    def calculateSld(self, event):
+        """
+            Calculate the neutron scattering density length of a molecule
+        """
+        self.clear_outputs()
+        try:
+            #Check validity user inputs
+            flag, msg = self.check_inputs()
+            if self.base is not None and msg.lstrip().rstrip() != "":
+                msg = "SLD Calculator: %s" % str(msg)
+                wx.PostEvent(self.base, StatusEvent(status=msg))
+            if not flag:
+               return 
+            #get ready to compute
+            self.sld_formula = formula(self.compound,
+                                            density=self.density)
+            (sld_real, sld_im, _), (_, absorp, incoh), \
+                        length = neutron_scattering(compound=self.compound,
+                                   density=self.density, 
+                                   wavelength=self.wavelength) 
+            cu_real, cu_im = self.calculate_sld_helper(element="Cu",
+                                                 density=self.density,
+                                        molecule_formula=self.sld_formula)
+            mo_real, mo_im = self.calculate_sld_helper(element="Mo", 
+                                                       density=self.density,
+                                     molecule_formula=self.sld_formula)
+            # set neutron sld values
+            val = format_number(sld_real * _SCALE)
+            self.neutron_sld_real_ctl.SetValue(val)
+            val = format_number(math.fabs(sld_im) * _SCALE)
+            self.neutron_sld_im_ctl.SetValue(val)
+            # Compute the Cu SLD
+            self.cu_ka_sld_real_ctl.SetValue(format_number(cu_real *_SCALE))
+            val = format_number(math.fabs(cu_im )* _SCALE)
+            self.cu_ka_sld_im_ctl.SetValue(val)
+            # Compute the Mo SLD
+            self.mo_ka_sld_real_ctl.SetValue(format_number(mo_real *_SCALE))
+            val = format_number(math.fabs(mo_im)* _SCALE)
+            self.mo_ka_sld_im_ctl.SetValue(val)
+            # set incoherence and absorption
+            self.neutron_inc_ctl.SetValue(format_number(incoh))
+            self.neutron_abs_ctl.SetValue(format_number(absorp))
+            # Neutron length
+            self.neutron_length_ctl.SetValue(format_number(length))
+            # display wavelength
+            self.wavelength_ctl.SetValue(str(self.wavelength))
+        except:
+            if self.base is not None:
+                msg = "SLD Calculator: %s"%(sys.exc_value)
+                wx.PostEvent(self.base, StatusEvent(status=msg))
+        if event is not None:
+            event.Skip()
+            
+    def clear_outputs(self):
+        """
+        Clear the outputs textctrl
+        """
+        self.neutron_sld_real_ctl.SetValue("")
+        self.neutron_sld_im_ctl.SetValue("")
+        self.mo_ka_sld_real_ctl.SetValue("")
+        self.mo_ka_sld_im_ctl.SetValue("")
+        self.cu_ka_sld_real_ctl.SetValue("")
+        self.cu_ka_sld_im_ctl.SetValue("")
+        self.neutron_abs_ctl.SetValue("")
+        self.neutron_inc_ctl.SetValue("")
+        self.neutron_length_ctl.SetValue("")
+        
+        
+class SldWindow(wx.Frame):
+    """
+    """
+    def __init__(self, parent=None, title="SLD Calculator",
+                  base=None, size=(PANEL_SIZE, PANEL_SIZE), *args, **kwds):
+        """
+        """
+        kwds['title'] = title
+        kwds['size'] = size
+        wx.Frame.__init__(self, parent, *args, **kwds)
+        """
+        """
+        self.panel = SldPanel(self, base=base)
+        self.Centre()
+        self.Show(True)
+        
+class ViewApp(wx.App):
+    """
+    """
+    def OnInit(self):
+        """
+        """
+        frame = SldWindow(None, title='SLD Calculator')    
+        frame.Show(True)
+        self.SetTopWindow(frame)
+        return True
+        
+
+if __name__ == "__main__": 
+    app = ViewApp(0)
+    app.MainLoop()     
Index: calculatorview/src/sans/perspectives/calculator/slit_length_calculator_panel.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/slit_length_calculator_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/slit_length_calculator_panel.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,258 @@
+"""
+   This software was developed by the University of Tennessee as part of the
+Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+project funded by the US National Science Foundation. 
+
+See the license text in license.txt
+
+copyright 2008, 2009, University of Tennessee
+"""
+
+import wx
+import sys
+import os
+
+from sans.guiframe.panel_base import PanelBase
+
+from sans.guiframe.events import StatusEvent  
+from sans.calculator.slit_length_calculator import SlitlengthCalculator  
+from calculator_widgets import OutputTextCtrl
+from calculator_widgets import InterActiveOutputTextCtrl
+
+_BOX_WIDTH = 76
+#Slit length panel size 
+if sys.platform.count("win32") > 0:
+    PANEL_WIDTH = 500
+    PANEL_HEIGHT = 200
+    FONT_VARIANT = 0
+else:
+    PANEL_WIDTH = 530
+    PANEL_HEIGHT = 210
+    FONT_VARIANT = 1
+ 
+class SlitLengthCalculatorPanel(wx.Panel, PanelBase):
+    """
+        Provides the slit length calculator GUI.
+    """
+    ## Internal nickname for the window, used by the AUI manager
+    window_name = "Slit Size Calculator"
+    ## Name to appear on the window title bar
+    window_caption = "Slit Size Calculator"
+    ## Flag to tell the AUI manager to put this panel in the center pane
+    CENTER_PANE = True
+    
+    def __init__(self, parent, *args, **kwds):
+        wx.Panel.__init__(self, parent, *args, **kwds)
+        PanelBase.__init__(self)
+        #Font size 
+        self.SetWindowVariant(variant=FONT_VARIANT)
+        #thread to read data 
+        self.reader = None
+        # Default location
+        self._default_save_location = os.getcwd()  
+        # Object that receive status event
+        self.parent = parent
+        self._do_layout()
+       
+    def _define_structure(self):
+        """
+            Define the main sizers building to build this application.
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.box_source = wx.StaticBox(self, -1,str("Slit Size Calculator"))
+        self.boxsizer_source = wx.StaticBoxSizer(self.box_source,
+                                                    wx.VERTICAL)
+        self.data_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.slit_size_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.hint_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+       
+    def _layout_data_name(self):
+        """
+            Fill the sizer containing data's name
+        """
+        data_name_txt = wx.StaticText(self, -1, 'Data: ')
+        self.data_name_tcl = OutputTextCtrl(self, -1, 
+                                            size=(_BOX_WIDTH*4, -1))
+        data_hint = "Loaded data"
+        self.data_name_tcl.SetToolTipString(data_hint)
+        #control that triggers importing data
+        id = wx.NewId()
+        self.browse_button = wx.Button(self, id, "Browse")
+        hint_on_browse = "Click on this button to import data in this panel."
+        self.browse_button.SetToolTipString(hint_on_browse)
+        self.Bind(wx.EVT_BUTTON, self.on_load_data, id=id)
+        self.data_name_sizer.AddMany([(data_name_txt, 0, wx.LEFT, 15),
+                                      (self.data_name_tcl, 0, wx.LEFT, 10),
+                                      (self.browse_button, 0, wx.LEFT, 10)])
+    def _layout_slit_size(self):
+        """
+            Fill the sizer containing slit size information
+        """
+        slit_size_txt = wx.StaticText(self, -1, 'Slit Size (FWHM/2): ')
+        self.slit_size_tcl = InterActiveOutputTextCtrl(self, -1,
+                                                       size=(_BOX_WIDTH, -1))
+        slit_size_hint = " Estimated full slit size"
+        self.slit_size_tcl.SetToolTipString(slit_size_hint)
+        slit_size_unit_txt = wx.StaticText(self, -1, 'Unit: ')
+        self.slit_size_unit_tcl = OutputTextCtrl(self, -1, 
+                                                 size=(_BOX_WIDTH, -1)) 
+        slit_size_unit_hint = "Full slit size's unit"
+        self.slit_size_unit_tcl.SetToolTipString(slit_size_unit_hint)
+        self.slit_size_sizer.AddMany([(slit_size_txt, 0, wx.LEFT, 15),
+                                      (self.slit_size_tcl, 0, wx.LEFT, 10),
+                                      (slit_size_unit_txt, 0, wx.LEFT, 10),
+                                    (self.slit_size_unit_tcl, 0, wx.LEFT, 10)])
+    
+    def _layout_hint(self):
+        """
+            Fill the sizer containing hint 
+        """
+        hint_msg = "This calculation works only for  SAXSess beam profile data."
+        self.hint_txt = wx.StaticText(self, -1, hint_msg)
+        self.hint_sizer.AddMany([(self.hint_txt, 0, wx.LEFT, 15)])
+    
+    def _layout_button(self):  
+        """
+            Do the layout for the button widgets
+        """ 
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.Bind(wx.EVT_BUTTON, self.on_close)
+        self.bt_close.SetToolTipString("Close this window.")
+        self.button_sizer.AddMany([(self.bt_close, 0, wx.LEFT, 390)])
+        
+    def _do_layout(self):
+        """
+            Draw window content
+        """
+        self._define_structure()
+        self._layout_data_name()
+        self._layout_slit_size()
+        self._layout_hint()
+        self._layout_button()
+        self.boxsizer_source.AddMany([(self.data_name_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.slit_size_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                     (self.hint_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.main_sizer.AddMany([(self.boxsizer_source, 0, wx.ALL, 10),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+        
+    def choose_data_file(self, location=None):
+        path = None
+        filename = ''
+        if location == None:
+            location = os.getcwd()
+        
+        wildcard = "SAXSess Data 1D (*.DAT, *.dat)|*.DAT" 
+        
+        dlg = wx.FileDialog(self, "Choose a file", location,
+                            "", wildcard, wx.OPEN)
+        if dlg.ShowModal() == wx.ID_OK:
+            path = dlg.GetPath()
+            filename = os.path.basename(path)
+        dlg.Destroy()
+        
+        return path
+
+    def on_close(self, event):
+        """
+            close the window containing this panel
+        """
+        self.parent.Close()
+        
+    def on_load_data(self, event):
+        """
+            Open a file dialog to allow the user to select a given file.
+            The user is only allow to load file with extension .DAT or .dat.
+            Display the slit size corresponding to the loaded data.
+        """
+        path = self.choose_data_file(location=self._default_save_location)
+        
+        if path is None:
+            return 
+        self._default_save_location = path
+        try:
+            #Load data
+            from load_thread import DataReader
+            ## If a thread is already started, stop it
+            if self.reader is not None and self.reader.isrunning():
+                self.reader.stop()
+            if self.parent.parent is not None:
+                wx.PostEvent(self.parent.parent, 
+                                StatusEvent(status="Loading...",
+                                type="progress"))
+            self.reader = DataReader(path=path,
+                                    completefn=self.complete_loading,
+                                    updatefn=None)
+            self.reader.queue()
+        except:
+            if self.parent.parent is None:
+                return 
+            msg = "Slit Length Calculator: %s" % (sys.exc_value)
+            wx.PostEvent(self.parent.parent,
+                          StatusEvent(status=msg, type='stop'))
+            return 
+            
+    def complete_loading(self, data=None, filename=''):
+        """
+            Complete the loading and compute the slit size
+        """
+        if data is None or data.__class__.__name__ == 'Data2D':
+            if self.parent.parent is None:
+                return 
+            msg = "Slit Length cannot be computed for 2D Data"
+            wx.PostEvent(self.parent.parent, 
+                         StatusEvent(status=msg, type='stop'))
+            return 
+        self.data_name_tcl.SetValue(str(data.filename))
+        #compute the slit size
+        try:
+            x = data.x
+            y = data.y
+            if x == [] or  x is None or y == [] or y is None:
+                msg = "The current data is empty please check x and y"
+                raise ValueError, msg
+            slit_length_calculator = SlitlengthCalculator()
+            slit_length_calculator.set_data(x=x, y=y)
+            slit_length = slit_length_calculator.calculate_slit_length()
+        except:
+            if self.parent.parent is None:
+                return 
+            msg = "Slit Size Calculator: %s" % (sys.exc_value)
+            wx.PostEvent(self.parent.parent,
+                          StatusEvent(status=msg, type='stop'))
+            return 
+        self.slit_size_tcl.SetValue(str(slit_length))
+        #Display unit
+        self.slit_size_unit_tcl.SetValue('[Unknown]')
+        if self.parent.parent is None:
+            return 
+        msg = "Load Complete"
+        wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
+    
+    
+class SlitLengthCalculatorWindow(wx.Frame):
+    """
+    """
+    def __init__(self, parent=None, title="Slit Size Calculator",
+                size=(PANEL_WIDTH,PANEL_HEIGHT), *args, **kwds):
+        """
+        """
+        kwds['size']= size
+        kwds['title']= title
+        wx.Frame.__init__(self, parent, *args, **kwds)
+        self.parent = parent
+        self.panel = SlitLengthCalculatorPanel(parent=self)
+        self.Centre()
+        self.Show(True)
+        
+if __name__ == "__main__": 
+    app = wx.PySimpleApp()
+    frame = SlitLengthCalculatorWindow()    
+    frame.Show(True)
+    app.MainLoop()     
Index: calculatorview/src/sans/perspectives/calculator/source_editor.py
===================================================================
--- calculatorview/src/sans/perspectives/calculator/source_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
+++ calculatorview/src/sans/perspectives/calculator/source_editor.py	(revision 7d45a560fc54369038cd457bd4c8f382c01d9367)
@@ -0,0 +1,541 @@
+"""
+"""
+import wx
+import sys
+from copy import deepcopy
+from sans.guiframe.utils import check_float
+
+_BOX_WIDTH = 60
+if sys.platform.count("win32") > 0:
+    _STATICBOX_WIDTH = 450
+    PANEL_WIDTH = 500
+    PANEL_HEIGHT = 430
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 480
+    PANEL_WIDTH = 550
+    PANEL_HEIGHT = 430
+    FONT_VARIANT = 1
+    
+class SourceDialog(wx.Dialog):
+    def __init__(self, parent=None, manager=None, source=None, *args, **kwds):
+        kwds['title'] = "Source Editor"
+        kwds['size'] = (PANEL_WIDTH, PANEL_HEIGHT)
+        wx.Dialog.__init__(self, parent=parent, *args, **kwds)
+        
+        self.parent = parent
+        self.manager = manager
+        self._source = source
+        self._reset_source = deepcopy(source)
+        self._notes = ""
+        self._description = "Edit source"
+        self._do_layout()
+        self.set_values()
+   
+    def _define_structure(self):
+        """
+            define initial sizer 
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.box_source = wx.StaticBox(self, -1, str("source"))
+        self.boxsizer_source = wx.StaticBoxSizer(self.box_source,
+                                                    wx.VERTICAL)
+        self.name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.radiation_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.beam_shape_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.wavelength_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.wavelength_min_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.wavelength_max_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.wavelength_spread_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.beam_size_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.beam_size_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+       
+    def _layout_name(self):
+        """
+            Do the layout for sample name related widgets
+        """
+        # Sample name [string]
+        sample_name_txt = wx.StaticText(self, -1, 'Sample Name : ')  
+        self.sample_name_tcl = wx.TextCtrl(self, -1,
+                                            size=(_BOX_WIDTH*5, 20), style=0) 
+        self.name_sizer.AddMany([(sample_name_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                       (self.sample_name_tcl, 0, wx.EXPAND)])
+    def _layout_radiation(self):
+        """
+            Do the  layout for  radiation related widgets
+        """
+        #Radiation type [string]
+        radiation_txt = wx.StaticText(self, -1, 'Radiation: ')  
+        self.radiation_tcl = wx.TextCtrl(self, -1, 
+                                         size=(_BOX_WIDTH, 20), style=0)
+        self.radiation_sizer.AddMany([(radiation_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.radiation_tcl, 0, wx.LEFT, 20)])
+        
+    def _layout_beam_shape(self):
+        """
+            Do the  layout for beam shape related widgets
+        """
+        #Beam shape [string]
+        beam_shape_txt = wx.StaticText(self, -1, 'Beam shape:') 
+        self.beam_shape_tcl = wx.TextCtrl(self, -1,
+                                           size=(_BOX_WIDTH, 20), style=0)  
+        self.beam_shape_sizer.AddMany([(beam_shape_txt, 0,
+                                         wx.LEFT|wx.RIGHT, 10),
+                                     (self.beam_shape_tcl, 0, wx.LEFT, 10)])
+        
+    def _layout_wavelength(self):
+        """
+            Do the  layout for wavelength related widgets
+        """
+        #Wavelength [float] [Angstrom]
+        wavelength_txt = wx.StaticText(self, -1, 'wavelength:') 
+        self.wavelength_tcl = wx.TextCtrl(self, -1,
+                                           size=(_BOX_WIDTH, 20), style=0)   
+        wavelength_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.wavelength_unit_tcl = wx.TextCtrl(self, -1,
+                                                size=(_BOX_WIDTH, 20),style=0)  
+        self.wavelength_sizer.AddMany([(wavelength_txt,
+                                         0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.wavelength_tcl, 0, wx.LEFT, 12),
+                            (wavelength_unit_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.wavelength_unit_tcl, 0, wx.EXPAND)]) 
+        
+    def _layout_wavelength_min(self):
+        """
+            Do the  layout for wavelength min related widgets
+        """
+        #Minimum wavelength [float] [Angstrom]
+        wavelength_min_txt = wx.StaticText(self, -1, 'Wavelength min:') 
+        self.wavelength_min_tcl = wx.TextCtrl(self, -1,
+                                               size=(_BOX_WIDTH, 20), style=0)   
+        wavelength_min_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.wavelength_min_unit_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH, 20), style=0)  
+        self.wavelength_min_sizer.AddMany([(wavelength_min_txt, 
+                                            0, wx.LEFT|wx.RIGHT, 10),
+                                     (self.wavelength_min_tcl, 0, wx.LEFT, 10),
+                            (wavelength_min_unit_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                            (self.wavelength_min_unit_tcl, 0, wx.EXPAND)])  
+    
+    def _layout_wavelength_max(self):
+        """
+            Do the  layout for wavelength max related widgets
+        """
+        #Maximum wavelength [float] [Angstrom]
+        wavelength_max_txt = wx.StaticText(self, -1, 'Wavelength max:') 
+        self.wavelength_max_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH, 20), style=0)   
+        wavelength_max_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.wavelength_max_unit_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH, 20), style=0)  
+        self.wavelength_max_sizer.AddMany([(wavelength_max_txt, 0,
+                                             wx.LEFT|wx.RIGHT, 10),
+                                     (self.wavelength_max_tcl, 0, wx.LEFT, 7),
+                            (wavelength_max_unit_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                            (self.wavelength_max_unit_tcl, 0, wx.EXPAND)]) 
+    
+    def _layout_wavelength_spread(self):
+        """
+            Do the  layout for wavelength spread related widgets
+        """
+        ## Wavelength spread [float] [Angstrom]
+        wavelength_spread = None
+        wavelength_spread_unit = 'percent'
+        wavelength_spread_txt = wx.StaticText(self, -1, 'Wavelength spread:') 
+        self.wavelength_spread_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH, 20), style=0)   
+        wavelength_spread_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.wavelength_spread_unit_tcl = wx.TextCtrl(self, -1,
+                                             size=(_BOX_WIDTH, 20), style=0)  
+        self.wavelength_spread_sizer.AddMany([(wavelength_spread_txt,
+                                                0, wx.LEFT, 10),
+                                (self.wavelength_spread_tcl, 0, wx.LEFT, 5),
+                        (wavelength_spread_unit_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                        (self.wavelength_spread_unit_tcl, 0, wx.EXPAND)]) 
+    def _layout_beam_size_name(self):
+        """
+            Do the layout for beam size name related widgets
+        """
+        # Beam size name [string]
+        beam_size_name_txt = wx.StaticText(self, -1, 'Beam size name : ')  
+        self.beam_size_name_tcl = wx.TextCtrl(self, -1,
+                                               size=(_BOX_WIDTH*5, 20), style=0) 
+        self.beam_size_name_sizer.AddMany([(beam_size_name_txt,
+                                             0, wx.LEFT|wx.RIGHT, 10),
+                                       (self.beam_size_name_tcl, 0, wx.EXPAND)])
+        
+    def _layout_beam_size(self):
+        """
+            Do the  layout for beam size related widgets
+        """
+        ## Beam size [Vector] [mm]
+        beam_size = None
+        beam_size_unit = 'mm'
+       
+        beam_size_txt = wx.StaticText(self, -1, 'Beam size:') 
+        x_beam_size_txt = wx.StaticText(self, -1, 'x = ')  
+        self.x_beam_size_tcl = wx.TextCtrl(self, -1,
+                                            size=(_BOX_WIDTH, 20), style=0) 
+        y_beam_size_txt = wx.StaticText(self, -1, 'y = ')  
+        self.y_beam_size_tcl = wx.TextCtrl(self, -1,
+                                            size=(_BOX_WIDTH, 20), style=0) 
+        z_beam_size_txt = wx.StaticText(self, -1, 'z = ')  
+        self.z_beam_size_tcl = wx.TextCtrl(self, -1, 
+                                           size=(_BOX_WIDTH, 20), style=0)  
+        beam_size_unit_txt = wx.StaticText(self, -1, 'Unit: ') 
+        self.beam_size_unit_tcl = wx.TextCtrl(self, -1, 
+                                              size=(_BOX_WIDTH, 20), style=0)  
+        self.beam_size_sizer.AddMany([(beam_size_txt, 0, wx.LEFT|wx.RIGHT, 10),
+                                     (x_beam_size_txt, 0, wx.LEFT, 17),
+                                     (self.x_beam_size_tcl, 0, wx.RIGHT, 10),
+                                     (y_beam_size_txt, 0, wx.EXPAND),
+                                     (self.y_beam_size_tcl, 0, wx.RIGHT, 10),
+                                     (z_beam_size_txt, 0, wx.EXPAND),
+                                     (self.z_beam_size_tcl, 0, wx.RIGHT, 10),
+                                     (beam_size_unit_txt, 0, wx.EXPAND),
+                                    (self.beam_size_unit_tcl, 0, wx.RIGHT, 10)])
+        
+    def _layout_button(self):  
+        """
+            Do the layout for the button widgets
+        """ 
+        self.bt_apply = wx.Button(self, -1,'Apply')
+        self.bt_apply.Bind(wx.EVT_BUTTON, self.on_click_apply)
+        self.bt_apply.SetToolTipString("Apply current changes to the source.")
+        self.bt_cancel = wx.Button(self, -1,'Cancel')
+        self.bt_cancel.SetToolTipString("Cancel current changes.")
+        self.bt_cancel.Bind(wx.EVT_BUTTON, self.on_click_cancel)
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.SetToolTipString("Close window.")
+        self.button_sizer.AddMany([(self.bt_apply, 0, wx.LEFT, 200),
+                                   (self.bt_cancel, 0, wx.LEFT, 10),
+                                   (self.bt_close, 0, wx.LEFT, 10)])
+        
+    def _do_layout(self, data=None):
+        """
+             Draw the current panel
+        """
+        self._define_structure()
+        self._layout_name()
+        self._layout_radiation()
+        self._layout_beam_shape()
+        self._layout_wavelength()
+        self._layout_wavelength_min()
+        self._layout_wavelength_max()
+        self._layout_wavelength_spread()
+        self._layout_beam_size_name()
+        self._layout_beam_size()
+        self._layout_button()
+     
+        self.boxsizer_source.AddMany([(self.name_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.radiation_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.beam_shape_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.wavelength_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.wavelength_min_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.wavelength_max_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                    (self.wavelength_spread_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.beam_size_name_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                    (self.beam_size_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.main_sizer.AddMany([(self.boxsizer_source, 0, wx.ALL, 10),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+    
+    def set_manager(self, manager):
+        """    
+            Set manager of this window
+        """
+        self.manager = manager
+        
+    def reset_source(self):
+        """
+            put back initial values of the source
+        """
+        self._source.name = self._reset_source.name
+        self._source.radiation = self._reset_source.radiation
+        self._source.beam_size_name = self._reset_source.beam_size_name
+       
+        self._source.beam_size.x =  self._reset_source.beam_size.x
+        self._source.beam_size.y =  self._reset_source.beam_size.y
+        self._source.beam_size.z =  self._reset_source.beam_size.z
+        self._source.beam_size_unit = self._reset_source.beam_size_unit
+        
+        self._source.beam_shape = self._reset_source.beam_shape
+        self._source.wavelength = self._reset_source.wavelength
+        self._source.wavelength_unit = self._reset_source.wavelength_unit
+        ## Minimum wavelength [float] [Angstrom]
+        self._source.wavelength_min = self._reset_source.wavelength_min
+        self._source.wavelength_min_unit = self._reset_source.wavelength_min_unit
+        
+        self._source.wavelength_max = self._reset_source.wavelength_max
+        self._source.wavelength_max_unit = self._reset_source.wavelength_max_unit
+        
+        self._source.wavelength_spread = self._reset_source.wavelength_spread
+        self._source.wavelength_spread_unit = self._reset_source.wavelength_spread_unit
+       
+    def set_values(self):
+        """
+            take the source values of the current data and display them
+            through the panel
+        """
+        source = self._source
+        #Name
+        self.sample_name_tcl.SetValue(str(source.name))
+        #Radiation
+        self.radiation_tcl.SetValue(str(source.radiation))
+        #Beam shape 
+        self.beam_shape_tcl.SetValue(str(source.beam_shape))
+        #Wavelength
+        self.wavelength_tcl.SetValue(str(source.wavelength))
+        self.wavelength_unit_tcl.SetValue(str(source.wavelength_unit))
+        #Wavelength min
+        self.wavelength_min_tcl.SetValue(str(source.wavelength_min))
+        self.wavelength_min_unit_tcl.SetValue(str(source.wavelength_min_unit))
+        #Wavelength max
+        self.wavelength_max_tcl.SetValue(str(source.wavelength_max))
+        self.wavelength_max_unit_tcl.SetValue(str(source.wavelength_max_unit))
+        #Wavelength spread
+        self.wavelength_spread_tcl.SetValue(str(source.wavelength_spread))
+        self.wavelength_spread_unit_tcl.SetValue(str(source.wavelength_spread_unit))
+        #Beam size 
+        self.beam_size_name_tcl.SetValue(str(source.beam_size_name))
+        x, y, z = source.beam_size.x, source.beam_size.y , source.beam_size.z
+        self.x_beam_size_tcl.SetValue(str(x))  
+        self.y_beam_size_tcl.SetValue(str(y)) 
+        self.z_beam_size_tcl.SetValue(str(z))  
+        self.beam_size_unit_tcl.SetValue(str(source.beam_size_unit))
+    
+    def get_source(self):
+        """
+            return the current source
+        """
+        return self._source
+    
+    def get_notes(self):
+        """
+            return notes
+        """
+        return self._notes
+    
+    def on_change_name(self):
+        """
+            Change name
+        """
+        #Change the name of the source
+        name = self.sample_name_tcl.GetValue().lstrip().rstrip()
+        if name == "" or name == str(None):
+            name = None
+        if self._source.name != name:
+            self._notes += "Change sample 's "
+            self._notes += "name from %s to %s \n"%(self._source.name, name)
+            self._source.name = name
+            
+    def on_change_radiation(self):
+        """
+            Change radiation of the sample 
+        """
+        #Change radiation
+        radiation = self.radiation_tcl.GetValue().lstrip().rstrip()
+        self._source.radiation = radiation
+        self._notes += " Change radiation from"
+        self._notes += " %s to %s \n"%(self._source.radiation, radiation)
+        
+    def on_change_beam_shape(self):
+        """
+            Change beams shape
+        """
+       #Change beam shape 
+        beam_shape = self.beam_shape_tcl.GetValue().lstrip().rstrip()
+        self._source.beam_shape = beam_shape
+        self._notes += " Change beam shape from"
+        self._notes += " %s to %s \n"%(self._source.beam_shape, beam_shape)
+        
+    def on_change_wavelength(self):
+        """
+            Change the wavelength
+        """
+        #Change wavelength  
+        wavelength = self.wavelength_tcl.GetValue().lstrip().rstrip()
+        self._source.wavelength = wavelength
+        self._notes += " Change wavelength from"
+        self._notes += " %s to %s \n"%(self._source.wavelength, wavelength)
+        #change the wavelength  unit
+        unit = self.wavelength_unit_tcl.GetValue().lstrip().rstrip()
+        if self._source.wavelength_unit != unit:
+            self._notes += " Change wavelength's unit from "
+            self._notes += "%s to %s"%(self._source.wavelength_unit, unit)
+            
+    def on_change_wavelength_min(self):
+        """
+            Change the wavelength minimum
+        """
+        #Change wavelength min
+        wavelength_min = self.wavelength_min_tcl.GetValue().lstrip().rstrip()
+        self._source.wavelength_min = wavelength_min
+        self._notes += " Change wavelength  min from"
+        self._notes += " %s to %s \n" % (self._source.wavelength_min,
+                                          wavelength_min)
+        #change the wavelength min unit
+        unit = self.wavelength_min_unit_tcl.GetValue().lstrip().rstrip()
+        if self._source.wavelength_min_unit != unit:
+            self._notes += " Change wavelength min's unit from "
+            self._notes += "%s to %s" % (self._source.wavelength_min_unit, unit)
+            
+    def on_change_wavelength_max(self):
+        """
+            Change the wavelength maximum
+        """
+        #Change wavelength max
+        wavelength_max = self.wavelength_max_tcl.GetValue().lstrip().rstrip()
+        self._source.wavelength_max = wavelength_max
+        self._notes += " Change wavelength  max from"
+        self._notes += " %s to %s \n" % (self._source.wavelength_max,
+                                        wavelength_max)
+        #change the wavelength max unit
+        unit = self.wavelength_max_unit_tcl.GetValue().lstrip().rstrip()
+        if self._source.wavelength_max_unit != unit:
+            self._notes += " Change wavelength max's unit from "
+            self._notes += "%s to %s"%(self._source.wavelength_max_unit, unit)
+            
+    def on_change_wavelength_spread(self):
+        """
+            Change the wavelength spread
+        """
+        #Change wavelength spread
+        wavelength_spread = self.wavelength_spread_tcl.GetValue().lstrip().rstrip()
+        self._notes += " Change wavelength  spread from"
+        self._notes += " %s to %s \n" % (self._source.wavelength_spread, 
+                                         wavelength_spread)
+        self._source.wavelength_spread = wavelength_spread
+        #change the wavelength spread unit
+        unit = self.wavelength_spread_unit_tcl.GetValue().lstrip().rstrip()
+        if self._source.wavelength_spread_unit != unit:
+            self._notes += " Change wavelength spread's unit from "
+            self._notes += "%s to %s" % (self._source.wavelength_spread_unit, 
+                                         unit)
+            self._source.wavelength_spread_unit = unit
+    
+    def on_change_beam_size_name(self):
+        """
+            Change beam size name
+        """
+        #Change beam size name
+        name = self.beam_size_name_tcl.GetValue().lstrip().rstrip()
+        if name == "" or name == str(None):
+            name = None
+        if self._source.beam_size_name != name:
+            self._notes += "Change beam size  's "
+            self._notes += "name from %s to %s \n" % (self._source.beam_size_name,
+                                                       name)
+            self._source.name = name
+            
+    def on_change_beam_size(self):
+        """
+            Change beam size
+        """
+        #Change x coordinate
+        x_beam_size = self.x_beam_size_tcl.GetValue().lstrip().rstrip()
+        if x_beam_size == "" or x_beam_size == str(None):
+            x_beam_size = None
+        else:
+            if check_float(self.x_beam_size_tcl):
+                if self._source.beam_size.x != float(x_beam_size) :
+                    self._notes += "Change x of beam size from "
+                    self._notes += "%s to %s \n" % (self._source.beam_size.x,
+                                                     x_beam_size)
+                    self._source.beam_size.x  = float(x_beam_size)
+            else:
+                self._notes += "Error: Expected a float for the beam size 's x "
+                self._notes += "won't changes x beam size from "
+                self._notes += "%s to %s" % (self._source.beam_size.x,
+                                            x_beam_size)
+        #Change y coordinate
+        y_beam_size = self.y_beam_size_tcl.GetValue().lstrip().rstrip()
+        if y_beam_size == "" or y_beam_size == str(None):
+            y_beam_size = None
+            self._source.beam_size.y = y_beam_size
+        else:
+            if check_float(self.y_beam_size_tcl):
+                if self._source.beam_size.y != float(y_beam_size):
+                    self._notes += "Change y of beam size from "
+                    self._notes += "%s to %s \n" % (self._source.beam_size.y,
+                                                     y_beam_size)
+                    self._source.beam_size.y  = float(y_beam_size)
+            else:
+                self._notes += "Error: Expected a float for the beam size's y "
+                self._notes += "won't changes y beam size from "
+                self._notes += "%s to %s" % (self._source.beam_size.y,
+                                              y_beam_size)
+        #Change z coordinate
+        z_beam_size = self.z_beam_size_tcl.GetValue().lstrip().rstrip()
+        if z_beam_size == "" or z_beam_size == str(None):
+            z_beam_size = None
+            self._source.beam_size.z = z_beam_size
+        else:
+            if check_float(self.z_beam_size_tcl):
+                if self._source.beam_size.z != float(z_beam_size):
+                    self._notes += "Change z of beam size from "
+                    self._notes += "%s to %s \n" % (self._source.beam_size.z,
+                                                     z_beam_size)
+                    self._source.beam_size.z  = float(z_beam_size)
+            else:
+                self._notes += "Error: Expected a float for the beam size 's z "
+                self._notes += "won't changes z beam size from "
+                self._notes += "%s to %s" % (self._source.beam_size.z,
+                                              z_beam_size)
+        #change the beam center unit
+        unit = self.beam_size_unit_tcl.GetValue().lstrip().rstrip()
+        if self._source.beam_size_unit != unit:
+            self._notes += " Change beam size's unit from "
+            self._notes += "%s to %s"%(self._source.beam_size_unit, unit)
+            self._source.beam_size_unit = unit
+                 
+    def on_click_apply(self, event):
+        """
+        Apply user values to the source
+        """
+        self.on_change_name()
+        self.on_change_radiation()
+        self.on_change_beam_shape()
+        self.on_change_wavelength()
+        self.on_change_wavelength_min()
+        self.on_change_wavelength_max()
+        self.on_change_wavelength_spread()
+        self.on_change_beam_size_name()
+        self.on_change_beam_size()
+        if self.manager is not None:
+            self.manager.set_source(self._source, self._notes)
+        if event is not None:
+            event.Skip()
+        
+    def on_click_cancel(self, event):
+        """
+        reset the current source
+        """
+        self.reset_source()
+        self.set_values()
+        if self.manager is not None:
+            self.manager.set_source(self._source)
+        if event is not None:
+            event.Skip()
+    
+if __name__ =="__main__":
+    app  = wx.App()
+    from DataLoader.data_info import Source
+    source = Source()
+    dlg = SourceDialog(source=source)
+    dlg.ShowModal()
+    app.MainLoop()
+ 
