Index: sansview/perspectives/fitting/fitpage1D.py
===================================================================
--- sansview/perspectives/fitting/fitpage1D.py	(revision 8aac6e1163780ad1be33df37f84bc35c8b8dcce4)
+++ sansview/perspectives/fitting/fitpage1D.py	(revision 2268d100cf4d0c2aa066591523a5c8846391f5d0)
@@ -92,8 +92,5 @@
             i+=1
             
-        # Minimum value of data   
-        self.data_min    = wx.StaticText(self, -1,str(format_number(numpy.min(data.x))))
-        # Maximum value of data  
-        self.data_max    =  wx.StaticText(self, -1,str(format_number(numpy.max(data.x))))
+        
         #Filing the sizer containing data related fields
         ix = 0
@@ -110,4 +107,8 @@
         #set maximum range for x in linear scale
         if not hasattr(self.data,"data"): #Display only for 1D data fit
+            # Minimum value of data   
+            self.data_min    = wx.StaticText(self, -1,str(format_number(numpy.min(data.x))))
+            # Maximum value of data  
+            self.data_max    =  wx.StaticText(self, -1,str(format_number(numpy.max(data.x))))   
             self.text4_3 = wx.StaticText(self, -1, 'Maximum Data Range(Linear)', style=wx.ALIGN_LEFT)
             self.sizer2.Add(self.text4_3,(iy,ix),(1,1),\
Index: sansview/perspectives/fitting/fitting.py
===================================================================
--- sansview/perspectives/fitting/fitting.py	(revision 9dd69ec8fca00eabeb05217ade106cccd0d50312)
+++ sansview/perspectives/fitting/fitting.py	(revision 2268d100cf4d0c2aa066591523a5c8846391f5d0)
@@ -92,9 +92,14 @@
             TODO: replace the text with a nice image
         """
-        from helpDialog import  HelpWindow
-        dialog = HelpWindow(None, -1, 'HelpWindow')
-        if dialog.ShowModal() == wx.ID_OK:
-            pass
-        dialog.Destroy()
+        #from helpDialog import  HelpWindow
+        #dialog = HelpWindow(None, -1, 'HelpWindow')
+        #if dialog.ShowModal() == wx.ID_OK:
+        #    pass
+        #dialog.Destroy()
+        from helpPanel import  HelpWindow
+        frame = HelpWindow(None, -1, 'HelpWindow')    
+        frame.Show(True)
+        
+        
         
     
Index: sansview/perspectives/fitting/helpDialog.py
===================================================================
--- sansview/perspectives/fitting/helpDialog.py	(revision b92884a93d3d6730a5b7fb5ff74dc0985709cc36)
+++ 	(revision )
@@ -1,152 +1,0 @@
-#!/usr/bin/python
-import wx
-import wx.html as html
-import os
-def help():
-    """
-        Provide general online help text
-        Future work: extend this function to allow topic selection
-    """
-    info_txt  = "The inversion approach is based on Moore, J. Appl. Cryst. (1980) 13, 168-175.\n\n"
-    info_txt += "P(r) is set to be equal to an expansion of base functions of the type "
-    info_txt += "phi_n(r) = 2*r*sin(pi*n*r/D_max). The coefficient of each base functions "
-    info_txt += "in the expansion is found by performing a least square fit with the "
-    info_txt += "following fit function:\n\n"
-    info_txt += "chi**2 = sum_i[ I_meas(q_i) - I_th(q_i) ]**2/error**2 + Reg_term\n\n"
-    info_txt += "where I_meas(q) is the measured scattering intensity and I_th(q) is "
-    info_txt += "the prediction from the Fourier transform of the P(r) expansion. "
-    info_txt += "The Reg_term term is a regularization term set to the second derivative "
-    info_txt += "d**2P(r)/dr**2 integrated over r. It is used to produce a smooth P(r) output.\n\n"
-    info_txt += "The following are user inputs:\n\n"
-    info_txt += "   - Number of terms: the number of base functions in the P(r) expansion.\n\n"
-    info_txt += "   - Regularization constant: a multiplicative constant to set the size of "
-    info_txt += "the regularization term.\n\n"
-    info_txt += "   - Maximum distance: the maximum distance between any two points in the system.\n"
-     
-    return info_txt
-    
-class HelpDialog(wx.Dialog):
-    def __init__(self, parent, id):
-      
-        wx.Dialog.__init__(self, parent, id, size=(400, 420))
-        self.SetTitle("P(r) help") 
-        
-
-        vbox = wx.BoxSizer(wx.VERTICAL)
-
-        explanation = help()
-           
-        label_explain = wx.StaticText(self, -1, explanation, size=(350,320))
-            
-        vbox.Add(label_explain, 0, wx.ALL|wx.EXPAND, 15)
-
-
-        static_line = wx.StaticLine(self, -1)
-        vbox.Add(static_line, 0, wx.EXPAND, 0)
-        
-        button_OK = wx.Button(self, wx.ID_OK, "OK")
-        #button_Cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
-        
-        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
-        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        sizer_button.Add(button_OK, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
-        #sizer_button.Add(button_Cancel, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)        
-        vbox.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
-
-        self.SetSizer(vbox)
-        self.SetAutoLayout(True)
-        
-        self.Layout()
-        self.Centre()
-
-class HelpWindow(wx.Dialog):
-    def __init__(self, parent, id, title):
-        wx.Dialog.__init__(self, parent, id, title, size=(600, 450))
-        
-        vbox1  = wx.BoxSizer(wx.HORIZONTAL)
-        
-        lpanel = wx.Panel(self, -1, style=wx.BORDER_SUNKEN)
-        rpanel = wx.Panel(self, -1)
-        vbox1.Add(lpanel, -1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        vbox1.Add(rpanel, -1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        
-        vbox = wx.BoxSizer(wx.VERTICAL)
-        header = wx.Panel(rpanel, -1, size=(-1, 20))
-        header.SetBackgroundColour('#6666FF')
-        header.SetForegroundColour('WHITE')
-        hbox = wx.BoxSizer(wx.HORIZONTAL)
-        st = wx.StaticText(header, -1, '', (5, 5))
-        font = st.GetFont()
-        font.SetPointSize(10)
-        st.SetFont(font)
-        hbox.Add(st, 1, wx.TOP | wx.BOTTOM | wx.LEFT, 5)
-        header.SetSizer(hbox)
-        vbox.Add(header, 0, wx.EXPAND)
-       
-        vboxl= wx.BoxSizer(wx.VERTICAL)
-        headerl = wx.Panel(lpanel, -1, size=(-1, 20))
-       
-        headerl.SetBackgroundColour('#6666FF')
-        headerl.SetForegroundColour('WHITE')
-        hboxl = wx.BoxSizer(wx.HORIZONTAL)
-        lst = wx.StaticText(headerl, -1, 'Contents', (5, 5))
-        fontl = lst.GetFont()
-        fontl.SetPointSize(10)
-        lst.SetFont(fontl)
-        hboxl.Add(lst, 1, wx.TOP | wx.BOTTOM | wx.LEFT, 5)
-        headerl.SetSizer(hboxl)
-        vboxl.Add(headerl, 0, wx.EXPAND)
-        self.lhelp = html.HtmlWindow(lpanel, -1, style=wx.NO_BORDER)
-        self.rhelp = html.HtmlWindow(rpanel, -1, style=wx.NO_BORDER)
-       
-        page="""<html>
-            <body>
-            <ul>
-            <li><a href ="doc/change_scale_help.html" target ="showframe">Change scale</a><br></li>
-            <li><a href ="doc/reset_Graph_help.html" target ="showframe">Graph Help</a><br></li>
-            <li><a href ="doc/load_data_help.html" target ="showframe">Load a File</a><br></li>
-            <li><a href ="doc/simultaneous_fit_help.html" target ="showframe">Simultaneous Fit</a><br></li>
-            <li><a href ="doc/single_fit_help.html" target ="showframe">Single Fit</a><br></li>
-            <li><a href ="doc/model_use_help.html" target ="showframe">Visualize Model</a><br></li>
-            </ul>
-            </body>
-            </html>"""
-       
-        self.lhelp.SetPage(page)
-        self.lhelp.Bind(wx.html.EVT_HTML_LINK_CLICKED,self.OnLinkClicked )
-        vbox.Add(self.rhelp, 1, wx.EXPAND)
-        vboxl.Add(self.lhelp, 1, wx.EXPAND)
-        rpanel.SetSizer(vbox)
-        lpanel.SetSizer(vboxl)
-        lpanel.SetFocus()
-        
-        self.SetSizer(vbox1)
-        
-        self.Centre()
-        self.Show(True)
-    def OnLinkClicked(self, event):
-        """
-            Function to diplay html page related to the hyperlinktext selected
-        """
-        link= event.GetLinkInfo().GetHref()
-        self.rhelp.LoadPage(link)
-
-
-class MyApp(wx.App):
-    def OnInit(self):
-        
-        dialog = HelpWindow(None, -1, 'HelpWindow')
-        if dialog.ShowModal() == wx.ID_OK:
-            pass
-        dialog.Destroy()
-        
-        return 1
-   
-
-# end of class MyApp
-
-if __name__ == "__main__":
-    app = MyApp(0)
-    app.MainLoop()
-
-
Index: sansview/perspectives/fitting/helpPanel.py
===================================================================
--- sansview/perspectives/fitting/helpPanel.py	(revision 2268d100cf4d0c2aa066591523a5c8846391f5d0)
+++ sansview/perspectives/fitting/helpPanel.py	(revision 2268d100cf4d0c2aa066591523a5c8846391f5d0)
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+import wx
+import wx.html as html
+import os
+def help():
+    """
+        Provide general online help text
+        Future work: extend this function to allow topic selection
+    """
+    info_txt  = "The inversion approach is based on Moore, J. Appl. Cryst. (1980) 13, 168-175.\n\n"
+    info_txt += "P(r) is set to be equal to an expansion of base functions of the type "
+    info_txt += "phi_n(r) = 2*r*sin(pi*n*r/D_max). The coefficient of each base functions "
+    info_txt += "in the expansion is found by performing a least square fit with the "
+    info_txt += "following fit function:\n\n"
+    info_txt += "chi**2 = sum_i[ I_meas(q_i) - I_th(q_i) ]**2/error**2 + Reg_term\n\n"
+    info_txt += "where I_meas(q) is the measured scattering intensity and I_th(q) is "
+    info_txt += "the prediction from the Fourier transform of the P(r) expansion. "
+    info_txt += "The Reg_term term is a regularization term set to the second derivative "
+    info_txt += "d**2P(r)/dr**2 integrated over r. It is used to produce a smooth P(r) output.\n\n"
+    info_txt += "The following are user inputs:\n\n"
+    info_txt += "   - Number of terms: the number of base functions in the P(r) expansion.\n\n"
+    info_txt += "   - Regularization constant: a multiplicative constant to set the size of "
+    info_txt += "the regularization term.\n\n"
+    info_txt += "   - Maximum distance: the maximum distance between any two points in the system.\n"
+     
+    return info_txt
+    
+class HelpDialog(wx.Dialog):
+    def __init__(self, parent, id):
+      
+        wx.Dialog.__init__(self, parent, id, size=(400, 420))
+        self.SetTitle("P(r) help") 
+        
+
+        vbox = wx.BoxSizer(wx.VERTICAL)
+
+        explanation = help()
+           
+        label_explain = wx.StaticText(self, -1, explanation, size=(350,320))
+            
+        vbox.Add(label_explain, 0, wx.ALL|wx.EXPAND, 15)
+
+
+        static_line = wx.StaticLine(self, -1)
+        vbox.Add(static_line, 0, wx.EXPAND, 0)
+        
+        button_OK = wx.Button(self, wx.ID_OK, "OK")
+        #button_Cancel = wx.Button(self, wx.ID_CANCEL, "Cancel")
+        
+        sizer_button = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_button.Add((20, 20), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        sizer_button.Add(button_OK, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)
+        #sizer_button.Add(button_Cancel, 0, wx.LEFT|wx.RIGHT|wx.ADJUST_MINSIZE, 10)        
+        vbox.Add(sizer_button, 0, wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
+
+        self.SetSizer(vbox)
+        self.SetAutoLayout(True)
+        
+        self.Layout()
+        self.Centre()
+
+class HelpWindow(wx.Frame):
+    def __init__(self, parent, id, title):
+        wx.Frame.__init__(self, parent, id, title, size=(600, 450))
+        
+        vbox1  = wx.BoxSizer(wx.HORIZONTAL)
+        
+        lpanel = wx.Panel(self, -1, style=wx.BORDER_SUNKEN)
+        rpanel = wx.Panel(self, -1)
+        vbox1.Add(lpanel, -1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        vbox1.Add(rpanel, -1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        
+        vbox = wx.BoxSizer(wx.VERTICAL)
+        header = wx.Panel(rpanel, -1, size=(-1, 20))
+        header.SetBackgroundColour('#6666FF')
+        header.SetForegroundColour('WHITE')
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        st = wx.StaticText(header, -1, 'Contents', (5, 5))
+        font = st.GetFont()
+        font.SetPointSize(10)
+        st.SetFont(font)
+        hbox.Add(st, 1, wx.TOP | wx.BOTTOM | wx.LEFT, 5)
+        header.SetSizer(hbox)
+        vbox.Add(header, 0, wx.EXPAND)
+       
+        vboxl= wx.BoxSizer(wx.VERTICAL)
+        headerl = wx.Panel(lpanel, -1, size=(-1, 20))
+       
+        headerl.SetBackgroundColour('#6666FF')
+        headerl.SetForegroundColour('WHITE')
+        hboxl = wx.BoxSizer(wx.HORIZONTAL)
+        lst = wx.StaticText(headerl, -1, 'Menu', (5, 5))
+        fontl = lst.GetFont()
+        fontl.SetPointSize(10)
+        lst.SetFont(fontl)
+        hboxl.Add(lst, 1, wx.TOP | wx.BOTTOM | wx.LEFT, 5)
+        headerl.SetSizer(hboxl)
+        vboxl.Add(headerl, 0, wx.EXPAND)
+        self.lhelp = html.HtmlWindow(lpanel, -1, style=wx.NO_BORDER)
+        self.rhelp = html.HtmlWindow(rpanel, -1, style=wx.NO_BORDER)
+        page1="""<html>
+            <body>
+             <p>Select topic on Menu</p>
+            </body>
+            </html>"""
+        page="""<html>
+            <body>
+            <ul>
+            <li><a href ="doc/change_scale_help.html" target ="showframe">Change scale</a><br></li>
+            <li><a href ="doc/reset_Graph_help.html" target ="showframe">Graph Help</a><br></li>
+            <li><a href ="doc/load_data_help.html" target ="showframe">Load a File</a><br></li>
+            <li><a href ="doc/simultaneous_fit_help.html" target ="showframe">Simultaneous Fit</a><br></li>
+            <li><a href ="doc/single_fit_help.html" target ="showframe">Single Fit</a><br></li>
+            <li><a href ="doc/model_use_help.html" target ="showframe">Visualize Model</a><br></li>
+            <li><a href ="doc/averaging_help.html" target ="showframe">Data Averaging</a><br></li>
+            </ul>
+            </body>
+            </html>"""
+        self.rhelp.SetPage(page1)
+        self.lhelp.SetPage(page)
+        self.lhelp.Bind(wx.html.EVT_HTML_LINK_CLICKED,self.OnLinkClicked )
+        vbox.Add(self.rhelp, 1, wx.EXPAND)
+        vboxl.Add(self.lhelp, 1, wx.EXPAND)
+        rpanel.SetSizer(vbox)
+        lpanel.SetSizer(vboxl)
+        lpanel.SetFocus()
+        
+        self.SetSizer(vbox1)
+        
+        self.Centre()
+        self.Show(True)
+    def OnLinkClicked(self, event):
+        """
+            Function to diplay html page related to the hyperlinktext selected
+        """
+        link= event.GetLinkInfo().GetHref()
+        self.rhelp.LoadPage(link)
+
+class ViewApp(wx.App):
+    def OnInit(self):
+        frame = HelpWindow(None, -1, 'HelpWindow')    
+        frame.Show(True)
+        self.SetTopWindow(frame)
+        
+        return True
+        
+
+if __name__ == "__main__": 
+    app = ViewApp(0)
+    app.MainLoop()     
Index: sansview/perspectives/fitting/state.py
===================================================================
--- sansview/perspectives/fitting/state.py	(revision 2268d100cf4d0c2aa066591523a5c8846391f5d0)
+++ sansview/perspectives/fitting/state.py	(revision 2268d100cf4d0c2aa066591523a5c8846391f5d0)
@@ -0,0 +1,258 @@
+"""
+    Object to manage the state of the application
+"""
+
+#TODO: use both CPUs and break the calculations in two threads
+#TODO: stop threads before starting a new one
+
+import wx
+import wx.lib.newevent
+
+#import ModelParameters
+#import history
+import modelData
+from model_thread import Calc2D, Calc1D, Calc2D_4fold, Calc2D_all
+from copy import deepcopy
+
+#TODO: State should report back to StateManager instead
+#    of firing these events itself
+(Refresh2DEvent, EVT_2DREFRESH) = wx.lib.newevent.NewEvent()
+(Refresh1DEvent, EVT_1DREFRESH) = wx.lib.newevent.NewEvent()
+
+# Debug printout
+#from config import printEVT
+
+
+
+class State:
+    
+    def __init__(self, target=None,data=None, model=None, slicer=None, panel=None):
+        self.target = target
+        self.model  = model
+        self.data   = data
+        self.type_panel= None
+        self.disp_list = []
+        self.manager = None
+        self.parent  = parent
+        self.event_owner = None
+        self.modelbox = wx.ComboBox(self, -1)
+         # preview selected model name
+        self.prevmodel_name=name
+        #print "model view prev_model",name
+        self.modelbox.SetValue(self.prevmodel_name)
+        #enable model 2D draw
+        self.enable2D= False
+         ## Q range
+        self.qmin_x= 0.001
+        self.qmax_x= 0.1
+        self.num_points= 100
+        self.parameters=[]
+        self.fixed_param=[]
+        self.fittable_param=[]
+        #contains link between a model and selected parameters to fit 
+        self.param_toFit=[]
+        
+        #dictionary of model name and model class
+        self.model_list_box={}
+        #Draw initial panel
+        self.enable_disp= None
+        self.disable_disp=None    
+            
+        if panel !=None:
+            self.panel= panel
+            
+        
+        
+        self.slicer = slicer
+        self.model_par_memento = None
+        self.detector_memento = None
+        self.averager_memento = None
+        self.pars1D_memento   = None
+        
+        # Keep the latest data 
+        self._data_2D = None
+        self._data_1D = None
+        # The following should disappear
+        self.qmax = None
+        self.x_1D = None
+        
+        # Threads
+        self.active = True
+        self.calc_thread_2D = None
+        self.calc_thread_1D = None
+        
+        # Info for history
+        self.description = ''
+    def clone_panel(self):
+        obj          = State(self.target, self.model.clone(),self.panel)
+        obj.data = deepcopy(self.data)
+        
+        
+        
+        
+    def clone(self):
+        obj          = State(self.target, self.model.clone(), self.slicer)
+        obj._data_1D = deepcopy(self._data_1D)
+        obj._data_2D = deepcopy(self._data_2D)
+        obj.qmax     = deepcopy(self.qmax)
+        obj.x_1D     = deepcopy(self.x_1D)
+        obj.model_par_memento = deepcopy(self.model_par_memento)
+        obj.detector_memento = deepcopy(self.detector_memento)
+        obj.averager_memento = deepcopy(self.averager_memento)
+        obj.description = self.description
+        return obj
+        
+    def clear_data(self):
+        self._data_1D = None
+        self._data_2D = None
+        
+    def stop(self):
+        self.active = False
+        if self.calc_thread_1D != None and self.calc_thread_1D.isrunning():
+            self.calc_thread_1D.stop()
+        if self.calc_thread_2D != None and self.calc_thread_2D.isrunning():
+            self.calc_thread_2D.stop()
+        
+    def setModelParMemento(self, memento):
+        self.model_par_memento = memento
+        
+    def setDetectorMemento(self, memento):
+        self.clear_data()
+        # Change description
+        self.description = '%s' % memento.toString(self.detector_memento)
+        self.detector_memento = memento
+        
+    def setPars1DMemento(self, memento):
+        self.clear_data()
+        # Change description
+        self.description = '%s' % memento.toString(self.pars1D_memento)
+        self.pars1D_memento = memento
+        
+    def setAveragerMemento(self, memento):
+        self.clear_data()
+        self.averager_memento = memento
+        
+    def setModel(self, model):
+        """
+            Set the model and send a history event
+        """
+        # Clean the data to invoke recalc
+        self._data_1D = None
+        self._data_2D = None
+        
+        # Set the model 
+        self.model = model
+        
+        self.description = ''
+        
+        return str(self.model.name)
+        
+    def setParams(self, params):
+        """
+            Update parameters and return a name
+            that represents the change (key)
+        """
+        # Clean the data to invoke recalc
+        self._data_1D = None
+        self._data_2D = None
+
+        # Compose string to summarize change        
+        name = self.model.name
+        
+        # Identify and perform changes
+        for item in params:
+            name += "/%s=%-5.5g" % (item, self.model.getParam(item))
+            self.model.setParam(item, params[item])
+        
+        return name
+
+    def setSlicer(self, slicer):
+        self.slicer = slicer
+        
+    def get_data_1d(self, x):
+        """
+            Calculate the data 
+            @param min: minimum q-value
+            @param max: maximum q-value
+        """
+        
+        printEVT("State.get_data_1d")
+        if not self.model:
+            return
+        
+        if self._data_1D == None:
+            self.x_1D = deepcopy(x)
+            if self.calc_thread_1D != None and self.calc_thread_1D.isrunning():
+                self.calc_thread_1D.stop()
+                
+            self.calc_thread_1D = Calc1D(x, self.model.clone(), 
+                                completefn=self.complete1D,
+                                updatefn=self.update1D)
+            self.calc_thread_1D.queue()
+            self.calc_thread_1D.ready(2.5)
+        else:
+            printEVT("Dispatch 1D non-recalc data") 
+            wx.PostEvent(self.target, Refresh1DEvent(name=self.model.name, x = self.x_1D,
+                                                     output=deepcopy(self._data_1D)))
+         
+    
+    def get_data_2d(self, max, x, y):
+        """ 
+            Calculate 2D data
+            @param max: maximum q-value
+        """
+        if not self.model:
+            return
+        
+        if self._data_2D == None:
+            self.qmax = max
+            if self.calc_thread_2D != None and self.calc_thread_2D.isrunning():
+                self.calc_thread_2D.stop()
+                
+            if self.detector_memento == None or self.detector_memento.sym4 == False:    
+                self.calc_thread_2D = Calc2D(x, y, self.model.clone(), 
+                                    completefn=self.complete2D,
+                                    updatefn=self.update2D,
+                                    yieldtime=0.0)
+            else:
+                self.calc_thread_2D = Calc2D_4fold(x, y, self.model.clone(), 
+                                    completefn=self.complete2D,
+                                    updatefn=self.update2D,
+                                    yieldtime=0.0)
+                
+            self.calc_thread_2D.queue()
+            self.calc_thread_2D.ready(2.5)
+        else:
+            print
+            #printEVT("Dispatch 2D non-recalc data") 
+            #wx.PostEvent(self.target, Refresh2DEvent(output=deepcopy(self._data_2D),
+            #                                        qmax=self.qmax))
+            
+             
+    def update2D(self, output):
+        printEVT("State.updated2D")
+        if self.active:
+            #self._data_2D = output
+            self._data_2D = deepcopy(output)
+            wx.PostEvent(self.target, Refresh2DEvent(output=deepcopy(self._data_2D),
+                                                qmax=self.qmax))
+    
+    def complete2D(self, output, elapsed):
+        printEVT("%s: Calc 2D complete in %g sec" % (self.model.name, elapsed)) 
+        if self.active:
+            self._data_2D = deepcopy(output)
+            wx.PostEvent(self.target, Refresh2DEvent(output=deepcopy(self._data_2D),
+                                                qmax=self.qmax))
+        else:
+            printEVT("Active = False!")
+
+    def update1D(self, output):
+        pass
+    
+    def complete1D(self, output, elapsed):
+        printEVT("Calc 1D complete in %g sec" % elapsed) 
+        self._data_1D = deepcopy(output)
+        wx.PostEvent(self.target, Refresh1DEvent(name=self.model.name, x = self.x_1D,
+                                                 output=deepcopy(self._data_1D)))
+
+    
