Changeset ae60f86 in sasview for sansmodels/src/sans/models
- Timestamp:
- Oct 14, 2008 8:13:28 AM (16 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 8809e48
- Parents:
- 4fe4394
- Location:
- sansmodels/src/sans/models
- Files:
-
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
sansmodels/src/sans/models/BaseComponent.py
rd30fdde rae60f86 1 1 #!/usr/bin/env python 2 """ Provide base functionality for all model components 3 @author: Mathieu Doucet / UTK 4 @contact: mathieu.doucet@nist.gov 2 """ 3 Provide base functionality for all model components 5 4 """ 6 5 7 # info8 __author__ = "Mathieu Doucet / UTK"9 __id__ = "$Id: BaseComponent.py,v 1.2 2007/03/14 21:04:40 doucet Exp $"10 11 6 # imports 12 7 import copy 13 8 14 9 class BaseComponent: 15 """ Basic model component16 Provides basic arithmetics10 """ 11 Basic model component 17 12 18 The supported operations are: add (+), subtract (-), multiply (*) and divide (/). 19 20 Here's an arithmetics example to define a function 21 f = ( 1+sin(x) )**2 + 3.0 22 and evaluate it at 1.4. 23 24 25 sin = Sin() 26 const1 = Constant() 27 const2 = Constant() 28 const2.setParam('value', 3.0) 29 30 func = (const1 + sin)*(const1 + sin) + const2 31 32 print func(1.4) 33 13 Since version 0.5.0, basic operations are no longer supported. 34 14 """ 35 15 … … 39 19 ## Name of the model 40 20 self.name = "BaseComponent" 41 ## Component left of operator42 self.operateOn = None43 ## Component right of operator44 self.other = None45 46 21 47 22 ## Parameters to be accessed by client … … 53 28 54 29 def __str__(self): 55 """ Prints an XML representation of the model30 """ 56 31 @return: string representation 57 32 """ 58 33 return self.name 59 34 60 def run(self, x=0): #pylint: disable-msg=R0201 61 """ Evaluate the model 62 Dummy function 63 @param x: input value 64 @return: value of the model 65 """ 66 return 0 35 def run(self, x): return NotImplemented 36 def runXY(self, x): return NotImplemented 67 37 68 38 def clone(self): … … 70 40 71 41 obj = copy.deepcopy(self) 72 obj.params = copy.deepcopy(self.params) 73 obj.details = copy.deepcopy(self.details) 42 obj.params = copy.deepcopy(self.params) 43 obj.details = copy.deepcopy(self.details) 44 obj.dispersion = copy.deepcopy(self.dispersion) 74 45 75 # Check for standard data members of arithmetics sub-classes76 if hasattr(self, 'operateOn') and \77 not self.operateOn == None:78 obj.operateOn = self.operateOn.clone()79 80 if hasattr(self, 'other') and \81 not self.other == None:82 obj.other = self.other.clone()83 84 46 return obj 85 47 86 def __add__(self, other): 87 """ Overload addition operator 88 @param other: model to add 89 """ 90 from sans.models.AddComponent import AddComponent 91 return AddComponent(self.clone(), other) 48 def setParam(self, name, value): 49 """ 50 Set the value of a model parameter 92 51 93 def __sub__(self, other):94 """ Overload subtraction operator95 @param other: model to subtract96 """97 from sans.models.SubComponent import SubComponent98 return SubComponent(self.clone(), other)99 100 def __mul__(self, other):101 """ Overload multiplication operator102 @param other: model to multiply103 """104 from sans.models.MulComponent import MulComponent105 return MulComponent(self.clone(), other)106 107 def __div__(self, other):108 """ Overload division operator109 @param other: mode to divide by110 """111 from sans.models.DivComponent import DivComponent112 return DivComponent(self.clone(), other)113 114 def setParam(self, name, value):115 """ Set the value of a model parameter116 117 A list of all the parameters of a model can118 be obtained with the getParamList() method.119 For models resulting from an arithmetic120 operation between two models, the names of121 the parameters are modified according to122 the following rule:123 124 For parameter 'a' of model A and125 parameter 'b' of model B:126 127 C = A + B128 C.setParam('base.a') to access 'a'129 C.setParam('add.b') to access 'b'130 131 C = A - B132 C.setParam('base.a') to access 'a'133 C.setParam('sub.b') to access 'b'134 135 C = A * B136 C.setParam('base.a') to access 'a'137 C.setParam('mul.b') to access 'b'138 139 C = A / B140 C.setParam('base.a') to access 'a'141 C.setParam('div.b') to access 'b'142 143 52 @param name: name of the parameter 144 53 @param value: value of the parameter 145 54 """ 146 # Lowercase for case insensitivity 147 name = name.lower() 55 # Look for dispersion parameters 56 toks = name.split('.') 57 if len(toks)==2: 58 for item in self.dispersion.keys(): 59 if item.lower()==toks[0].lower(): 60 for par in self.dispersion[item]: 61 if par.lower() == toks[1].lower(): 62 self.dispersion[item][par] = value 63 return 64 else: 65 # Look for standard parameter 66 for item in self.params.keys(): 67 if item.lower()==name.lower(): 68 self.params[item] = value 69 return 70 71 raise ValueError, "Model does not contain parameter %s" % name 148 72 149 keys = self.params.keys() 150 found = False 73 74 def _setParam(self, name, value): 75 """ 76 Set the value of a model parameter 151 77 152 # Loop through the keys and find the right one153 # The case should not matter154 for key in keys:155 if name == key.lower():156 self.params[key] = value157 found = True158 break159 160 # Check whether we found the key161 if not found:162 raise ValueError, "Model does not contain parameter %s" % name163 164 def setParamWithToken(self, name, value, token, member):165 """166 Returns value of a parameter that is part of an internal component167 @param name: name of the parameter168 @param value: value of the parameter169 @param token: parameter prefix170 @param member: data member pointing to the component171 """172 # Lowercase for case insensitivity173 name = name.lower()174 175 # Look for sub-model access176 toks = name.split('.')177 if len(toks)>1:178 short_name = '.'.join(toks[1:])179 if toks[0] == 'base':180 return self.operateOn.setParam(short_name, value)181 elif toks[0] == token:182 return member.setParam(short_name, value)183 else:184 raise ValueError, "Model does not contain parameter %s" % name185 186 # If we didn't find a token we know, call the default behavior187 return BaseComponent.setParam(self, name, value)188 189 190 def getParam(self, name):191 """ Set the value of a model parameter192 193 A list of all the parameters of a model can194 be obtained with the getParamList() method.195 For models resulting from an arithmetic196 operation between two models, the names of197 the parameters are modified according to198 the following rule:199 200 For parameter 'a' of model A and201 parameter 'b' of model B:202 203 C = A + B204 C.getParam('base.a') to access 'a'205 C.getParam('add.b') to access 'b'206 207 C = A - B208 C.getParam('base.a') to access 'a'209 C.getParam('sub.b') to access 'b'210 211 C = A * B212 C.getParam('base.a') to access 'a'213 C.getParam('mul.b') to access 'b'214 215 C = A / B216 C.getParam('base.a') to access 'a'217 C.getParam('div.b') to access 'b'218 219 78 @param name: name of the parameter 220 79 @param value: value of the parameter 221 80 """ 222 # Lowercase for case insensitivity 223 name = name.lower() 81 # Look for dispersion parameters 82 toks = name.split('.') 83 if len(toks)==2 and toks[0] in self.dispersion: 84 # Setting a dispersion model parameter 85 if toks[1] in self.dispersion[toks[0]]: 86 self.dispersion[toks[0]][toks[1]] = value 87 return 88 else: 89 raise ValueError, "Model does not contain parameter %s.%s" % (toks[0], toks[1]) 224 90 225 keys = self.params.keys() 226 value = None 227 228 # Loop through the keys and find the right one 229 # The case should not matter 230 for key in keys: 231 if name == key.lower(): 232 value = self.params[key] 233 break 234 235 # Check whether we found the key 236 if value == None: 91 if name in self.params.keys(): 92 self.params[name] = value 93 else: 237 94 raise ValueError, "Model does not contain parameter %s" % name 238 95 239 return value 96 def _getParam(self, name): 97 """ 98 Set the value of a model parameter 99 100 @param name: name of the parameter 101 """ 102 # Look for dispersion parameters 103 toks = name.split('.') 104 if len(toks)==2 and toks[0] in self.dispersion: 105 # Setting a dispersion model parameter 106 if toks[1] in self.dispersion[toks[0]]: 107 return self.dispersion[toks[0]][toks[1]] 108 else: 109 raise ValueError, "Model does not contain parameter %s.%s" % (toks[0], toks[1]) 110 111 if name in self.params.keys(): 112 return self.params[name] 113 else: 114 raise ValueError, "Model does not contain parameter %s" % name 240 115 241 def getParamWithToken(self, name, token, member): 116 def getParam(self, name): 117 """ 118 Set the value of a model parameter 119 120 @param name: name of the parameter 242 121 """ 243 Returns value of a parameter that is part of an internal component 244 @param name: name of the parameter 245 @param token: parameter prefix 246 @param member: data member pointing to the component 247 @return: value of the parameter 248 """ 249 # Lowercase for case insensitivity 250 name = name.lower() 122 # Look for dispersion parameters 123 toks = name.split('.') 124 if len(toks)==2: 125 for item in self.dispersion.keys(): 126 if item.lower()==toks[0].lower(): 127 for par in self.dispersion[item]: 128 if par.lower() == toks[1].lower(): 129 return self.dispersion[item][par] 130 else: 131 # Look for standard parameter 132 for item in self.params.keys(): 133 if item.lower()==name.lower(): 134 return self.params[item] 135 136 raise ValueError, "Model does not contain parameter %s" % name 137 138 def getParamList(self): 139 """ 140 Return a list of all available parameters for the model 141 """ 142 list = self.params.keys() 143 # WARNING: Extending the list with the dispersion parameters 144 list.extend(self.getDispParamList()) 145 return list 146 147 def getDispParamList(self): 148 """ 149 Return a list of all available parameters for the model 150 """ 151 list = [] 251 152 252 # Look for sub-model access 253 toks = name.split('.') 254 if len(toks)>1: 255 #short_name = string.join(toks[1:],'.') 256 short_name = '.'.join(toks[1:]) 257 if toks[0] == 'base': 258 return self.operateOn.getParam(short_name) 259 elif toks[0] == token: 260 return member.getParam(short_name) 261 else: 262 raise ValueError, "Model does not contain parameter %s" % name 263 264 # If we didn't find a token we know, call the default behavior 265 return BaseComponent.getParam(self, name) 153 for item in self.dispersion.keys(): 154 for p in self.dispersion[item].keys(): 155 if p not in ['type']: 156 list.append('%s.%s' % (item.lower(), p.lower())) 157 158 return list 159 160 # Old-style methods that are no longer used 161 def setParamWithToken(self, name, value, token, member): return NotImplemented 162 def getParamWithToken(self, name, token, member): return NotImplemented 163 def getParamListWithToken(self, token, member): return NotImplemented 164 def __add__(self, other): raise ValueError, "Model operation are no longer supported" 165 def __sub__(self, other): raise ValueError, "Model operation are no longer supported" 166 def __mul__(self, other): raise ValueError, "Model operation are no longer supported" 167 def __div__(self, other): raise ValueError, "Model operation are no longer supported" 266 168 267 268 def getParamList(self):269 """ Return a list of all available parameters for the model270 271 For models resulting from an arithmetic272 operation between two models, the names of273 the parameters are modified according to274 the following rule:275 276 For parameter 'a' of model A and277 parameter 'b' of model B:278 279 C = A + B280 C.getParam('base.a') to access 'a'281 C.getParam('add.b') to access 'b'282 283 C = A - B284 C.getParam('base.a') to access 'a'285 C.getParam('sub.b') to access 'b'286 287 C = A * B288 C.getParam('base.a') to access 'a'289 C.getParam('mul.b') to access 'b'290 291 C = A / B292 C.getParam('base.a') to access 'a'293 C.getParam('div.b') to access 'b'294 295 """296 param_list = self.params.keys()297 return param_list298 299 def getParamListWithToken(self, token, member):300 """301 Return a list of all available parameters for the model302 303 @param token: parameter prefix304 @param member: data member pointing to internal component305 @return: list of parameters306 """307 param_list = self.params.keys()308 if not self.operateOn == None:309 sub_list = self.operateOn.params.keys()310 for p in sub_list:311 param_list.append("base.%s" % p)312 if not member == None:313 sub_list = member.params.keys()314 for p in sub_list:315 param_list.append("%s.%s" % (token, p))316 return param_list317 318 # End of file -
sansmodels/src/sans/models/BaseModel.py
r1b162dfa rae60f86 64 64 ## Name of the model 65 65 name = "BaseModel" 66 ## Dictionary of Parameter objects 67 parameters = {} 66 67 def __init__(self): 68 ## Dictionary of Parameter objects 69 self.parameters = {} 70 71 for item in self.params: 72 self.parameters[item] = Parameter(item, self.params[item]) 73 74 68 75 69 76 # Evaluation methods to be implemented by the models … … 97 104 # Lowercase for case insensitivity 98 105 name = name.lower() 99 return object.__setattribute__(self, name, value) 106 if name in self.parameters: 107 print "found" 108 return object.__setattr__(self, name, value) 100 109 101 110 def getParam(self, name): -
sansmodels/src/sans/models/ModelAdaptor.py
r1b162dfa rae60f86 62 62 ## Provided for backward compatibility 63 63 self.dispersion = {} 64 65 def __getattribute__(self, name): 66 """ 67 Provide additional information when accessing old-style 68 data members. 69 """ 70 if name in ['operateOn', 'other']: 71 raise AttributeError, "Model operation are no longer supported" 72 73 return object.__getattribute__(self, name) 74 64 75 65 # Old-style methods that are no longer used 76 66 def setParamWithToken(self, name, value, token, member): return NotImplemented -
sansmodels/src/sans/models/NewCylinderModel.py
r1b162dfa rae60f86 46 46 47 47 # Initialize BaseComponent first, then sphere 48 CCylinderModel.__init__(self) 48 49 BaseModel.__init__(self) 49 CCylinderModel.__init__(self)50 50 51 51 ## Name of the model -
sansmodels/src/sans/models/test/testcase_generator.py
r36948c92 rae60f86 2 2 Random test-case generator for BaseComponents 3 3 4 @author: Mathieu Doucet / UTK5 @license: This software is provided as part of the DANSE project.6 4 """ 7 5 import time … … 760 758 761 759 if __name__ == '__main__': 762 760 print "Model operations are no longer supported." 761 print "The TestCase generator for model operation can't be used with this version of sansmodels." 762 763 763 764 #print randomModel() 764 g = TestCaseGenerator()765 g.generateAndRun(20000)765 #g = TestCaseGenerator() 766 #g.generateAndRun(20000) 766 767 767 768 #t = TestCase(filename = "error_1.17721e+009.xml") -
sansmodels/src/sans/models/test/utest_dispersity.py
r0f5bc9f rae60f86 47 47 self.assertAlmostEqual(self.model.run(0.001), 4723.32213339, 3) 48 48 self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 4743.56, 2) 49 50 def test_gaussian_zero(self): 51 from sans.models.dispersion_models import GaussianDispersion 52 disp = GaussianDispersion() 53 self.model.set_dispersion('radius', disp) 54 self.model.dispersion['radius']['width'] = 0.0 55 self.model.dispersion['radius']['npts'] = 100 56 self.model.setParam('scale', 1.0) 57 58 self.assertAlmostEqual(self.model.run(0.001), 450.355, 3) 59 self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 452.299, 3) 49 60 50 61 def test_array(self): … … 429 440 self.assertTrue(math.fabs(val_1d-val_2d)/val_1d < 0.02) 430 441 442 class TestDispModel(unittest.TestCase): 443 def setUp(self): 444 from sans.models.CylinderModel import CylinderModel 445 self.model = CylinderModel() 446 447 448 def test_disp_params(self): 449 450 self.assertEqual(self.model.dispersion['radius']['width'], 0.0) 451 self.model.setParam('radius.width', 5.0) 452 self.assertEqual(self.model.dispersion['radius']['width'], 5.0) 453 self.assertEqual(self.model.getParam('radius.width'), 5.0) 454 self.assertEqual(self.model.dispersion['radius']['type'], 'gaussian') 431 455 432 456 -
sansmodels/src/sans/models/test/utest_models.py
raf03ddd rae60f86 66 66 67 67 def testIO_add(self): 68 # version 0.5.0: No longer supported 69 return 68 70 from sans.models.ModelFactory import ModelFactory 69 71 from sans.models.ModelIO import ModelIO … … 79 81 80 82 def testIO_add2(self): 83 # version 0.5.0: No longer supported 84 return 81 85 from sans.models.ModelFactory import ModelFactory 82 86 #from sans.models.ModelIO import ModelIO … … 109 113 self.assertAlmostEqual(self.comp.run(0.2), 0.041761386790780453, 4) 110 114 111 class TestAddition(unittest.TestCase):112 """Unit tests for Model Factory"""113 114 def setUp(self):115 from sans.models.ModelFactory import ModelFactory116 self.comp1 = ModelFactory().getModel('CylinderModel')117 self.comp2 = ModelFactory().getModel('CylinderModel')118 self.comp3 = self.comp1+self.comp2119 120 def test1D(self):121 """ Test 1D model of a cylinder """122 self.assertAlmostEqual(self.comp3.run(0.2), 2*0.041761386790780453, 4)123 124 115 125 116 class TestGaussian(unittest.TestCase): … … 230 221 231 222 def testFunction(self): 223 # version 0.5.0: No longer supported 224 return 232 225 from sans.models.Sin import Sin 233 226 s = Sin() -
sansmodels/src/sans/models/test/utest_newstylemodels.py
r1b162dfa rae60f86 3 3 C++ model classes 4 4 """ 5 5 print "New style models are still under development" 6 6 import unittest, math, numpy 7 7 … … 22 22 return self.params['scale']*x 23 23 24 from BaseModel import BaseModel24 from sans.models.BaseModel import BaseModel,ParameterProperty 25 25 class NewTestModel(BaseModel): 26 26 scale = ParameterProperty('scale') … … 57 57 """ 58 58 def setUp(self): 59 from sans.models.NewCylinderModel import NewCylinderModel60 self.model = NewCylinderModel()59 from sans.models.NewCylinderModel import CylinderModel 60 self.model = CylinderModel() 61 61 62 62 63 63 def test_setparam(self): 64 pass 64 self.model.setParam("length", 151.0) 65 self.assertEquals(self.model.getParam("length"), 151.0) 66 67 68 print self.model.parameters 69 70 print self.model(0.001) 71 self.model.setParam("length", 250.0) 72 print self.model(0.001) 65 73 66 74
Note: See TracChangeset
for help on using the changeset viewer.