source: sasview/sansview/plugins/sum_p1_p2.py @ e42cc0e0

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 e42cc0e0 was 858d6ee, checked in by Jae Cho <jhjcho@…>, 13 years ago

renamed

  • Property mode set to 100644
File size: 12.5 KB
Line 
1# A sample of an experimental model function for Sum(Pmodel1,Pmodel2)
2import copy
3from sans.models.pluginmodel import Model1DPlugin
4# User can change the name of the model (only with single functional model)
5from sans.models.CylinderModel import CylinderModel as P1
6from sans.models.PolymerExclVolume import PolymerExclVolume as P2
7
8
9class Model(Model1DPlugin):
10    """
11    Use for p1(Q)+p2(Q);
12    Note: P(Q) refers to 'form factor' model.
13    """
14    name = ""
15    def __init__(self):
16        Model1DPlugin.__init__(self, name='')
17        """
18        :param p_model1: a form factor, P(Q)
19        :param p_model2: another form factor, P(Q)
20        """
21        p_model1 = P1()
22        p_model2 = P2()
23        ## Setting  model name model description
24        self.description=""
25        self.name = "Sum[" + "P1(Cyl)"  +", "+ "P2(PEV)" + "]"
26        self.description = p_model1.name+"\n"
27        self.description += p_model2.name+"\n"
28        self.fill_description(p_model1, p_model2)
29
30        ## Define parameters
31        self.params = {}
32
33        ## Parameter details [units, min, max]
34        self.details = {}
35       
36        # non-fittable parameters
37        self.non_fittable = p_model1.non_fittable 
38        self.non_fittable += p_model2.non_fittable 
39           
40        ##models
41        self.p_model1= p_model1
42        self.p_model2= p_model2
43       
44       
45        ## dispersion
46        self._set_dispersion()
47        ## Define parameters
48        self._set_params()
49        ## New parameter:Scaling factor
50        self.params['scale_factor'] = 1
51       
52        ## Parameter details [units, min, max]
53        self._set_details()
54        self.details['scale_factor'] = ['',     None, None]
55
56       
57        #list of parameter that can be fitted
58        self._set_fixed_params() 
59        ## parameters with orientation
60        for item in self.p_model1.orientation_params:
61            new_item = "p1_" + item
62            if not new_item in self.orientation_params:
63                self.orientation_params.append(new_item)
64           
65        for item in self.p_model2.orientation_params:
66            new_item = "p2_" + item
67            if not new_item in self.orientation_params:
68                self.orientation_params.append(new_item)
69        # get multiplicity if model provide it, else 1.
70        try:
71            multiplicity1 = p_model1.multiplicity
72            try:
73                multiplicity2 = p_model2.multiplicity
74            except:
75                multiplicity2 = 1
76        except:
77            multiplicity1 = 1
78            multiplicity2 = 1
79        ## functional multiplicity of the model
80        self.multiplicity1 = multiplicity1 
81        self.multiplicity2 = multiplicity2   
82        self.multiplicity_info = []   
83       
84    def _clone(self, obj):
85        """
86            Internal utility function to copy the internal
87            data members to a fresh copy.
88        """
89        obj.params     = copy.deepcopy(self.params)
90        obj.description     = copy.deepcopy(self.description)
91        obj.details    = copy.deepcopy(self.details)
92        obj.dispersion = copy.deepcopy(self.dispersion)
93        obj.p_model1  = self.p_model1.clone()
94        obj.p_model2  = self.p_model2.clone()
95        #obj = copy.deepcopy(self)
96        return obj
97   
98   
99    def _set_dispersion(self):
100        """
101           combined the two models dispersions
102           Polydispersion should not be applied to s_model
103        """
104        ##set dispersion only from p_model
105        for name , value in self.p_model1.dispersion.iteritems():
106            #if name.lower() not in self.p_model1.orientation_params:
107            new_name = "p1_" + name
108            self.dispersion[new_name]= value
109        for name , value in self.p_model2.dispersion.iteritems():
110            #if name.lower() not in self.p_model2.orientation_params:
111            new_name = "p2_" + name
112            self.dispersion[new_name]= value
113           
114    def function(self, x=0.0): 
115        """
116        """
117        return 0
118                               
119    def getProfile(self):
120        """
121        Get SLD profile of p_model if exists
122       
123        : return: (r, beta) where r is a list of radius of the transition points
124                beta is a list of the corresponding SLD values
125        : Note: This works only for func_shell# = 2 (exp function)
126                and is not supporting for p2
127        """
128        try:
129            x,y = self.p_model1.getProfile()
130        except:
131            x = None
132            y = None
133           
134        return x, y
135   
136    def _set_params(self):
137        """
138            Concatenate the parameters of the two models to create
139            this model parameters
140        """
141
142        for name , value in self.p_model1.params.iteritems():
143            # No 2D-supported
144            #if name not in self.p_model1.orientation_params:
145            new_name = "p1_" + name
146            self.params[new_name]= value
147           
148        for name , value in self.p_model2.params.iteritems():
149            # No 2D-supported
150            #if name not in self.p_model2.orientation_params:
151            new_name = "p2_" + name
152            self.params[new_name]= value
153               
154        # Set "scale" as initializing
155        self._set_scale_factor()
156     
157           
158    def _set_details(self):
159        """
160            Concatenate details of the two models to create
161            this model details
162        """
163        for name ,detail in self.p_model1.details.iteritems():
164            new_name = "p1_" + name
165            #if new_name not in self.orientation_params:
166            self.details[new_name]= detail
167           
168        for name ,detail in self.p_model2.details.iteritems():
169            new_name = "p2_" + name
170            #if new_name not in self.orientation_params:
171            self.details[new_name]= detail
172   
173    def _set_scale_factor(self):
174        """
175        Not implemented
176        """
177        pass
178       
179               
180    def setParam(self, name, value):
181        """
182        Set the value of a model parameter
183   
184        :param name: name of the parameter
185        :param value: value of the parameter
186        """
187        # set param to p1+p2 model
188        self._setParamHelper(name, value)
189       
190        ## setParam to p model
191        model_pre = name.split('_', 1)[0]
192        new_name = name.split('_', 1)[1]
193        if model_pre == "p1":
194            if new_name in self.p_model1.getParamList():
195                self.p_model1.setParam(new_name, value)
196        elif model_pre == "p2":
197             if new_name in self.p_model2.getParamList():
198                self.p_model2.setParam(new_name, value)
199        elif name.lower() == 'scale_factor':
200            self.params['scale_factor'] = value
201        else:
202            raise ValueError, "Model does not contain parameter %s" % name
203           
204    def getParam(self, name):
205        """
206        Set the value of a model parameter
207
208        :param name: name of the parameter
209       
210        """
211        # Look for dispersion parameters
212        toks = name.split('.')
213        if len(toks)==2:
214            for item in self.dispersion.keys():
215                # 2D not supported
216                if item.lower()==toks[0].lower():# and \
217                            #item.lower() not in self.orientation_params \
218                            #and toks[0].lower() not in self.orientation_params:
219                    for par in self.dispersion[item]:
220                        if par.lower() == toks[1].lower():
221                            return self.dispersion[item][par]
222        else:
223            # Look for standard parameter
224            for item in self.params.keys():
225                if item.lower()==name.lower():#and \
226                            #item.lower() not in self.orientation_params \
227                            #and toks[0].lower() not in self.orientation_params:
228                    return self.params[item]
229        return 
230        #raise ValueError, "Model does not contain parameter %s" % name
231       
232    def _setParamHelper(self, name, value):
233        """
234        Helper function to setparam
235        """
236        # Look for dispersion parameters
237        toks = name.split('.')
238        if len(toks)== 2:
239            for item in self.dispersion.keys():
240                if item.lower()== toks[0].lower():# and \
241                            #item.lower() not in self.orientation_params:
242                    for par in self.dispersion[item]:
243                        if par.lower() == toks[1].lower():#and \
244                                #item.lower() not in self.orientation_params:
245                            self.dispersion[item][par] = value
246                            return
247        else:
248            # Look for standard parameter
249            for item in self.params.keys():
250                if item.lower()== name.lower():#and \
251                            #item.lower() not in self.orientation_params:
252                    self.params[item] = value
253                    return
254           
255        raise ValueError, "Model does not contain parameter %s" % name
256             
257   
258    def _set_fixed_params(self):
259        """
260             fill the self.fixed list with the p_model fixed list
261        """
262        for item in self.p_model1.fixed:
263            new_item = "p1" + item
264            self.fixed.append(new_item)
265        for item in self.p_model2.fixed:
266            new_item = "p2" + item
267            self.fixed.append(new_item)
268
269        self.fixed.sort()
270               
271                   
272    def run(self, x = 0.0):
273        """
274        Evaluate the model
275       
276        :param x: input q-value (float or [float, float] as [r, theta])
277        :return: (scattering function value)
278        """
279        self._set_scale_factor()
280        return self.params['scale_factor'] * \
281                (self.p_model1.run(x) + self.p_model2.run(x))
282   
283    def runXY(self, x = 0.0):
284        """
285        Evaluate the model
286       
287        :param x: input q-value (float or [float, float] as [qx, qy])
288        :return: scattering function value
289        """ 
290        self._set_scale_factor()
291        return self.params['scale_factor'] * \
292                (self.p_model1.runXY(x) + self.p_model2.runXY(x))
293   
294    ## Now (May27,10) directly uses the model eval function
295    ## instead of the for-loop in Base Component.
296    def evalDistribution(self, x = []):
297        """
298        Evaluate the model in cartesian coordinates
299       
300        :param x: input q[], or [qx[], qy[]]
301        :return: scattering function P(q[])
302        """
303        self._set_scale_factor()
304        return self.params['scale_factor'] * \
305                    (self.p_model1.evalDistribution(x) + \
306                                 self.p_model2.evalDistribution(x))
307
308    def set_dispersion(self, parameter, dispersion):
309        """
310        Set the dispersion object for a model parameter
311       
312        :param parameter: name of the parameter [string]
313        :dispersion: dispersion object of type DispersionModel
314        """
315        value= None
316        new_pre = parameter.split("_", 1)[0]
317        new_parameter = parameter.split("_", 1)[1]
318        try:
319            if new_pre == 'p1' and \
320                            new_parameter in self.p_model1.dispersion.keys():
321                value= self.p_model1.set_dispersion(new_parameter, dispersion)
322            if new_pre == 'p2' and \
323                             new_parameter in self.p_model2.dispersion.keys():
324                value= self.p_model2.set_dispersion(new_parameter, dispersion)
325            self._set_dispersion()
326            return value
327        except:
328            raise 
329
330    def fill_description(self, p_model1, p_model2):
331        """
332        Fill the description for P(Q)+P(Q)
333        """
334        description = ""
335        description +="This model gives the summation of  %s and %s.\n"% \
336                                        ( p_model1.name, p_model2.name )
337        self.description += description
338       
339if __name__ == "__main__": 
340    m1= Model() 
341    m1.setParam("p1_scale", 25) 
342    m1.setParam("p1_length", 1000)
343    m1.setParam("p2_scale", 100) 
344    m1.setParam("p2_rg", 100) 
345    out1 = m1.runXY(0.01)
346
347    m2= Model()
348    m2.p_model1.setParam("scale", 25) 
349    m2.p_model1.setParam("length", 1000) 
350    m2.p_model2.setParam("scale", 100)
351    m2.p_model2.setParam("rg", 100)
352    out2 = m2.p_model1.runXY(0.01) + m2.p_model2.runXY(0.01)
353    print out1, " = ", out2
354
355   
Note: See TracBrowser for help on using the repository browser.