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

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 5bf0331 was 5bf0331, checked in by pkienzle, 10 years ago

merge from trunk

  • Property mode set to 100644
File size: 21.5 KB
Line 
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"""
6################################################################################
7#This software was developed by the University of Tennessee as part of the
8#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
9#project funded by the US National Science Foundation.
10#
11#See the license text in license.txt
12#
13#copyright 2009, University of Tennessee
14################################################################################
15import copy
16from sans.models.qsmearing import smear_selection
17
18class FitProblemComponent(object):
19    """
20    Inferface containing information to store data, model, range of data, etc...
21    and retreive this information. This is an inferface
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        """
29       
30    def get_smearer(self):
31        """
32        return smear object
33        """
34    def save_model_name(self, name):
35        """
36        """
37       
38    def get_name(self):
39        """
40        """
41       
42    def set_model(self, model):
43        """
44        associates each model with its new created name
45        :param model: model selected
46        :param name: name created for model
47        """
48       
49    def get_model(self):
50        """
51        :return: saved model
52        """
53       
54    def set_residuals(self, residuals):
55        """
56        save a copy of residual
57        :param data: data selected
58        """
59       
60    def get_residuals(self):
61        """
62        :return: residuals
63        """
64       
65    def set_theory_data(self, data):
66        """
67        save a copy of the data select to fit
68        :param data: data selected
69        """
70       
71    def get_theory_data(self):
72        """
73        :return: list of data dList
74        """
75       
76    def set_fit_data(self, data):
77        """
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
82        """
83       
84    def get_fit_data(self):
85        """
86        """
87       
88    def set_model_param(self, name, value=None):
89        """
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        """
94       
95    def set_param2fit(self, list):
96        """
97        Store param names to fit (checked)
98        :param list: list of the param names
99        """
100       
101    def get_param2fit(self):
102        """
103        return the list param names to fit
104        """
105       
106    def get_model_param(self):
107        """
108        return list of couple of parameter name and value
109        """
110       
111    def schedule_tofit(self, schedule=0):
112        """
113        set schedule to true to decide if this fit  must be performed
114        """
115       
116    def get_scheduled(self):
117        """
118        return true or false if a problem as being schedule for fitting
119        """
120       
121    def set_range(self, qmin=None, qmax=None):
122        """
123        set fitting range
124        """
125       
126    def get_range(self):
127        """
128        :return: fitting range
129        """
130       
131    def set_weight(self, flag=None):
132        """
133        set fitting range
134        """
135       
136    def get_weight(self):
137        """
138        get fitting weight
139        """
140       
141    def clear_model_param(self):
142        """
143        clear constraint info
144        """
145       
146    def set_fit_tab_caption(self, caption):
147        """
148        store the caption of the page associated with object
149        """
150       
151    def get_fit_tab_caption(self):
152        """
153        Return the caption of the page associated with object
154        """
155       
156    def set_graph_id(self, id):
157        """
158        Set graph id (from data_group_id at the time the graph produced)
159        """
160       
161    def get_graph_id(self):
162        """
163        Get graph_id
164        """
165
166    def set_result(self, result):
167        """
168        """
169
170    def get_result(self):
171        """
172        get result
173        """
174
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
185        ## if 1 this fit problem will be selected to fit , if 0
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
193        self.graph_id = None
194        self._smear_on = False
195        self.scheduled = 0
196        self.fit_tab_caption = ''
197        self.nbr_residuals_computed = 0
198        self.batch_inputs = {}
199        self.batch_outputs = {}
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        """
230        if fid in self.iterkeys():
231            return self[fid].get_smearer()
232     
233    def save_model_name(self, name, fid=None):
234        """
235        """
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):
256        """
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():
274            return self[fid].get_model()
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   
288    def set_residuals(self, residuals, fid):
289        """
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       
303    def set_theory_data(self, fid, data=None):
304        """
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):
329        """
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)
344               
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):
355        """
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):
368        """
369        return list of couple of parameter name and value
370        """
371        if fid in self.iterkeys():
372            return self[fid].get_model_param()
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
384        """
385        return self.list_param2fit
386         
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        """
403        set fitting range
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       
421    def set_weight(self, is2d, flag=None, fid=None):
422        """
423        fit weight
424        """
425        if fid is None:
426            for value in self.itervalues():
427                value.set_weight(flag=flag, is2d=is2d)
428        else:
429            if fid in self.iterkeys():
430                self[fid].set_weight(flag=flag, is2d=is2d)
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                 
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   
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):
463        """
464        set a list of result
465        """
466        self.batch_inputs = batch_inputs
467        self.batch_outputs = batch_outputs
468             
469    def get_result(self, fid):
470        """
471        get result
472        """
473        if fid in self.iterkeys():
474            return self[fid].get_result()
475           
476    def get_batch_result(self):
477        """
478        get result
479        """
480        return self.batch_inputs, self.batch_outputs
481   
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       
488    def get_graph_id(self):
489        """
490        Get graph_id
491        """
492        return self.graph_id
493   
494   
495class FitProblem(FitProblemComponent):
496    """
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.
500    """
501    def __init__(self):
502        FitProblemComponent.__init__(self)
503        """
504        contains information about data and model to fit
505        """
506        ## data used for fitting
507        self.fit_data = None
508        self.theory_data = None
509        self.residuals = None
510        # original data: should not be modified
511        self.original_data = None
512        ## the current model
513        self.model = None
514        ## if 1 this fit problem will be selected to fit , if 0
515        ## it will not be selected for fit
516        self.schedule = 0
517        ##list containing parameter name and value
518        self.list_param = []
519        ## smear object to smear or not data1D
520        self.smearer_computed = False
521        self.smearer_enable = False
522        self.smearer_computer_value = None
523        ## fitting range
524        self.qmin = None
525        self.qmax = None
526        # fit weight
527        self.weight = None
528        self.result = None
529       
530    def enable_smearing(self, flag=False):
531        """
532        :param flag: bool.When flag is 1 get the computer smear value. When
533        flag is 0 ingore smear value.
534        """
535        self.smearer_enable = flag
536       
537    def set_smearer(self, smearer):
538        """
539        save reference of  smear object on fitdata
540       
541        :param smear: smear object from DataLoader
542       
543        """
544        self.smearer_computer_value = smearer
545       
546    def get_smearer(self):
547        """
548        return smear object
549        """
550        if not self.smearer_enable:
551            return None
552        if not self.smearer_computed:
553            #smeari_selection should be call only once per fitproblem
554            self.smearer_computer_value = smear_selection(self.fit_data,
555                                                           self.model)
556            self.smearer_computed = True
557        return self.smearer_computer_value
558   
559    def save_model_name(self, name):
560        """
561        """
562        self.name_per_page = name
563       
564    def get_name(self):
565        """
566        """
567        return self.name_per_page
568   
569    def set_model(self, model):
570        """
571        associates each model with its new created name
572        :param model: model selected
573        :param name: name created for model
574        """
575        self.model = model
576        self.smearer_computer_value = smear_selection(self.fit_data,
577                                                           self.model)
578        self.smearer_computed = True
579       
580    def get_model(self):
581        """
582        :return: saved model
583        """
584        return self.model
585   
586    def set_residuals(self, residuals):
587        """
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       
599    def set_theory_data(self, data):
600        """
601        save a copy of the data select to fit
602       
603        :param data: data selected
604       
605        """
606        self.theory_data = copy.deepcopy(data)
607       
608    def get_theory_data(self):
609        """
610        :return: theory generated with the current model and data of this class
611        """
612        return self.theory_data
613
614    def set_fit_data(self, data):
615        """
616        Store data associated with this class
617        :param data: list of data selected
618        """
619        self.original_data = None
620        self.fit_data = None
621        # original data: should not be modified
622        self.original_data = data
623        # fit data: used for fit and can be modified for convenience
624        self.fit_data = copy.deepcopy(data)
625        self.smearer_computer_value = smear_selection(self.fit_data,
626                                                           self.model)
627        self.smearer_computed = True
628        self.result = None
629       
630    def get_fit_data(self):
631        """
632        :return: data associate with this class
633        """
634        return self.fit_data
635   
636    def get_origin_data(self):
637        """
638        """
639        return self.original_data
640   
641    def set_weight(self, is2d, flag=None):
642        """
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
646        """
647        from .utils import get_weight
648        # send original data for weighting
649        self.weight = get_weight(data=self.original_data, is2d=is2d, flag=flag)
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
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
667       
668    def get_param2fit(self):
669        """
670        return the list param names to fit
671        """
672        return self.list_param2fit
673   
674    def set_model_param(self, name, value=None):
675        """
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
679        """
680        self.list_param.append([name, value])
681       
682    def get_model_param(self):
683        """
684        return list of couple of parameter name and value
685        """
686        return self.list_param
687       
688    def schedule_tofit(self, schedule=0):
689        """
690        set schedule to true to decide if this fit  must be performed
691        """
692        self.schedule = schedule
693       
694    def get_scheduled(self):
695        """
696        return true or false if a problem as being schedule for fitting
697        """
698        return self.schedule
699   
700    def set_range(self, qmin=None, qmax=None):
701        """
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
705        """
706        self.qmin = qmin
707        self.qmax = qmax
708       
709    def get_range(self):
710        """
711        :return: fitting range
712       
713        """
714        return self.qmin, self.qmax
715   
716    def clear_model_param(self):
717        """
718        clear constraint info
719        """
720        self.list_param = []
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
731   
732    def set_graph_id(self, id):
733        """
734        Set graph id (from data_group_id at the time the graph produced)
735        """
736        self.graph_id = id
737       
738    def get_graph_id(self):
739        """
740        Get graph_id
741        """
742        return self.graph_id
743   
744    def set_result(self, result):
745        """
746        """
747        self.result = result
748       
749    def get_result(self):
750        """
751        get result
752        """
753        return self.result
Note: See TracBrowser for help on using the repository browser.