[ae3ce4e] | 1 | """ |
---|
| 2 | Unit tests for BaseComponent |
---|
| 3 | @author: Mathieu Doucet / UTK |
---|
| 4 | """ |
---|
| 5 | # Disable "missing docstring" complaint |
---|
| 6 | # pylint: disable-msg=C0111 |
---|
| 7 | # Disable "too many methods" complaint |
---|
| 8 | # pylint: disable-msg=R0904 |
---|
| 9 | |
---|
| 10 | |
---|
| 11 | import unittest, math |
---|
| 12 | from sans.models.BaseComponent import BaseComponent |
---|
| 13 | |
---|
| 14 | class ConstantComponent(BaseComponent): |
---|
| 15 | """ Test component """ |
---|
| 16 | def __init__(self, value=0): |
---|
| 17 | BaseComponent.__init__(self) |
---|
| 18 | self.params['value'] = value |
---|
| 19 | self.dim = 0 |
---|
| 20 | self.name = 'constant' |
---|
| 21 | def run(self, x=0): |
---|
| 22 | """ Evaluate method """ |
---|
| 23 | return self.params['value'] |
---|
| 24 | |
---|
| 25 | class IdentityComponent(BaseComponent): |
---|
| 26 | """ Test identity component """ |
---|
| 27 | def __init__(self): |
---|
| 28 | BaseComponent.__init__(self) |
---|
| 29 | self.dim = 1 |
---|
| 30 | self.name = 'id' |
---|
| 31 | def run(self, x=0): |
---|
| 32 | """ Evaluate method """ |
---|
| 33 | return x |
---|
| 34 | |
---|
| 35 | class SinComponent(BaseComponent): |
---|
| 36 | """ Test sin(x) component """ |
---|
| 37 | def __init__(self): |
---|
| 38 | BaseComponent.__init__(self) |
---|
| 39 | self.params['norm'] = 1 |
---|
| 40 | self.dim = 1 |
---|
| 41 | self.name = 'sin' |
---|
| 42 | def run(self, x=0): |
---|
| 43 | """ Evaluate method """ |
---|
| 44 | return self.params['norm']*math.sin(x) |
---|
| 45 | |
---|
| 46 | class TwoDimComponent(BaseComponent): |
---|
| 47 | """ Test 2D component """ |
---|
| 48 | def __init__(self): |
---|
| 49 | BaseComponent.__init__(self) |
---|
| 50 | self.params['norm'] = 1 |
---|
| 51 | self.dim = 2 |
---|
| 52 | self.name = '2D' |
---|
| 53 | def run(self, x): |
---|
| 54 | """ Evaluate method """ |
---|
| 55 | return self.params['norm']*x[0]*math.sin(x[1]) |
---|
| 56 | |
---|
| 57 | class ThreeDimComponent(BaseComponent): |
---|
| 58 | """ Test 3D component """ |
---|
| 59 | def __init__(self): |
---|
| 60 | BaseComponent.__init__(self) |
---|
| 61 | self.params['norm'] = 1 |
---|
| 62 | self.dim = 3 |
---|
| 63 | self.name = '3D' |
---|
| 64 | def run(self, x): |
---|
| 65 | """ Evaluate method """ |
---|
| 66 | return self.params['norm']*x[0]*math.sin(x[1])*x[2]*x[2] |
---|
| 67 | |
---|
| 68 | |
---|
| 69 | |
---|
| 70 | class TestBasicComponent(unittest.TestCase): |
---|
| 71 | |
---|
| 72 | def setUp(self): |
---|
| 73 | self.comp = BaseComponent() |
---|
| 74 | |
---|
| 75 | def testrun(self): |
---|
| 76 | input = 45 |
---|
| 77 | self.assertEqual(self.comp.run(input), 0) |
---|
| 78 | |
---|
| 79 | class TestArithmetic(unittest.TestCase): |
---|
| 80 | def setUp(self): |
---|
| 81 | self.value1 = 5 |
---|
| 82 | self.comp1 = ConstantComponent(self.value1) |
---|
| 83 | |
---|
| 84 | self.value2 = 7 |
---|
| 85 | self.comp2 = ConstantComponent(self.value2) |
---|
| 86 | |
---|
| 87 | def testrun(self): |
---|
| 88 | self.assertEqual(self.comp1.run(45), self.value1) |
---|
| 89 | |
---|
| 90 | def testadd(self): |
---|
| 91 | newcomp = self.comp1+self.comp2 |
---|
| 92 | self.assertEqual(newcomp.run(45), self.value1+self.value2) |
---|
| 93 | |
---|
| 94 | def testmultiply(self): |
---|
| 95 | newcomp = self.comp1*self.comp2 |
---|
| 96 | self.assertEqual(newcomp.run(45), self.value1*self.value2) |
---|
| 97 | |
---|
| 98 | def testsubtract(self): |
---|
| 99 | newcomp = self.comp1-self.comp2 |
---|
| 100 | self.assertEqual(newcomp.run(45), self.value1-self.value2) |
---|
| 101 | |
---|
| 102 | def testdivide(self): |
---|
| 103 | newcomp = self.comp1/self.comp2 |
---|
| 104 | self.assertEqual(newcomp.run(45), self.value1/self.value2) |
---|
| 105 | print newcomp |
---|
| 106 | |
---|
| 107 | def vtestcomplic1(self): |
---|
| 108 | val = (self.value1+self.value2)/self.value2 |
---|
| 109 | newcomp = (self.comp1+self.comp2) |
---|
| 110 | newcomp2 = newcomp/self.comp2 |
---|
| 111 | self.assertEqual(newcomp2.run(45), val) |
---|
| 112 | |
---|
| 113 | def testcomplic2(self): |
---|
| 114 | # A + B |
---|
| 115 | newcomp = self.comp1+self.comp2 |
---|
| 116 | # Value of A |
---|
| 117 | self.assertEqual(newcomp.operateOn.params['value'], self.value1) |
---|
| 118 | # Value of B |
---|
| 119 | self.assertEqual(newcomp.other.params['value'], self.value2) |
---|
| 120 | # Value of D = A+B |
---|
| 121 | self.assertEqual(newcomp.run(), self.value1+self.value2) |
---|
| 122 | # D + C |
---|
| 123 | newcomp2 = newcomp+self.comp2 |
---|
| 124 | # Value of D |
---|
| 125 | self.assertEqual(newcomp2.operateOn.run(), self.value1+self.value2) |
---|
| 126 | # Value of B |
---|
| 127 | self.assertEqual(newcomp2.other.params['value'], self.value2) |
---|
| 128 | |
---|
| 129 | |
---|
| 130 | self.assertEqual(newcomp2.run(45), self.value1+self.value2+self.value2) |
---|
| 131 | |
---|
| 132 | def testcomplic3(self): |
---|
| 133 | # Same as testcomplic2, but all in one go |
---|
| 134 | newcomp = self.comp1+self.comp2+self.comp2 |
---|
| 135 | self.assertEqual(newcomp.run(45), self.value1+self.value2+self.value2) |
---|
| 136 | |
---|
| 137 | def testcomplic4(self): |
---|
| 138 | output = (self.value1+self.value1)/(self.value1+self.value2) |
---|
| 139 | newcomp = (self.comp1+self.comp1)/(self.comp1+self.comp2) |
---|
| 140 | self.assertEqual(newcomp.run(45), output) |
---|
| 141 | |
---|
| 142 | class TestIO(unittest.TestCase): |
---|
| 143 | def setUp(self): |
---|
| 144 | from sans.models.ModelFactory import ModelFactory |
---|
| 145 | from sans.models.ModelIO import ModelIO |
---|
| 146 | self.factory = ModelFactory() |
---|
| 147 | self.io = ModelIO(self.factory) |
---|
| 148 | self.sph = self.factory.getModel("SphereModel") |
---|
| 149 | self.cyl = self.factory.getModel("CylinderModel") |
---|
| 150 | |
---|
| 151 | |
---|
| 152 | def saveLoadAndCompare(self, combo): |
---|
| 153 | # Save |
---|
| 154 | self.io.save(combo,"test_io.xml") |
---|
| 155 | # Load |
---|
| 156 | loaded = self.io.load("test_io.xml") |
---|
| 157 | |
---|
| 158 | # Check that the model is the same |
---|
| 159 | # ONLY WORKS FOR DEFAULT PARAMETERS |
---|
| 160 | # print combo.run(1) |
---|
| 161 | self.assertEqual(combo.run(1), loaded.run(1)) |
---|
| 162 | return loaded |
---|
| 163 | |
---|
| 164 | def testSimple(self): |
---|
| 165 | self.saveLoadAndCompare(self.sph) |
---|
| 166 | |
---|
| 167 | def testAdd(self): |
---|
| 168 | combo = self.sph+self.cyl |
---|
| 169 | self.saveLoadAndCompare(combo) |
---|
| 170 | |
---|
| 171 | def testSub(self): |
---|
| 172 | combo = self.sph-self.cyl |
---|
| 173 | self.saveLoadAndCompare(combo) |
---|
| 174 | |
---|
| 175 | def testMul(self): |
---|
| 176 | combo = self.sph*self.cyl |
---|
| 177 | self.saveLoadAndCompare(combo) |
---|
| 178 | |
---|
| 179 | def testDiv(self): |
---|
| 180 | combo = self.sph/self.cyl |
---|
| 181 | self.saveLoadAndCompare(combo) |
---|
| 182 | |
---|
| 183 | def testDegree2(self): |
---|
| 184 | combo = (self.sph+self.sph)/self.cyl |
---|
| 185 | self.saveLoadAndCompare(combo) |
---|
| 186 | |
---|
| 187 | def testDegree3(self): |
---|
| 188 | combo = self.sph*(self.cyl+self.sph/self.cyl) |
---|
| 189 | self.saveLoadAndCompare(combo) |
---|
| 190 | |
---|
| 191 | def testReSave(self): |
---|
| 192 | combo = self.sph+self.cyl |
---|
| 193 | loaded = self.saveLoadAndCompare(combo) |
---|
| 194 | self.saveLoadAndCompare(loaded) |
---|
| 195 | |
---|
| 196 | class TestGetSet(unittest.TestCase): |
---|
| 197 | def setUp(self): |
---|
| 198 | from sans.models.ModelFactory import ModelFactory |
---|
| 199 | self.factory = ModelFactory() |
---|
| 200 | self.sph = self.factory.getModel("SphereModel") |
---|
| 201 | |
---|
| 202 | def testGet(self): |
---|
| 203 | # The default value is 1.0e-6 |
---|
| 204 | self.assertEqual(self.sph.getParam("scale"), 1.0e-6) |
---|
| 205 | |
---|
| 206 | def testGetCaseSensitivity(self): |
---|
| 207 | # The default value is 1.0e-6 |
---|
| 208 | self.assertEqual(self.sph.getParam("sCale"), 1.0e-6) |
---|
| 209 | |
---|
| 210 | def testGetException(self): |
---|
| 211 | self.assertRaises(ValueError, self.sph.getParam, "scalee") |
---|
| 212 | |
---|
| 213 | def testSet(self): |
---|
| 214 | value_0 = self.sph.run(1) |
---|
| 215 | scale = 2.0e-6 |
---|
| 216 | self.sph.setParam("scale", scale) |
---|
| 217 | self.assertEqual(self.sph.getParam("scale"), scale) |
---|
| 218 | self.assertEqual(self.sph.run(1), 2*value_0) |
---|
| 219 | |
---|
| 220 | def testSetCaseSensitivity(self): |
---|
| 221 | value_0 = self.sph.run(1) |
---|
| 222 | scale = 2.0e-6 |
---|
| 223 | self.sph.setParam("sCale", scale) |
---|
| 224 | self.assertEqual(self.sph.getParam("scale"), scale) |
---|
| 225 | self.assertEqual(self.sph.run(1), 2*value_0) |
---|
| 226 | |
---|
| 227 | def testSetException(self): |
---|
| 228 | self.assertRaises(ValueError, self.sph.setParam, "scalee", 2.0) |
---|
| 229 | |
---|
| 230 | def testCompositeAdd(self): |
---|
| 231 | sph2 = self.factory.getModel("SphereModel") |
---|
| 232 | sph2.setParam("scale", 2.0e-6) |
---|
| 233 | model = sph2+self.sph |
---|
| 234 | self.assertEqual(model.getParam('Base.scale'), 2.0e-6) |
---|
| 235 | self.assertEqual(model.getParam('add.scale'), 1.0e-6) |
---|
| 236 | |
---|
| 237 | def testCompositeSub(self): |
---|
| 238 | sph2 = self.factory.getModel("SphereModel") |
---|
| 239 | sph2.setParam("scale", 2.0e-6) |
---|
| 240 | model = sph2-self.sph |
---|
| 241 | self.assertEqual(model.getParam('Base.scale'), 2.0e-6) |
---|
| 242 | self.assertEqual(model.getParam('sub.scale'), 1.0e-6) |
---|
| 243 | |
---|
| 244 | def testCompositeMul(self): |
---|
| 245 | sph2 = self.factory.getModel("SphereModel") |
---|
| 246 | sph2.setParam("scale", 2.0e-6) |
---|
| 247 | model = sph2*self.sph |
---|
| 248 | self.assertEqual(model.getParam('Base.scale'), 2.0e-6) |
---|
| 249 | self.assertEqual(model.getParam('mul.scale'), 1.0e-6) |
---|
| 250 | |
---|
| 251 | def testCompositeDiv(self): |
---|
| 252 | sph2 = self.factory.getModel("SphereModel") |
---|
| 253 | sph2.setParam("scale", 2.0e-6) |
---|
| 254 | model = sph2/self.sph |
---|
| 255 | self.assertEqual(model.getParam('Base.scale'), 2.0e-6) |
---|
| 256 | self.assertEqual(model.getParam('div.scale'), 1.0e-6) |
---|
| 257 | |
---|
| 258 | def testSetCompositeAdd(self): |
---|
| 259 | sph2 = self.factory.getModel("SphereModel") |
---|
| 260 | #sph2.setParam("scale", 2.0e-6) |
---|
| 261 | model = sph2+self.sph |
---|
| 262 | value = model.run(1) |
---|
| 263 | scale = 2.0e-6 |
---|
| 264 | model.setParam("base.scale", scale) |
---|
| 265 | model.setParam("add.scale", scale) |
---|
| 266 | |
---|
| 267 | self.assertEqual(model.getParam("base.scale"), scale) |
---|
| 268 | self.assertEqual(model.getParam("add.scale"), scale) |
---|
| 269 | self.assertEqual(model.run(1), 2*value) |
---|
| 270 | |
---|
| 271 | def testSetCompositeSub(self): |
---|
| 272 | sph2 = self.factory.getModel("SphereModel") |
---|
| 273 | #sph2.setParam("scale", 2.0e-6) |
---|
| 274 | model = sph2-self.sph |
---|
| 275 | value = model.run(1) |
---|
| 276 | scale = 2.0e-6 |
---|
| 277 | model.setParam("base.scale", scale) |
---|
| 278 | model.setParam("sub.scale", scale) |
---|
| 279 | |
---|
| 280 | self.assertEqual(model.getParam("base.scale"), scale) |
---|
| 281 | self.assertEqual(model.getParam("sub.scale"), scale) |
---|
| 282 | self.assertEqual(model.run(1), 2*value) |
---|
| 283 | |
---|
| 284 | def testSetCompositeMul(self): |
---|
| 285 | sph2 = self.factory.getModel("SphereModel") |
---|
| 286 | #sph2.setParam("scale", 2.0e-6) |
---|
| 287 | model = sph2*self.sph |
---|
| 288 | value = model.run(1) |
---|
| 289 | scale = 2.0e-6 |
---|
| 290 | model.setParam("mul.scale", scale) |
---|
| 291 | |
---|
| 292 | self.assertEqual(model.getParam("mul.scale"), scale) |
---|
| 293 | self.assertEqual(model.run(1), 2*value) |
---|
| 294 | |
---|
| 295 | def testSetCompositeDiv(self): |
---|
| 296 | sph2 = self.factory.getModel("SphereModel") |
---|
| 297 | #sph2.setParam("scale", 2.0e-6) |
---|
| 298 | model = sph2/self.sph |
---|
| 299 | value = model.run(1) |
---|
| 300 | scale = 2.0e-6 |
---|
| 301 | model.setParam("div.scale", scale) |
---|
| 302 | |
---|
| 303 | self.assertEqual(model.getParam("div.scale"), scale) |
---|
| 304 | self.assertEqual(model.run(1), 0.5*value) |
---|
| 305 | |
---|
| 306 | def testParamList(self): |
---|
| 307 | sph2 = self.factory.getModel("SphereModel") |
---|
| 308 | model = sph2/self.sph |
---|
| 309 | p_list = model.getParamList() |
---|
| 310 | #print p_list |
---|
| 311 | check_list = ['base.scale', 'base.radius', 'base.background', |
---|
| 312 | 'base.contrast', |
---|
| 313 | 'div.scale', 'div.radius', 'div.contrast', |
---|
| 314 | 'div.background'] |
---|
| 315 | self.assertEqual(check_list, p_list) |
---|
| 316 | |
---|
| 317 | if __name__ == '__main__': |
---|
| 318 | unittest.main() |
---|