Index: calculatorview/perspectives/calculator/aperture_editor.py
===================================================================
--- calculatorview/perspectives/calculator/aperture_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
+++ calculatorview/perspectives/calculator/aperture_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
@@ -0,0 +1,374 @@
+
+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):
+        try:
+            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"
+            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_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 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 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.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)
+        
+    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 __name__ =="__main__":
+   
+    app  = wx.App()
+    # Instantiate a loader 
+    loader = Loader()
+    # Load data 
+    data = loader.load("MAR07232_rest.ASC")
+   
+    if len(data.collimation) == 0:
+        from DataLoader.data_info import Collimation
+        collimation = Collimation()
+        from DataLoader.data_info import Aperture
+        aperture = Aperture()
+        dlg = ApertureDialog(aperture=aperture)
+        dlg.ShowModal()
+    else:
+        for collimation in data.collimation:
+            for aperture in collimation:
+                dlg = ApertureDialog(aperture=aperture)
+                dlg.ShowModal()
+                break
+    app.MainLoop()
+ 
Index: calculatorview/perspectives/calculator/calculator.py
===================================================================
--- calculatorview/perspectives/calculator/calculator.py	(revision b50065239ae6bc630acaef4366914ec5a2902760)
+++ calculatorview/perspectives/calculator/calculator.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
@@ -106,10 +106,21 @@
             Returns a set of menu entries for tools
         """
-        sld_help = "Provides computation related to Scattering Length density"
-        slit_length_help = "Provides computation related to Scattering Length density"
+        sld_help = "Provides computation related to Scattering Length Density"
+        slit_length_help = "Provides computation related to Slit Length Density"
+        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)]
+                                self.on_calculate_slit_size),
+                ("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)
+        
     def on_calculate_sld(self, event):
         """
Index: calculatorview/perspectives/calculator/collimation_editor.py
===================================================================
--- calculatorview/perspectives/calculator/collimation_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
+++ calculatorview/perspectives/calculator/collimation_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
@@ -0,0 +1,506 @@
+
+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 = 450
+    PANEL_WIDTH = 530
+    PANEL_HEIGHT = 430
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 480
+    PANEL_WIDTH = 600
+    PANEL_HEIGHT = 480
+    FONT_VARIANT = 1
+    
+class CollimationDialog(wx.Dialog):
+    def __init__(self, parent=None, manager=None,
+                 collimation=[], *args, **kwds):
+        try:
+            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"
+            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_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_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)
+        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")
+        self.bt_remove_collimation.SetToolTipString("Remove data's collimation.")
+        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, data=None):
+        """
+            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() 
+        
+    def remove_collimation(self, event):
+        """
+            Remove collimation to data's list of collimation
+        """
+        if self.collimation_cbox.IsEnabled():
+            if self.collimation_cbox.GetCount() > 1:
+                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)
+                   
+        #disable or enable the combo box when necessary
+        self.enable_collimation()
+        
+    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 available: %s '%str(n_collimation)
+            if len(self._collimation) > 1:
+                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:
+            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:
+            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) > 1:
+                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
+        """
+        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:
+            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.reset_collimation()
+        self.set_values()
+        if self.manager is not None:
+             self.manager.set_collimation(self._collimation)
+       
+ 
+if __name__ =="__main__":
+
+    app  = wx.App()
+    # Instantiate a loader 
+    loader = Loader()
+    # Load data 
+    data = loader.load("MAR07232_rest.ASC")
+    dlg = CollimationDialog(collimation=data.collimation)
+    dlg.ShowModal()
+    app.MainLoop()
+ 
Index: calculatorview/perspectives/calculator/console.py
===================================================================
--- calculatorview/perspectives/calculator/console.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
+++ calculatorview/perspectives/calculator/console.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
@@ -0,0 +1,62 @@
+import wx
+CONSOLE_WIDTH = 340
+CONSOLE_HEIGHT = 240
+
+import wx
+import sys
+from DataLoader.loader import Loader
+
+_BOX_WIDTH = 60
+
+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, id=-1, manager=None, data=None,
+                        title="Data Summary",size=(PANEL_WIDTH, PANEL_HEIGHT)):
+        wx.Dialog.__init__(self, parent=parent, id=id, 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):
+        """
+        """
+        self._manager = manager
+        
+    def set_message(self, msg=""):  
+        """
+        """
+        self.msg_txt.SetValue(str(msg))
+ 
+if __name__ =="__main__":
+   
+    app  = wx.App()
+    # Instantiate a loader 
+    loader = Loader()
+    # Load data 
+    data = loader.load("MAR07232_rest.ASC")
+    dlg = ConsoleDialog(data=data)
+    dlg.ShowModal()
+    app.MainLoop()
Index: calculatorview/perspectives/calculator/data_editor.py
===================================================================
--- calculatorview/perspectives/calculator/data_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
+++ calculatorview/perspectives/calculator/data_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
@@ -0,0 +1,631 @@
+
+import wx
+import sys
+import os 
+from copy import deepcopy
+
+from DataLoader.loader import Loader
+from DataLoader.data_info import DataInfo, Detector, Collimation, Data2D
+from detector_editor import DetectorDialog
+from collimation_editor import CollimationDialog
+from console import ConsoleDialog
+
+from sans.guiframe.utils import check_float
+from sans.guicomm.events import StatusEvent
+
+_BOX_WIDTH = 76
+_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
+    ON_MAC = False
+else:
+    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, 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)) 
+        self.data_run_tcl.Bind(wx.EVT_TEXT_ENTER, self.on_change_run)
+        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*2/3,-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*2/3,-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*2/3,-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*2/3,-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*2/3,-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, data=None):
+        """
+            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:
+            pos = self.data_cbox.Append(str(data.filename))
+            self.data_cbox.SetClientData(pos, data)
+            self.data_cbox.SetSelection(pos)
+            self.data_cbox.SetStringSelection(str(data.filename)) 
+           
+            
+    def reset_panel(self):
+        """
+        """
+        self.enable_data_cbox()
+        self.data_run_tcl.SetValue("")
+        self.data_title_tcl.SetValue("")
+        
+    def on_select_data(self, event=None):
+        """
+        """
+        data, data_name, position = self.get_current_data()
+        self.reset_panel()
+        if data is None:
+            return
+        self.data_title_tcl.SetValue(str(data.title))
+        for item in data.run:
+            self.data_run_tcl.AppendText(str(item))
+            
+    def get_current_data(self):
+        """
+        """
+        if not self.data_cbox.IsEnabled():
+            return None, None, None
+        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, data_name, position = 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, data_name, position = 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(parent, 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(parent, "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._data = []
+        if data is None:
+            msg = "Couldn't load data"
+            wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
+            return 
+        if not  data.__class__.__name__ == "list":
+            self._data.append(data)
+            self._reset_data.append(deepcopy(data))
+        else:
+            self._data = data
+            self._reset_data = deepcopy(data)
+        # set data field
+        self.reset_panel()
+        self.set_values()
+        
+        if self.parent.parent is None:
+            return 
+        msg = "Load Complete"
+        wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
+  
+    def set_values(self):
+        """
+            take the aperture values of the current data and display them
+            through the panel
+        """
+        if self._data == []:
+            return 
+        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
+        """
+        data, data_name, position = self.get_current_data()
+        #Change data's name
+        run = self.data_run_tcl.GetValue().lstrip().rstrip()
+        if run == "":
+            run = []
+        if data.run != run:
+            self._notes += "Change data 's "
+            self._notes += "run from %s to %s \n"%(data.run, str(run))
+            data.run = [run]
+            
+    def on_change_title(self, event=None):
+        """
+            Change title
+        """
+        data, data_name, position = 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
+           
+    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 
+        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:
+            msg = "Data Editor: %s"%(sys.exc_value)
+            load_error(msg)
+            return 
+         
+    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()
+            
+    def on_click_apply(self, event):
+        """   
+            changes are saved in data object imported to edit
+        """
+        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)
+        #must post event here
+        
+    def on_click_save(self, event):
+        """
+            Save change into a file
+        """
+        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)
+        
+        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()   
+            return 
+            
+        path = None
+        wildcard = "CanSAS 1D files(*.xml)|*.xml" 
+        dlg = wx.FileDialog(self, "Choose a file",
+                            self._default_save_location, "",wildcard , wx.SAVE)
+       
+        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()
+        
+    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()
+    
+    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()
+        
+    def on_close(self, event):
+        """
+            leave data as it is and close
+        """
+        self.parent.Close()
+        
+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/perspectives/calculator/detector_editor.py
===================================================================
--- calculatorview/perspectives/calculator/detector_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
+++ calculatorview/perspectives/calculator/detector_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
@@ -0,0 +1,814 @@
+
+import wx
+import sys
+from copy import deepcopy
+from DataLoader.loader import Loader
+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 = 530
+    PANEL_HEIGHT = 450
+    FONT_VARIANT = 1
+    
+class DetectorDialog(wx.Dialog):
+    def __init__(self, parent=None, id=-1, 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, z = detector.orientation.x, detector.orientation.y, 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, z = detector.beam_center.x, detector.beam_center.y, 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, z = detector.pixel_size.x, detector.pixel_size.y, 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 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"
+                    self._notes += "offset from %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 's x "
+                self._notes += "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 y "
+                self._notes += "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 x "
+                self._notes += "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 center 's x "
+                self._notes += "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 center 's y "
+                self._notes += "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 size 's x "
+                self._notes += "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 size's y "
+                self._notes += "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 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()
+    # Instantiate a loader 
+    loader = Loader()
+    # Load data 
+    output = loader.load("MAR07232_rest.ASC")
+    dlg = DetectorDialog(detector=output.detector)
+    dlg.ShowModal()
+    app.MainLoop()
+ 
Index: calculatorview/perspectives/calculator/sample_editor.py
===================================================================
--- calculatorview/perspectives/calculator/sample_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
+++ calculatorview/perspectives/calculator/sample_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
@@ -0,0 +1,530 @@
+
+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 = 430
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 480
+    PANEL_WIDTH = 530
+    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, z = sample.orientation.x, sample.orientation.y , 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)
+       
+    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 __name__ =="__main__":
+    
+    app  = wx.App()
+    # Instantiate a loader 
+    loader = Loader()
+    # Load data 
+    data = loader.load("MAR07232_rest.ASC")
+    #print output
+    dlg = SampleDialog(sample=data.sample)
+    dlg.ShowModal()
+    #print dlg.get_sample()
+    app.MainLoop()
+ 
Index: calculatorview/perspectives/calculator/source_editor.py
===================================================================
--- calculatorview/perspectives/calculator/source_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
+++ calculatorview/perspectives/calculator/source_editor.py	(revision 91f151aa297ca6be7a92ce3c4ba7905d318441cf)
@@ -0,0 +1,506 @@
+
+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 = 430
+    FONT_VARIANT = 0
+else:
+    _STATICBOX_WIDTH = 480
+    PANEL_WIDTH = 530
+    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)
+        
+    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 __name__ =="__main__":
+    app  = wx.App()
+    # Instantiate a loader 
+    loader = Loader()
+    # Load data 
+    data = loader.load("MAR07232_rest.ASC")
+    dlg = SourceDialog(source=data.source)
+    dlg.ShowModal()
+    app.MainLoop()
+ 
