source: sasview/sansmodels/src/sans/models/MultiplicationModel.py @ 9ce41c6

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 9ce41c6 was 8b677ec, checked in by Jae Cho <jhjcho@…>, 15 years ago

Corrections are made after multiplicationmodel unittest

  • Property mode set to 100644
File size: 8.3 KB
Line 
1
2from sans.models.BaseComponent import BaseComponent
3import numpy, math
4import copy
5from sans.models.pluginmodel import Model1DPlugin
6class MultiplicationModel(BaseComponent):
7    """
8        Use for P(Q)*S(Q); function call must be in order of P(Q) and then S(Q).
9        Perform multiplication of two models.
10        Contains the models parameters combined.
11    """
12    def __init__(self, model1, model2 ):
13        BaseComponent.__init__(self)
14
15       
16        ## Setting  model name model description
17        self.description=""
18        if  model1.name != "NoStructure" and  model2.name != "NoStructure":
19             self.name = model1.name +" * "+ model2.name
20             self.description= self.name+"\n"
21             self.fill_description(model1, model2)
22        elif  model2.name != "NoStructure":
23            self.name = model2.name
24            self.description= model2.description
25        else :
26            self.name = model1.name
27            self.description= model1.description
28                       
29       
30        self.model1= model1
31        self.model2= model2
32       
33       
34        ## dispersion
35        self._set_dispersion()
36        ## Define parameters
37        self._set_params()
38        ## Parameter details [units, min, max]
39        self._set_details()
40        #list of parameter that can be fitted
41        self._set_fixed_params() 
42        ## parameters with orientation
43        for item in self.model1.orientation_params:
44            self.orientation_params.append(item)
45           
46        for item in self.model2.orientation_params:
47            if not item in self.orientation_params:
48                self.orientation_params.append(item)
49               
50       
51    def _clone(self, obj):
52        """
53            Internal utility function to copy the internal
54            data members to a fresh copy.
55        """
56        obj.params     = copy.deepcopy(self.params)
57        obj.description     = copy.deepcopy(self.description)
58        obj.details    = copy.deepcopy(self.details)
59        obj.dispersion = copy.deepcopy(self.dispersion)
60        obj.model1  = self.model1.clone()
61        obj.model2  = self.model2.clone()
62       
63        return obj
64   
65   
66    def _set_dispersion(self):
67        """
68           combined the two models dispersions
69        """
70        for name , value in self.model1.dispersion.iteritems():
71            self.dispersion[name]= value
72           
73        for name , value in self.model2.dispersion.iteritems():
74            ## All S(Q) has only 'effect_radius' for dispersion which
75            #    will not be allowed for now.
76            if not name in self.dispersion.keys():
77                if name != 'effect_radius':
78                    self.dispersion[name]= value
79
80                   
81               
82               
83    def _set_params(self):
84        """
85            Concatenate the parameters of the two models to create
86            this model parameters
87        """
88        dia_rad = 0
89        for name , value in self.model1.params.iteritems():
90            self.params[name]= value
91           
92        for name , value in self.model2.params.iteritems():
93            if not name in self.params.keys():
94                #effect_radius is not treated as a parameter anymore.
95                if name != 'effect_radius': 
96                    self.params[name]= value
97           
98    def _set_details(self):
99        """
100            Concatenate details of the two models to create
101            this model details
102        """
103        for name ,detail in self.model1.details.iteritems():
104            self.details[name]= detail
105           
106        for name , detail in self.model2.details.iteritems():
107            if not name in self.details.keys(): 
108                if name != 'effect_radius': 
109                    self.details[name]= detail
110               
111    def setParam(self, name, value):
112        """
113            Set the value of a model parameter
114       
115            @param name: name of the parameter
116            @param value: value of the parameter
117        """
118
119        self._setParamHelper( name, value)
120
121        if name in self.model1.getParamList():
122            self.model1.setParam( name, value)
123
124        if name in self.model2.getParamList():
125            self.model2.setParam( name, value)
126
127        self._setParamHelper( name, value)
128       
129    def _setParamHelper(self, name, value):
130        """
131            Helper function to setparam
132        """
133        # Look for dispersion parameters
134        toks = name.split('.')
135        if len(toks)==2:
136            for item in self.dispersion.keys():
137                if item.lower()==toks[0].lower():
138                    for par in self.dispersion[item]:
139                        if par.lower() == toks[1].lower():
140                            self.dispersion[item][par] = value
141                            return
142        else:
143            # Look for standard parameter
144            for item in self.params.keys():
145                if item.lower()==name.lower():
146                    self.params[item] = value
147                    return
148           
149        raise ValueError, "Model does not contain parameter %s" % name
150             
151   
152    def _set_fixed_params(self):
153        """
154             fill the self.fixed list with the two models fixed list
155        """
156        for item in self.model1.fixed:
157            self.fixed.append(item)
158        #S(Q) should not have fixed items for P*S for now.
159        #for item in self.model2.fixed:
160        #    if not item in self.fixed:
161        #        self.fixed.append(item)
162
163        self.fixed.sort()
164               
165               
166    def run(self, x = 0.0):
167        """ Evaluate the model
168            @param x: input q-value (float or [float, float] as [r, theta])
169            @return: (DAB value)
170        """
171        #Reset radius of model2 just before the run
172        effective_radius = None   
173        effective_radius = self.model1.calculate_ER()
174        if effective_radius !=None:         
175            self.model2.setParam( 'effect_radius',effective_radius)
176       
177        return self.model1.run(x)*self.model2.run(x)
178   
179    def runXY(self, x = 0.0):
180        """ Evaluate the model
181            @param x: input q-value (float or [float, float] as [qx, qy])
182            @return: DAB value
183        """
184       
185        #Reset radius of model2 just before the run
186        effective_radius = None   
187        effective_radius = self.model1.calculate_ER()
188        if effective_radius !=None:         
189            self.model2.setParam( 'effect_radius',effective_radius)
190
191        return self.model1.runXY(x)* self.model2.runXY(x)
192   
193    def set_dispersion(self, parameter, dispersion):
194        """
195            Set the dispersion object for a model parameter
196            @param parameter: name of the parameter [string]
197            @dispersion: dispersion object of type DispersionModel
198        """
199        value= None
200        try:
201            if parameter in self.model1.dispersion.keys():
202                value= self.model1.set_dispersion(parameter, dispersion)
203            #There is no dispersion for the structure factors(S(Q)).
204            #ToDo: need to decide whether or not the dispersion for S(Q) has to be considered for P*S. 
205            #elif parameter in self.model2.dispersion.keys():
206            #    if item != 'effect_radius':
207            #        value= self.model2.set_dispersion(parameter, dispersion)
208            self._set_dispersion()
209            return value
210        except:
211            raise 
212
213    def fill_description(self, model1, model2):
214        """
215            Fill the description for P(Q)*S(Q)
216        """
217        description = ""
218        description += "Note:1) The effect_radius (effective radius) of %s \n"% (model2.name)
219        description +="             is automatically calculated from size parameters (radius...).\n"
220        description += "         2) For non-spherical shape, this approximation is valid \n"
221        description += "            only for highly dilute systems. Thus, use it at your own risk.\n"
222        description +="See %s description and %s description \n"%( model1.name,model2.name )
223        description += "        for details."
224        self.description += description
225   
Note: See TracBrowser for help on using the repository browser.