Index: fittingview/src/sans/perspectives/fitting/fitproblem.py
===================================================================
--- fittingview/src/sans/perspectives/fitting/fitproblem.py	(revision 49c69de79aac6bbde0711203fe50ff3af1f0bb81)
+++ fittingview/src/sans/perspectives/fitting/fitproblem.py	(revision 3e3ab46e8a8026694117dce4a72941ae4106aad0)
@@ -1,5 +1,357 @@
+################################################################################
+#This software was developed by the University of Tennessee as part of the
+#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+#project funded by the US National Science Foundation. 
+#
+#See the license text in license.txt
+#
+#copyright 2009, University of Tennessee
+################################################################################
 import copy 
+from sans.models.qsmearing import smear_selection
 
-class FitProblem:
+
+class FitProblemComponent(object):
+    """
+    Inferface containing information to store data, model, range of data, etc...
+    and retreive this information. This is an inferface 
+    for a fitProblem i.e relationship between data and model.
+    """
+    def enable_smearing(self, flag=False):
+        """
+        :param flag: bool.When flag is 1 get the computer smear value. When
+        flag is 0 ingore smear value.
+        """
+    def get_smearer(self):
+        """
+        return smear object
+        """
+    def save_model_name(self, name):
+        """
+        """  
+    def get_name(self):
+        """
+        """
+    def set_model(self, model):
+        """ 
+        associates each model with its new created name
+        :param model: model selected
+        :param name: name created for model
+        """
+    def get_model(self):
+        """
+        :return: saved model
+        """
+    def set_theory_data(self, data):
+        """ 
+        save a copy of the data select to fit
+        :param data: data selected
+        """
+    def get_theory_data(self):
+        """
+        :return: list of data dList
+        """
+    def set_fit_data(self, data):
+        """ 
+         Store of list of data and create  by create new fitproblem of each data
+         id , if there was existing information about model, this information
+         get copy to the new fitproblem
+        :param data: list of data selected
+        """   
+    def get_fit_data(self):
+        """
+        """
+    def set_model_param(self, name, value=None):
+        """ 
+        Store the name and value of a parameter of this fitproblem's model
+        :param name: name of the given parameter
+        :param value: value of that parameter
+        """
+    def get_model_param(self):
+        """ 
+        return list of couple of parameter name and value
+        """
+    def schedule_tofit(self, schedule=0):
+        """
+        set schedule to true to decide if this fit  must be performed
+        """
+    def get_scheduled(self):
+        """
+        return true or false if a problem as being schedule for fitting
+        """
+    def set_range(self, qmin=None, qmax=None):
+        """
+        set fitting range 
+        """
+    def get_range(self):
+        """
+        :return: fitting range
+        """
+    def clear_model_param(self):
+        """
+        clear constraint info
+        """
+    def set_fit_tab_caption(self, caption):
+        """
+        store the caption of the page associated with object
+        """
+    def get_fit_tab_caption(self):
+        """
+        Return the caption of the page associated with object
+        """
+        
+   
+class FitProblemDictionary(FitProblemComponent, dict):
+    """
+    This module implements a dictionary of fitproblem objects
+    """
+    def __init__(self):
+        FitProblemComponent.__init__(self)
+        dict.__init__(self)
+        ## the current model
+        self.model = None
+        ## if 1 this fit problem will be selected to fit , if 0 
+        ## it will not be selected for fit
+        self.schedule = 0
+        ##list containing parameter name and value
+        self.list_param = []
+        ## fitting range
+        self.qmin = None
+        self.qmax = None
+        self._smear_on = False
+        self.scheduled = 0
+        self.fit_tab_caption = ''
+ 
+    def enable_smearing(self, flag=False, fid=None):
+        """
+        :param flag: bool.When flag is 1 get the computer smear value. When
+        flag is 0 ingore smear value.
+        """
+        self._smear_on = flag
+        if fid is None:
+            for value in self.itervalues():
+                value.enable_smearing(flag)
+        else:
+            if fid in self.iterkeys():
+                self[fid].enable_smearing(flag)
+        
+    def set_smearer(self, smearer, fid=None):
+        """
+        save reference of  smear object on fitdata
+        :param smear: smear object from DataLoader
+        """
+        if fid is None:
+            for value in self.itervalues():
+                value.set_smearer(smearer)
+        else:
+            if fid in self.iterkeys():
+                self[fid].set_smearer(smearer)
+                
+    def get_smearer(self, fid=None):
+        """
+        return smear object
+        """
+        result = []
+        if fid is None:
+            for value in self.itervalues():
+                result.append(value.get_smearer())
+        else:
+            if fid in self.iterkeys():
+                result.append(self[fid].get_smearer())
+        return result
+    
+    def save_model_name(self, name, fid=None):
+        """
+        """  
+        if fid is None:
+            for value in self.itervalues():
+                value.save_model_name(name)
+        else:
+            if fid in self.iterkeys():
+                self[fid].save_model_name(name)
+                
+    def get_name(self, fid=None):
+        """
+        """
+        result = []
+        if fid is None:
+            for value in self.itervalues():
+                result.append(value.get_name())
+        else:
+            if fid in self.iterkeys():
+                result.append(self[fid].get_name())
+        return result
+    
+    def set_model(self, model, fid=None):
+        """ 
+        associates each model with its new created name
+        :param model: model selected
+        :param name: name created for model
+        """
+        self.model = model
+        if fid is None:
+            for value in self.itervalues():
+                value.set_model(self.model)
+        else:
+            if fid in self.iterkeys():
+                self[fid].set_model(self.model)
+      
+    def get_model(self, fid):
+        """
+        :return: saved model
+        """
+        if fid in self.iterkeys():
+            self[fid].get_model()
+       
+    def set_fit_tab_caption(self, caption):
+        """
+        store the caption of the page associated with object
+        """
+        self.fit_tab_caption = caption
+    
+    def get_fit_tab_caption(self):
+        """
+        Return the caption of the page associated with object
+        """
+        return self.fit_tab_caption
+    
+    def set_theory_data(self, fid, data=None):
+        """ 
+        save a copy of the data select to fit
+        :param data: data selected
+        """
+        if fid in self.iterkeys():
+            self[fid].set_theory_data(data)
+            
+    def get_theory_data(self, fid):
+        """
+        :return: list of data dList
+        """
+        if fid in self.iterkeys():
+            return self[fid].get_theory_data()
+            
+    def add_data(self, data):
+        """
+        Add data to the current dictionary of fitproblem. if data id does not
+        exist create a new fit problem.
+        :note: only data changes in the fit problem
+        """
+        if data.id not in self.iterkeys():
+            self[data.id] = FitProblem()
+        self[data.id].set_fit_data(data)
+        
+    def set_fit_data(self, data):
+        """ 
+        save a copy of the data select to fit
+        :param data: data selected
+        
+        """
+        self.clear()
+        if data is None:
+            data = []
+        for d in data:
+            if (d is not None):
+                if (d.id not in self.iterkeys()):
+                    self[d.id] = FitProblem()
+                self[d.id].set_fit_data(d)
+                self[d.id].set_model(self.model)
+                self[d.id].set_range(self.qmin, self.qmax)
+          
+    def get_fit_data(self, fid):
+        """
+       
+        return data for the given fitproblem id
+        :param fid: is key representing a fitproblem. usually extract from data
+                    id
+        """
+        if fid in self.iterkeys():
+            return self[fid].get_fit_data()
+   
+    def set_model_param(self, name, value=None, fid=None):
+        """ 
+        Store the name and value of a parameter of this fitproblem's model
+        :param name: name of the given parameter
+        :param value: value of that parameter
+        """
+        if fid is None:
+            for value in self.itervalues():
+                value.set_model_param(name, value)
+        else:
+            if fid in self.iterkeys():
+                self[fid].set_model_param(name, value)
+                
+    def get_model_param(self, fid):
+        """ 
+        return list of couple of parameter name and value
+        """
+        if fid in self.iterkeys():
+            return self[fid].get_model_param()
+      
+    def schedule_tofit(self, schedule=0):
+        """
+        set schedule to true to decide if this fit  must be performed
+        """
+        self.scheduled = schedule
+        for value in self.itervalues():
+            value.schedule_tofit(schedule)
+      
+    def get_scheduled(self):
+        """
+        return true or false if a problem as being schedule for fitting
+        """
+        return self.scheduled
+    
+    def set_range(self, qmin=None, qmax=None, fid=None):
+        """
+        set fitting range 
+        """
+        self.qmin = qmin
+        self.qmax = qmax
+        if fid is None:
+            for value in self.itervalues():
+                value.set_range(self.qmin, self.qmax)
+        else:
+            if fid in self.iterkeys():
+                self[fid].value.set_range(self.qmin, self.qmax)
+        
+    def get_range(self, fid):
+        """
+        :return: fitting range
+        """
+        if fid in self.iterkeys():
+            return self[fid].get_range()
+        
+    
+    def clear_model_param(self, fid=None):
+        """
+        clear constraint info
+        """
+        if fid is None:
+            for value in self.itervalues():
+                value.clear_model_param()
+        else:
+            if fid in self.iterkeys():
+                self[fid].clear_model_param()
+                
+    def get_fit_problem(self):
+        """
+        return fitproblem contained in this dictionary
+        """
+        return self.itervalues()
+    
+    def set_result(self, result):
+        """
+        set a list of result
+        """
+        self.result = result
+                
+    def get_result(self):
+        """
+        get result 
+        """
+        return self.result
+    
+
+class FitProblem(FitProblemComponent):
     """  
     FitProblem class allows to link a model with the new name created in _on_model,
@@ -8,4 +360,5 @@
     """
     def __init__(self):
+        FitProblemComponent.__init__(self)
         """
         contains information about data and model to fit
@@ -13,12 +366,7 @@
         ## data used for fitting
         self.fit_data = None
-        #list of data  in case of batch mode
-        self.data_list = []
-        #dictionary of data id and location to corresponding fitproblem
-        self.fitproblem_pointers = {}
         self.theory_data = None
         ## the current model
         self.model = None
-        self.model_index = None
         ## if 1 this fit problem will be selected to fit , if 0 
         ## it will not be selected for fit
@@ -27,35 +375,18 @@
         self.list_param = []
         ## smear object to smear or not data1D
-        self.smearer = None
-        self.fit_tab_caption = ''
+        self.smearer_compute_count = 0
+        self.smearer_enable = False
+        self.smearer_computer_value = None
         ## fitting range
         self.qmin = None
         self.qmax = None
-        self.result = []
-        
-        # 1D or 2D
-        self.enable2D = False
-        
-    def clone(self):
-        """
-        copy fitproblem
-        """
-        
-        obj          = FitProblem()
-        model= None
-        if self.model!=None:
-            model = self.model.clone()
-        obj.model = model
-        obj.fit_data = copy.deepcopy(self.fit_data)
-        obj.theory_data = copy.deepcopy(self.theory_data)
-        obj.model = copy.deepcopy(self.model)
-        obj.schedule = copy.deepcopy(self.schedule)
-        obj.list_param = copy.deepcopy(self.list_param)
-        obj.smearer = copy.deepcopy(self.smearer)
-        obj.plotted_data = copy.deepcopy(self.plotted_data)
-        obj.qmin = copy.deepcopy(self.qmin)
-        obj.qmax = copy.deepcopy(self.qmax)
-        obj.enable2D = copy.deepcopy(self.enable2D)
-        return obj
+        
+        
+    def enable_smearing(self, flag=False):
+        """
+        :param flag: bool.When flag is 1 get the computer smear value. When
+        flag is 0 ingore smear value.
+        """
+        self.smearer_enable = flag
         
     def set_smearer(self, smearer):
@@ -66,5 +397,5 @@
         
         """
-        self.smearer= smearer
+        self.smearer_computer_value = smearer
        
     def get_smearer(self):
@@ -72,5 +403,13 @@
         return smear object
         """
-        return self.smearer
+        if not self.smearer_enable:
+            return None
+        if self.smearer_computer_value is None and \
+            self.smearer_compute_count > 1:
+            #smeari_selection should be call only once per fitproblem
+            self.smearer_computer_value = smear_selection(self.fit_data,
+                                                           self.model)
+            self.smearer_compute_count += 1
+        return self.smearer_computer_value
     
     def save_model_name(self, name):
@@ -87,8 +426,6 @@
         """ 
         associates each model with its new created name
-        
         :param model: model selected
         :param name: name created for model
-        
         """
         self.model= model
@@ -97,20 +434,7 @@
         """
         :return: saved model
-        
         """
         return self.model
   
-    def set_index(self, index):
-        """
-        set index of the model name
-        """
-        self.model_index = index
-        
-    def get_index(self):
-        """
-        get index of the model name
-        """
-        return self.model_index
-    
     def set_theory_data(self, data):
         """ 
@@ -122,22 +446,16 @@
         self.theory_data = copy.deepcopy(data)
         
-    def set_enable2D(self, enable2D):
-        """
-        """
-        self.enable2D = enable2D
+  
          
     def get_theory_data(self):
         """
-        :return: list of data dList
-        
+        :return: theory generated with the current model and data of this class
         """
         return self.theory_data
 
-    def set_fit_data(self,data):
-        """ 
-        save a copy of the data select to fit
-        
-        :param data: data selected
-        
+    def set_fit_data(self, data):
+        """ 
+        Store data associated with this class
+        :param data: list of data selected
         """
         self.fit_data = data
@@ -145,28 +463,13 @@
     def get_fit_data(self):
         """
+        :return: data associate with this class
         """
         return self.fit_data
     
-    def set_fit_data_list(self, data_list):
-        """ 
-        save a copy of a list of data
-        
-        :param data_list: list of data
-        
-        """
-        self.data_list = data_list
-            
-    def get_fit_data_list(self):
-        """
-        """
-        return self.data_list
-    
     def set_model_param(self,name,value=None):
         """ 
         Store the name and value of a parameter of this fitproblem's model
-        
         :param name: name of the given parameter
         :param value: value of that parameter
-        
         """
         self.list_param.append([name,value])
@@ -182,5 +485,5 @@
         set schedule to true to decide if this fit  must be performed
         """
-        self.schedule=schedule
+        self.schedule = schedule
         
     def get_scheduled(self):
@@ -192,5 +495,7 @@
     def set_range(self, qmin=None, qmax=None):
         """
-        set fitting range 
+        set fitting range
+        :param qmin: minimum value to consider for the fit range
+        :param qmax: maximum value to consider for the fit range
         """
         self.qmin = qmin
@@ -208,5 +513,5 @@
         clear constraint info
         """
-        self.list_param=[]
+        self.list_param = []
         
     def set_fit_tab_caption(self, caption):
@@ -220,31 +525,4 @@
         return self.fit_tab_caption
     
-    def get_enable2D(self):
-        """
-        """
-        return self.enable2D
-    
-    def get_pointer_to_fitproblem(self):
-        """
-        return dictionary of id of fitproblem
-        """
-        return self.fitproblem_pointers
-    
-    def set_pointer_to_fitproblem(self, data_id, page_id):
-        """
-        """
-        self.fitproblem_pointers[data_id] = page_id
-        
-    def set_result(self, result):
-        """
-        set a list of result
-        """
-        self.result = result
-        
-    def get_result(self):
-        """
-        get result 
-        """
-        return self.result
-        
+  
    
