source: sasview/src/sans/perspectives/fitting/fitproblem.py @ 5777106

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 5777106 was 5777106, checked in by Mathieu Doucet <doucetm@…>, 11 years ago

Moving things around. Will definitely not build.

  • Property mode set to 100644
File size: 21.5 KB
RevLine 
[f32d144]1"""
2Inferface containing information to store data, model, range of data, etc...
3and retreive this information. This is an inferface
4for a fitProblem i.e relationship between data and model.
5"""
[3e3ab46]6################################################################################
7#This software was developed by the University of Tennessee as part of the
8#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
[f32d144]9#project funded by the US National Science Foundation.
[3e3ab46]10#
11#See the license text in license.txt
12#
13#copyright 2009, University of Tennessee
14################################################################################
[f32d144]15import copy
[3e3ab46]16from sans.models.qsmearing import smear_selection
[d89f09b]17
[3e3ab46]18class FitProblemComponent(object):
19    """
20    Inferface containing information to store data, model, range of data, etc...
[f32d144]21    and retreive this information. This is an inferface
[3e3ab46]22    for a fitProblem i.e relationship between data and model.
23    """
24    def enable_smearing(self, flag=False):
25        """
26        :param flag: bool.When flag is 1 get the computer smear value. When
27        flag is 0 ingore smear value.
28        """
[f32d144]29       
[3e3ab46]30    def get_smearer(self):
31        """
32        return smear object
33        """
34    def save_model_name(self, name):
35        """
[f32d144]36        """
37       
[3e3ab46]38    def get_name(self):
39        """
40        """
[f32d144]41       
[3e3ab46]42    def set_model(self, model):
[f32d144]43        """
[3e3ab46]44        associates each model with its new created name
45        :param model: model selected
46        :param name: name created for model
47        """
[f32d144]48       
[3e3ab46]49    def get_model(self):
50        """
51        :return: saved model
52        """
[f32d144]53       
[62f851f]54    def set_residuals(self, residuals):
[f32d144]55        """
[62f851f]56        save a copy of residual
57        :param data: data selected
58        """
[f32d144]59       
[62f851f]60    def get_residuals(self):
61        """
62        :return: residuals
63        """
64       
[3e3ab46]65    def set_theory_data(self, data):
[f32d144]66        """
[3e3ab46]67        save a copy of the data select to fit
68        :param data: data selected
69        """
[f32d144]70       
[3e3ab46]71    def get_theory_data(self):
72        """
73        :return: list of data dList
74        """
[f32d144]75       
[3e3ab46]76    def set_fit_data(self, data):
[f32d144]77        """
[3e3ab46]78         Store of list of data and create  by create new fitproblem of each data
79         id , if there was existing information about model, this information
80         get copy to the new fitproblem
81        :param data: list of data selected
[f32d144]82        """
83       
[3e3ab46]84    def get_fit_data(self):
85        """
86        """
[f32d144]87       
[3e3ab46]88    def set_model_param(self, name, value=None):
[f32d144]89        """
[3e3ab46]90        Store the name and value of a parameter of this fitproblem's model
91        :param name: name of the given parameter
92        :param value: value of that parameter
93        """
[f32d144]94       
[1b14795]95    def set_param2fit(self, list):
96        """
97        Store param names to fit (checked)
98        :param list: list of the param names
99        """
[f32d144]100       
[1b14795]101    def get_param2fit(self):
102        """
103        return the list param names to fit
104        """
[f32d144]105       
[3e3ab46]106    def get_model_param(self):
[f32d144]107        """
[3e3ab46]108        return list of couple of parameter name and value
109        """
[f32d144]110       
[3e3ab46]111    def schedule_tofit(self, schedule=0):
112        """
113        set schedule to true to decide if this fit  must be performed
114        """
[f32d144]115       
[3e3ab46]116    def get_scheduled(self):
117        """
118        return true or false if a problem as being schedule for fitting
119        """
[f32d144]120       
[3e3ab46]121    def set_range(self, qmin=None, qmax=None):
122        """
[f32d144]123        set fitting range
[3e3ab46]124        """
[f32d144]125       
[3e3ab46]126    def get_range(self):
127        """
128        :return: fitting range
129        """
[f32d144]130       
[f7ef313]131    def set_weight(self, flag=None):
[55bb249c]132        """
[f32d144]133        set fitting range
[55bb249c]134        """
[f32d144]135       
[55bb249c]136    def get_weight(self):
137        """
138        get fitting weight
139        """
[f32d144]140       
[3e3ab46]141    def clear_model_param(self):
142        """
143        clear constraint info
144        """
[f32d144]145       
[3e3ab46]146    def set_fit_tab_caption(self, caption):
147        """
148        store the caption of the page associated with object
149        """
[f32d144]150       
[3e3ab46]151    def get_fit_tab_caption(self):
152        """
153        Return the caption of the page associated with object
154        """
[f32d144]155       
[5e48acb]156    def set_graph_id(self, id):
157        """
158        Set graph id (from data_group_id at the time the graph produced)
159        """
[f32d144]160       
161    def get_graph_id(self):
[5e48acb]162        """
163        Get graph_id
[f32d144]164        """
165
[41661a0]166    def set_result(self, result):
167        """
168        """
169
170    def get_result(self):
171        """
[f32d144]172        get result
173        """
[41661a0]174
[3e3ab46]175   
176class FitProblemDictionary(FitProblemComponent, dict):
177    """
178    This module implements a dictionary of fitproblem objects
179    """
180    def __init__(self):
181        FitProblemComponent.__init__(self)
182        dict.__init__(self)
183        ## the current model
184        self.model = None
[f32d144]185        ## if 1 this fit problem will be selected to fit , if 0
[3e3ab46]186        ## it will not be selected for fit
187        self.schedule = 0
188        ##list containing parameter name and value
189        self.list_param = []
190        ## fitting range
191        self.qmin = None
192        self.qmax = None
[5e48acb]193        self.graph_id = None
[3e3ab46]194        self._smear_on = False
195        self.scheduled = 0
196        self.fit_tab_caption = ''
[f64a4b7]197        self.nbr_residuals_computed = 0
198        self.batch_inputs = {}
199        self.batch_outputs = {}
[3e3ab46]200 
201    def enable_smearing(self, flag=False, fid=None):
202        """
203        :param flag: bool.When flag is 1 get the computer smear value. When
204        flag is 0 ingore smear value.
205        """
206        self._smear_on = flag
207        if fid is None:
208            for value in self.itervalues():
209                value.enable_smearing(flag)
210        else:
211            if fid in self.iterkeys():
212                self[fid].enable_smearing(flag)
213       
214    def set_smearer(self, smearer, fid=None):
215        """
216        save reference of  smear object on fitdata
217        :param smear: smear object from DataLoader
218        """
219        if fid is None:
220            for value in self.itervalues():
221                value.set_smearer(smearer)
222        else:
223            if fid in self.iterkeys():
224                self[fid].set_smearer(smearer)
225               
226    def get_smearer(self, fid=None):
227        """
228        return smear object
229        """
[62f851f]230        if fid in self.iterkeys():
231            return self[fid].get_smearer()
232     
[3e3ab46]233    def save_model_name(self, name, fid=None):
234        """
[f32d144]235        """
[3e3ab46]236        if fid is None:
237            for value in self.itervalues():
238                value.save_model_name(name)
239        else:
240            if fid in self.iterkeys():
241                self[fid].save_model_name(name)
242               
243    def get_name(self, fid=None):
244        """
245        """
246        result = []
247        if fid is None:
248            for value in self.itervalues():
249                result.append(value.get_name())
250        else:
251            if fid in self.iterkeys():
252                result.append(self[fid].get_name())
253        return result
254   
255    def set_model(self, model, fid=None):
[f32d144]256        """
[3e3ab46]257        associates each model with its new created name
258        :param model: model selected
259        :param name: name created for model
260        """
261        self.model = model
262        if fid is None:
263            for value in self.itervalues():
264                value.set_model(self.model)
265        else:
266            if fid in self.iterkeys():
267                self[fid].set_model(self.model)
268     
269    def get_model(self, fid):
270        """
271        :return: saved model
272        """
273        if fid in self.iterkeys():
[62f851f]274            return self[fid].get_model()
[3e3ab46]275       
276    def set_fit_tab_caption(self, caption):
277        """
278        store the caption of the page associated with object
279        """
280        self.fit_tab_caption = caption
281   
282    def get_fit_tab_caption(self):
283        """
284        Return the caption of the page associated with object
285        """
286        return self.fit_tab_caption
287   
[62f851f]288    def set_residuals(self, residuals, fid):
[f32d144]289        """
[62f851f]290        save a copy of residual
291        :param data: data selected
292        """
293        if fid in self.iterkeys():
294            self[fid].set_residuals(residuals)
295           
296    def get_residuals(self, fid):
297        """
298        :return: residuals
299        """
300        if fid in self.iterkeys():
301            return self[fid].get_residuals()
302       
[3e3ab46]303    def set_theory_data(self, fid, data=None):
[f32d144]304        """
[3e3ab46]305        save a copy of the data select to fit
306        :param data: data selected
307        """
308        if fid in self.iterkeys():
309            self[fid].set_theory_data(data)
310           
311    def get_theory_data(self, fid):
312        """
313        :return: list of data dList
314        """
315        if fid in self.iterkeys():
316            return self[fid].get_theory_data()
317           
318    def add_data(self, data):
319        """
320        Add data to the current dictionary of fitproblem. if data id does not
321        exist create a new fit problem.
322        :note: only data changes in the fit problem
323        """
324        if data.id not in self.iterkeys():
325            self[data.id] = FitProblem()
326        self[data.id].set_fit_data(data)
327       
328    def set_fit_data(self, data):
[f32d144]329        """
[3e3ab46]330        save a copy of the data select to fit
331        :param data: data selected
332       
333        """
334        self.clear()
335        if data is None:
336            data = []
337        for d in data:
338            if (d is not None):
339                if (d.id not in self.iterkeys()):
340                    self[d.id] = FitProblem()
341                self[d.id].set_fit_data(d)
342                self[d.id].set_model(self.model)
343                self[d.id].set_range(self.qmin, self.qmax)
[f32d144]344               
[3e3ab46]345    def get_fit_data(self, fid):
346        """
347        return data for the given fitproblem id
348        :param fid: is key representing a fitproblem. usually extract from data
349                    id
350        """
351        if fid in self.iterkeys():
352            return self[fid].get_fit_data()
353   
354    def set_model_param(self, name, value=None, fid=None):
[f32d144]355        """
[3e3ab46]356        Store the name and value of a parameter of this fitproblem's model
357        :param name: name of the given parameter
358        :param value: value of that parameter
359        """
360        if fid is None:
361            for value in self.itervalues():
362                value.set_model_param(name, value)
363        else:
364            if fid in self.iterkeys():
365                self[fid].set_model_param(name, value)
366               
367    def get_model_param(self, fid):
[f32d144]368        """
[3e3ab46]369        return list of couple of parameter name and value
370        """
371        if fid in self.iterkeys():
372            return self[fid].get_model_param()
[1b14795]373   
374    def set_param2fit(self, list):
375        """
376        Store param names to fit (checked)
377        :param list: list of the param names
378        """
379        self.list_param2fit = list
380       
381    def get_param2fit(self):
382        """
383        return the list param names to fit
[f32d144]384        """
[1b14795]385        return self.list_param2fit
386         
[3e3ab46]387    def schedule_tofit(self, schedule=0):
388        """
389        set schedule to true to decide if this fit  must be performed
390        """
391        self.scheduled = schedule
392        for value in self.itervalues():
393            value.schedule_tofit(schedule)
394     
395    def get_scheduled(self):
396        """
397        return true or false if a problem as being schedule for fitting
398        """
399        return self.scheduled
400   
401    def set_range(self, qmin=None, qmax=None, fid=None):
402        """
[f32d144]403        set fitting range
[3e3ab46]404        """
405        self.qmin = qmin
406        self.qmax = qmax
407        if fid is None:
408            for value in self.itervalues():
409                value.set_range(self.qmin, self.qmax)
410        else:
411            if fid in self.iterkeys():
412                self[fid].value.set_range(self.qmin, self.qmax)
413       
414    def get_range(self, fid):
415        """
416        :return: fitting range
417        """
418        if fid in self.iterkeys():
419            return self[fid].get_range()
420       
[f32d144]421    def set_weight(self, is2d, flag=None, fid=None):
[55bb249c]422        """
423        fit weight
424        """
425        if fid is None:
426            for value in self.itervalues():
[f7ef313]427                value.set_weight(flag=flag, is2d=is2d)
[55bb249c]428        else:
429            if fid in self.iterkeys():
[f7ef313]430                self[fid].set_weight(flag=flag, is2d=is2d)
[55bb249c]431               
432    def get_weight(self, fid=None):
433        """
434        return fit weight
435        """
436        if fid in self.iterkeys():
437            return self[fid].get_weight()
438                 
[3e3ab46]439    def clear_model_param(self, fid=None):
440        """
441        clear constraint info
442        """
443        if fid is None:
444            for value in self.itervalues():
445                value.clear_model_param()
446        else:
447            if fid in self.iterkeys():
448                self[fid].clear_model_param()
449               
450    def get_fit_problem(self):
451        """
452        return fitproblem contained in this dictionary
453        """
454        return self.itervalues()
455   
[41661a0]456    def  set_result(self, result, fid):
457        """
458        """
459        if fid in self.iterkeys():
460            self[fid].set_result(result)
461           
462    def set_batch_result(self, batch_inputs, batch_outputs):
[3e3ab46]463        """
464        set a list of result
465        """
[f64a4b7]466        self.batch_inputs = batch_inputs
467        self.batch_outputs = batch_outputs
[41661a0]468             
469    def get_result(self, fid):
470        """
[f32d144]471        get result
472        """
[41661a0]473        if fid in self.iterkeys():
474            return self[fid].get_result()
475           
476    def get_batch_result(self):
[3e3ab46]477        """
[f32d144]478        get result
[3e3ab46]479        """
[f64a4b7]480        return self.batch_inputs, self.batch_outputs
[3e3ab46]481   
[5e48acb]482    def set_graph_id(self, id):
483        """
484        Set graph id (from data_group_id at the time the graph produced)
485        """
486        self.graph_id = id
487       
[f32d144]488    def get_graph_id(self):
[5e48acb]489        """
490        Get graph_id
[f32d144]491        """
[5e48acb]492        return self.graph_id
493   
494   
[3e3ab46]495class FitProblem(FitProblemComponent):
[f32d144]496    """
[5062bbf]497    FitProblem class allows to link a model with the new name created in _on_model,
498    a name theory created with that model  and the data fitted with the model.
499    FitProblem is mostly used  as value of the dictionary by fitting module.
[d89f09b]500    """
501    def __init__(self):
[3e3ab46]502        FitProblemComponent.__init__(self)
[d89f09b]503        """
[5062bbf]504        contains information about data and model to fit
[d89f09b]505        """
[925a30e]506        ## data used for fitting
[6bbeacd4]507        self.fit_data = None
508        self.theory_data = None
[62f851f]509        self.residuals = None
[05325ec4]510        # original data: should not be modified
511        self.original_data = None
[2140e68]512        ## the current model
513        self.model = None
[f32d144]514        ## if 1 this fit problem will be selected to fit , if 0
[925a30e]515        ## it will not be selected for fit
[6bbeacd4]516        self.schedule = 0
[925a30e]517        ##list containing parameter name and value
[6bbeacd4]518        self.list_param = []
[925a30e]519        ## smear object to smear or not data1D
[7afcae8]520        self.smearer_computed = False
[3e3ab46]521        self.smearer_enable = False
522        self.smearer_computer_value = None
[2140e68]523        ## fitting range
524        self.qmin = None
525        self.qmax = None
[55bb249c]526        # fit weight
527        self.weight = None
[a3c8e8f]528        self.result = None
[08b9c6c8]529       
[3e3ab46]530    def enable_smearing(self, flag=False):
[9853ad0]531        """
[3e3ab46]532        :param flag: bool.When flag is 1 get the computer smear value. When
533        flag is 0 ingore smear value.
[9853ad0]534        """
[3e3ab46]535        self.smearer_enable = flag
[9853ad0]536       
[08b9c6c8]537    def set_smearer(self, smearer):
[925a30e]538        """
[5062bbf]539        save reference of  smear object on fitdata
540       
541        :param smear: smear object from DataLoader
542       
[925a30e]543        """
[3e3ab46]544        self.smearer_computer_value = smearer
[925a30e]545       
[08b9c6c8]546    def get_smearer(self):
[925a30e]547        """
[5062bbf]548        return smear object
[925a30e]549        """
[3e3ab46]550        if not self.smearer_enable:
551            return None
[7afcae8]552        if not self.smearer_computed:
[3e3ab46]553            #smeari_selection should be call only once per fitproblem
[7afcae8]554            self.smearer_computer_value = smear_selection(self.fit_data,
[3e3ab46]555                                                           self.model)
[7afcae8]556            self.smearer_computed = True
[3e3ab46]557        return self.smearer_computer_value
[08b9c6c8]558   
[5062bbf]559    def save_model_name(self, name):
560        """
[f32d144]561        """
562        self.name_per_page = name
[bb18ef1]563       
564    def get_name(self):
[5062bbf]565        """
566        """
[bb18ef1]567        return self.name_per_page
[08b9c6c8]568   
[8aa5788]569    def set_model(self, model):
[f32d144]570        """
[5062bbf]571        associates each model with its new created name
572        :param model: model selected
573        :param name: name created for model
[d89f09b]574        """
[7afcae8]575        self.model = model
576        self.smearer_computer_value = smear_selection(self.fit_data,
577                                                           self.model)
578        self.smearer_computed = True
[bb18ef1]579       
[2140e68]580    def get_model(self):
[5062bbf]581        """
582        :return: saved model
583        """
[2140e68]584        return self.model
[62f851f]585   
586    def set_residuals(self, residuals):
[f32d144]587        """
[62f851f]588        save a copy of residual
589        :param data: data selected
590        """
591        self.residuals = residuals
592           
593    def get_residuals(self):
594        """
595        :return: residuals
596        """
597        return self.residuals
598       
[6bbeacd4]599    def set_theory_data(self, data):
[f32d144]600        """
[5062bbf]601        save a copy of the data select to fit
602       
603        :param data: data selected
604       
[d89f09b]605        """
[e88ebfd]606        self.theory_data = copy.deepcopy(data)
[ba1f0b2]607       
[6bbeacd4]608    def get_theory_data(self):
[5062bbf]609        """
[3e3ab46]610        :return: theory generated with the current model and data of this class
[5062bbf]611        """
[6bbeacd4]612        return self.theory_data
[5062bbf]613
[3e3ab46]614    def set_fit_data(self, data):
[f32d144]615        """
[3e3ab46]616        Store data associated with this class
617        :param data: list of data selected
[2a8fac1]618        """
[3fb5e68]619        self.original_data = None
620        self.fit_data = None
[05325ec4]621        # original data: should not be modified
[7db52f1]622        self.original_data = data
[05325ec4]623        # fit data: used for fit and can be modified for convenience
[55bb249c]624        self.fit_data = copy.deepcopy(data)
[7afcae8]625        self.smearer_computer_value = smear_selection(self.fit_data,
626                                                           self.model)
627        self.smearer_computed = True
[a3c8e8f]628        self.result = None
[f7ef313]629       
[2a8fac1]630    def get_fit_data(self):
[5062bbf]631        """
[3e3ab46]632        :return: data associate with this class
[5062bbf]633        """
[2a8fac1]634        return self.fit_data
635   
[7db52f1]636    def get_origin_data(self):
637        """
638        """
639        return self.original_data
640   
[f7ef313]641    def set_weight(self, is2d, flag=None):
[55bb249c]642        """
[f7ef313]643        Received flag and compute error on data.
644        :param flag: flag to transform error of data.
645        :param is2d: flag to distinguish 1D to 2D Data
[55bb249c]646        """
[f7ef313]647        from .utils import get_weight
[05325ec4]648        # send original data for weighting
649        self.weight = get_weight(data=self.original_data, is2d=is2d, flag=flag)
[55bb249c]650        if is2d:
651            self.fit_data.err_data = self.weight
652        else:
653            self.fit_data.dy = self.weight
654
655    def get_weight(self):
656        """
657        returns weight array
658        """
659        return self.weight
[1b14795]660   
661    def set_param2fit(self, list):
662        """
663        Store param names to fit (checked)
664        :param list: list of the param names
665        """
666        self.list_param2fit = list
[55bb249c]667       
[1b14795]668    def get_param2fit(self):
669        """
670        return the list param names to fit
[f32d144]671        """
[1b14795]672        return self.list_param2fit
673   
[f32d144]674    def set_model_param(self, name, value=None):
675        """
[5062bbf]676        Store the name and value of a parameter of this fitproblem's model
677        :param name: name of the given parameter
678        :param value: value of that parameter
[d89f09b]679        """
[f32d144]680        self.list_param.append([name, value])
[925a30e]681       
[00561739]682    def get_model_param(self):
[f32d144]683        """
[5062bbf]684        return list of couple of parameter name and value
[00561739]685        """
[8e81af0]686        return self.list_param
[d89f09b]687       
[948add7]688    def schedule_tofit(self, schedule=0):
[3b19ac9]689        """
[5062bbf]690        set schedule to true to decide if this fit  must be performed
[3b19ac9]691        """
[3e3ab46]692        self.schedule = schedule
[6bcdad1]693       
[3b19ac9]694    def get_scheduled(self):
[5062bbf]695        """
696        return true or false if a problem as being schedule for fitting
697        """
[3b19ac9]698        return self.schedule
[925a30e]699   
[2140e68]700    def set_range(self, qmin=None, qmax=None):
701        """
[3e3ab46]702        set fitting range
703        :param qmin: minimum value to consider for the fit range
704        :param qmax: maximum value to consider for the fit range
[2140e68]705        """
706        self.qmin = qmin
707        self.qmax = qmax
708       
709    def get_range(self):
710        """
[5062bbf]711        :return: fitting range
712       
[2140e68]713        """
714        return self.qmin, self.qmax
[925a30e]715   
[9e27de9]716    def clear_model_param(self):
717        """
718        clear constraint info
719        """
[3e3ab46]720        self.list_param = []
[6bbeacd4]721       
722    def set_fit_tab_caption(self, caption):
723        """
724        """
725        self.fit_tab_caption = str(caption)
726       
727    def get_fit_tab_caption(self):
728        """
729        """
730        return self.fit_tab_caption
[ba1f0b2]731   
[5e48acb]732    def set_graph_id(self, id):
733        """
[f32d144]734        Set graph id (from data_group_id at the time the graph produced)
[5e48acb]735        """
736        self.graph_id = id
737       
[f32d144]738    def get_graph_id(self):
[5e48acb]739        """
740        Get graph_id
[f32d144]741        """
[5e48acb]742        return self.graph_id
[41661a0]743   
744    def set_result(self, result):
745        """
746        """
747        self.result = result
748       
749    def get_result(self):
750        """
[f32d144]751        get result
752        """
753        return self.result
Note: See TracBrowser for help on using the repository browser.