source: sasview/sansmodels/src/sans/models/MultiplicationModel.py @ 4785dec

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 4785dec 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
RevLine 
[c9636f7]1
2from sans.models.BaseComponent import BaseComponent
3import numpy, math
[a68efd1]4import copy
[3740b11]5from sans.models.pluginmodel import Model1DPlugin
[c9636f7]6class MultiplicationModel(BaseComponent):
7    """
[8b677ec]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.
[c9636f7]10        Contains the models parameters combined.
11    """
12    def __init__(self, model1, model2 ):
13        BaseComponent.__init__(self)
14
[996fd35]15       
[8cfdd5e]16        ## Setting  model name model description
[996fd35]17        self.description=""
[8b677ec]18        if  model1.name != "NoStructure" and  model2.name != "NoStructure":
[996fd35]19             self.name = model1.name +" * "+ model2.name
20             self.description= self.name+"\n"
[8b677ec]21             self.fill_description(model1, model2)
[996fd35]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
[3740b11]28                       
[5eb9154]29       
[c9636f7]30        self.model1= model1
31        self.model2= model2
[5eb9154]32       
33       
[c9636f7]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() 
[5fc8e22]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:
[8b677ec]48                self.orientation_params.append(item)
[5fc8e22]49               
[5eb9154]50       
[a68efd1]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   
[c9636f7]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():
[8b677ec]74            ## All S(Q) has only 'effect_radius' for dispersion which
75            #    will not be allowed for now.
[5eb9154]76            if not name in self.dispersion.keys():
[59930f3]77                if name != 'effect_radius':
[5eb9154]78                    self.dispersion[name]= value
[3740b11]79
[5eb9154]80                   
81               
[c9636f7]82               
83    def _set_params(self):
84        """
85            Concatenate the parameters of the two models to create
86            this model parameters
87        """
[ab62adb]88        dia_rad = 0
[c9636f7]89        for name , value in self.model1.params.iteritems():
90            self.params[name]= value
[3740b11]91           
[c9636f7]92        for name , value in self.model2.params.iteritems():
[5eb9154]93            if not name in self.params.keys():
[8b677ec]94                #effect_radius is not treated as a parameter anymore.
[59930f3]95                if name != 'effect_radius': 
[5eb9154]96                    self.params[name]= value
[c9636f7]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():
[8b677ec]107            if not name in self.details.keys(): 
108                if name != 'effect_radius': 
109                    self.details[name]= detail
[c9636f7]110               
[8cfdd5e]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        """
[3740b11]118
119        self._setParamHelper( name, value)
120
[8cfdd5e]121        if name in self.model1.getParamList():
122            self.model1.setParam( name, value)
[ab62adb]123
[5eb9154]124        if name in self.model2.getParamList():
125            self.model2.setParam( name, value)
126
[24415e9]127        self._setParamHelper( name, value)
[8cfdd5e]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   
[c9636f7]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)
[8b677ec]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
[c9636f7]163        self.fixed.sort()
[5eb9154]164               
165               
[c9636f7]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        """
[5eb9154]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       
[3740b11]177        return self.model1.run(x)*self.model2.run(x)
[c9636f7]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        """
[8b677ec]184       
[5eb9154]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
[c9636f7]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        """
[db39b2a]199        value= None
200        try:
[c3e4a7fa]201            if parameter in self.model1.dispersion.keys():
[db39b2a]202                value= self.model1.set_dispersion(parameter, dispersion)
[5eb9154]203            #There is no dispersion for the structure factors(S(Q)).
[8077fc4]204            #ToDo: need to decide whether or not the dispersion for S(Q) has to be considered for P*S. 
[8b677ec]205            #elif parameter in self.model2.dispersion.keys():
206            #    if item != 'effect_radius':
207            #        value= self.model2.set_dispersion(parameter, dispersion)
[8077fc4]208            self._set_dispersion()
[db39b2a]209            return value
210        except:
211            raise 
[c9636f7]212
[8b677ec]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
[c9636f7]225   
Note: See TracBrowser for help on using the repository browser.