Changeset af03ddd in sasview for sansmodels/src/sans/models
- Timestamp:
- Aug 18, 2008 2:19:47 PM (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:
- a86bbe9
- Parents:
- fca6936
- Location:
- sansmodels/src/sans/models
- Files:
-
- 5 added
- 2 deleted
- 6 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
sansmodels/src/sans/models/CylinderModel.py
rae3ce4e raf03ddd 1 1 #!/usr/bin/env python 2 """ 3 This software was developed by the University of Tennessee as part of the 4 Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 5 project funded by the US National Science Foundation. 6 7 If you use DANSE applications to do scientific research that leads to 8 publication, we ask that you acknowledge the use of the software with the 9 following sentence: 10 11 "This work benefited from DANSE software developed under NSF award DMR-0520547." 12 13 copyright 2008, University of Tennessee 14 """ 15 2 16 """ Provide functionality for a C extension model 3 17 4 18 WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY 5 DO NOT MODIFY THIS FILE, MODIFY cylinder.h19 DO NOT MODIFY THIS FILE, MODIFY ../c_extensions/cylinder.h 6 20 AND RE-RUN THE GENERATOR SCRIPT 7 21 8 @author: Mathieu Doucet / UTK9 @contact: mathieu.doucet@nist.gov10 22 """ 11 23 … … 16 28 class CylinderModel(CCylinderModel, BaseComponent): 17 29 """ Class that evaluates a CylinderModel model. 18 This file was auto-generated from cylinder.h.30 This file was auto-generated from ../c_extensions/cylinder.h. 19 31 Refer to that file and the structure it contains 20 32 for details of the model. … … 72 84 73 85 return CCylinderModel.runXY(self, x) 86 87 def set_dispersion(self, parameter, dispersion): 88 """ 89 Set the dispersion object for a model parameter 90 @param parameter: name of the parameter [string] 91 @dispersion: dispersion object of type DispersionModel 92 """ 93 return CCylinderModel.set_dispersion(self, parameter, dispersion.cdisp) 94 74 95 75 96 # End of file -
sansmodels/src/sans/models/c_extensions/c_models.c
rae3ce4e raf03ddd 1 1 /** c_models 2 2 * 3 * Module containing all SANS model extensions 3 * Module containing all SANS model extensions 4 4 * 5 5 * @author M.Doucet / UTK … … 11 11 */ 12 12 static PyMethodDef module_methods[] = { 13 {NULL} 13 {NULL} 14 14 }; 15 15 … … 19 19 #endif 20 20 PyMODINIT_FUNC 21 initc_models(void) 21 initc_models(void) 22 22 { 23 23 PyObject* m; … … 25 25 m = Py_InitModule3("c_models", module_methods, 26 26 "C extension module for SANS scattering models."); 27 27 28 28 addCCylinderModel(m); 29 29 addCCoreShellCylinderModel(m); -
sansmodels/src/sans/models/c_extensions/cylinder.h
rae3ce4e raf03ddd 2 2 #define cylinder_h 3 3 4 /** Structure definition for cylinder parameters 4 /** Structure definition for cylinder parameters 5 5 * [PYTHONCLASS] = CylinderModel 6 * [DISP_PARAMS] = radius, length, cyl_theta, cyl_phi 6 7 * */ 7 8 typedef struct { 8 /// Scale factor 9 /// Scale factor 9 10 // [DEFAULT]=scale=1.0 10 11 double scale; 11 12 /// Radius of the cylinder [A] 12 // [DEFAULT]=radius=20.0 A 13 // [DEFAULT]=radius=20.0 A 13 14 double radius; 14 15 /// Length of the cylinder [A] … … 20 21 /// Incoherent Background (cm-1) 0.000 21 22 // [DEFAULT]=background=0 cm-1 22 double background; 23 double background; 23 24 /// Orientation of the cylinder axis w/respect incoming beam [rad] 24 25 // [DEFAULT]=cyl_theta=1.0 rad … … 26 27 /// Orientation of the cylinder in the plane of the detector [rad] 27 28 // [DEFAULT]=cyl_phi=1.0 rad 28 double cyl_phi; 29 double cyl_phi; 29 30 } CylinderParameters; 30 31 -
sansmodels/src/sans/models/c_models/CCylinderModel.cpp
rfca6936 raf03ddd 1 /** CCylinder 1 /** 2 This software was developed by the University of Tennessee as part of the 3 Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 4 project funded by the US National Science Foundation. 5 6 If you use DANSE applications to do scientific research that leads to 7 publication, we ask that you acknowledge the use of the software with the 8 following sentence: 9 10 "This work benefited from DANSE software developed under NSF award DMR-0520547." 11 12 copyright 2008, University of Tennessee 13 */ 14 15 /** CCylinderModel 2 16 * 3 * C extension 17 * C extension 18 * 19 * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY 20 * DO NOT MODIFY THIS FILE, MODIFY cylinder.h 21 * AND RE-RUN THE GENERATOR SCRIPT 4 22 * 5 23 */ 24 6 25 extern "C" { 7 26 #include <Python.h> … … 14 33 } 15 34 16 17 35 #include "models.hh" 18 36 #include "dispersion_visitor.hh" … … 27 45 /// Parameters 28 46 PyObject * params; 47 /// Dispersion parameters 29 48 PyObject * dispersion; 30 Cylinder * model; 49 /// Underlying model object 50 CylinderModel * model; 31 51 /// Log for unit testing 32 52 PyObject * log; 33 /// Model parameters34 CylinderParameters model_pars;35 53 } CCylinderModel; 36 54 … … 40 58 { 41 59 self->ob_type->tp_free((PyObject*)self); 42 60 43 61 44 62 } … … 48 66 { 49 67 CCylinderModel *self; 50 68 51 69 self = (CCylinderModel *)type->tp_alloc(type, 0); 52 70 53 71 return (PyObject *)self; 54 72 } … … 58 76 { 59 77 if (self != NULL) { 60 printf("Hello cylinder\n");78 61 79 // Create parameters 62 80 self->params = PyDict_New(); 63 81 self->dispersion = PyDict_New(); 64 self->model = new Cylinder ();65 82 self->model = new CylinderModel(); 83 66 84 // Initialize parameter dictionary 67 PyDict_SetItemString(self->params,"scale", 68 PyDict_SetItemString(self->params,"length", 69 PyDict_SetItemString(self->params,"cyl_theta", 85 PyDict_SetItemString(self->params,"scale",Py_BuildValue("d", self->model->scale())); 86 PyDict_SetItemString(self->params,"length",Py_BuildValue("d", self->model->length())); 87 PyDict_SetItemString(self->params,"cyl_theta",Py_BuildValue("d", self->model->cyl_theta())); 70 88 PyDict_SetItemString(self->params,"background",Py_BuildValue("d", self->model->background())); 71 PyDict_SetItemString(self->params,"radius", Py_BuildValue("d", self->model->radius())); 72 PyDict_SetItemString(self->params,"contrast", Py_BuildValue("d", self->model->contrast())); 73 PyDict_SetItemString(self->params,"cyl_phi", Py_BuildValue("d", self->model->cyl_phi())); 74 89 PyDict_SetItemString(self->params,"radius",Py_BuildValue("d", self->model->radius())); 90 PyDict_SetItemString(self->params,"contrast",Py_BuildValue("d", self->model->contrast())); 91 PyDict_SetItemString(self->params,"cyl_phi",Py_BuildValue("d", self->model->cyl_phi())); 75 92 // Initialize dispersion / averaging parameter dict 76 93 DispersionVisitor* visitor = new DispersionVisitor(); 77 PyObject * disp_dict = PyDict_New(); 94 PyObject * disp_dict; 95 disp_dict = PyDict_New(); 78 96 self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict); 79 PyDict_SetItemString(self->dispersion, "disp_radius", disp_dict); 80 97 PyDict_SetItemString(self->dispersion, "radius", disp_dict); 81 98 disp_dict = PyDict_New(); 82 99 self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict); 83 PyDict_SetItemString(self->dispersion, "disp_length", disp_dict); 84 100 PyDict_SetItemString(self->dispersion, "length", disp_dict); 101 disp_dict = PyDict_New(); 102 self->model->cyl_theta.dispersion->accept_as_source(visitor, self->model->cyl_theta.dispersion, disp_dict); 103 PyDict_SetItemString(self->dispersion, "cyl_theta", disp_dict); 85 104 disp_dict = PyDict_New(); 86 105 self->model->cyl_phi.dispersion->accept_as_source(visitor, self->model->cyl_phi.dispersion, disp_dict); 87 PyDict_SetItemString(self->dispersion, "disp_cyl_phi", disp_dict); 88 89 disp_dict = PyDict_New(); 90 self->model->cyl_theta.dispersion->accept_as_source(visitor, self->model->cyl_theta.dispersion, disp_dict); 91 PyDict_SetItemString(self->dispersion, "disp_cyl_theta", disp_dict); 92 106 PyDict_SetItemString(self->dispersion, "cyl_phi", disp_dict); 107 108 109 93 110 // Create empty log 94 111 self->log = PyDict_New(); 112 113 95 114 96 115 } … … 99 118 100 119 static PyMemberDef CCylinderModel_members[] = { 101 102 120 {"params", T_OBJECT, offsetof(CCylinderModel, params), 0, 121 "Parameters"}, 103 122 {"dispersion", T_OBJECT, offsetof(CCylinderModel, dispersion), 0, 104 "Dispersion parameters"}, 123 "Dispersion parameters"}, 105 124 {"log", T_OBJECT, offsetof(CCylinderModel, log), 0, 106 125 "Log"}, … … 124 143 } 125 144 126 /**127 * Method to set the dispersion model for a parameter.128 * We need to update the dispersion object of the parameter129 * on the C++ side and update the dispersion dictionary on the python side.130 *131 * TODO: define read-only integers that will be data members of this132 * class and allow the user to specify which model is needed with a code name.133 *134 * This method should take in a code name (FLAT, GAUSSIAN) and a string135 * that represent the parameter to attach the dispersion model to.136 *137 */138 static PyObject * set_dispersion_model(CCylinderModel *self, PyObject *args) {139 140 }141 142 145 143 146 /** … … 150 153 PyObject* pars; 151 154 int npars; 152 155 153 156 // Get parameters 154 155 // Reader parameter dictionary157 158 // Reader parameter dictionary 156 159 self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 157 160 self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") ); … … 161 164 self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 162 165 self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") ); 163 164 166 // Read in dispersion parameters 167 PyObject* disp_dict; 165 168 DispersionVisitor* visitor = new DispersionVisitor(); 166 PyObject* disp_dict = PyDict_New(); 167 disp_dict = PyDict_GetItemString(self->dispersion, "disp_radius"); 169 disp_dict = PyDict_GetItemString(self->dispersion, "radius"); 168 170 self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict); 171 disp_dict = PyDict_GetItemString(self->dispersion, "length"); 169 172 self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict); 173 disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta"); 170 174 self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict); 175 disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi"); 171 176 self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict); 172 177 178 173 179 // Get input and determine whether we have to supply a 1D or 2D return value. 174 180 if ( !PyArg_ParseTuple(args,"O",&pars) ) { 175 PyErr_SetString(CCylinderModelError, 181 PyErr_SetString(CCylinderModelError, 176 182 "CCylinderModel.run expects a q value."); 177 183 return NULL; 178 184 } 179 185 180 186 // Check params 181 187 if( PyList_Check(pars)==1) { 182 188 183 189 // Length of list should be 2 for I(q,phi) 184 npars = PyList_GET_SIZE(pars); 190 npars = PyList_GET_SIZE(pars); 185 191 if(npars!=2) { 186 PyErr_SetString(CCylinderModelError, 192 PyErr_SetString(CCylinderModelError, 187 193 "CCylinderModel.run expects a double or a list of dimension 2."); 188 194 return NULL; … … 201 207 202 208 // We have a scalar q, we will evaluate I(q) 203 q_value = CCylinderModel_readDouble(pars); 204 209 q_value = CCylinderModel_readDouble(pars); 210 205 211 return Py_BuildValue("d",(*(self->model))(q_value)); 206 } 212 } 207 213 } 208 214 … … 216 222 PyObject* pars; 217 223 int npars; 218 224 219 225 // Get parameters 220 221 // Reader parameter dictionary226 227 // Reader parameter dictionary 222 228 self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 223 229 self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") ); … … 227 233 self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 228 234 self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") ); 229 230 235 // Read in dispersion parameters 236 PyObject* disp_dict; 231 237 DispersionVisitor* visitor = new DispersionVisitor(); 232 PyObject* disp_dict = PyDict_New(); 233 disp_dict = PyDict_GetItemString(self->dispersion, "disp_radius"); 238 disp_dict = PyDict_GetItemString(self->dispersion, "radius"); 234 239 self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict); 240 disp_dict = PyDict_GetItemString(self->dispersion, "length"); 235 241 self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict); 242 disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta"); 236 243 self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict); 244 disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi"); 237 245 self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict); 238 246 247 239 248 // Get input and determine whether we have to supply a 1D or 2D return value. 240 249 if ( !PyArg_ParseTuple(args,"O",&pars) ) { 241 PyErr_SetString(CCylinderModelError, 250 PyErr_SetString(CCylinderModelError, 242 251 "CCylinderModel.run expects a q value."); 243 252 return NULL; 244 253 } 245 254 246 255 // Check params 247 256 if( PyList_Check(pars)==1) { 248 257 249 258 // Length of list should be 2 for I(qx, qy)) 250 npars = PyList_GET_SIZE(pars); 259 npars = PyList_GET_SIZE(pars); 251 260 if(npars!=2) { 252 PyErr_SetString(CCylinderModelError, 261 PyErr_SetString(CCylinderModelError, 253 262 "CCylinderModel.run expects a double or a list of dimension 2."); 254 263 return NULL; … … 263 272 264 273 // We have a scalar q, we will evaluate I(q) 265 qx_value = CCylinderModel_readDouble(pars); 266 274 qx_value = CCylinderModel_readDouble(pars); 275 267 276 return Py_BuildValue("d",(*(self->model))(qx_value)); 277 } 278 } 279 280 static PyObject * reset(CCylinderModel *self, PyObject *args) { 281 282 283 return Py_BuildValue("d",0.0); 284 } 285 286 static PyObject * set_dispersion(CCylinderModel *self, PyObject *args) { 287 PyObject * disp; 288 const char * par_name; 289 290 if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) { 291 PyErr_SetString(CCylinderModelError, 292 "CCylinderModel.set_dispersion expects a DispersionModel object."); 293 return NULL; 268 294 } 269 } 270 271 static PyObject * reset(CCylinderModel *self, PyObject *args) { 272 273 274 return Py_BuildValue("d",0.0); 295 void *temp = PyCObject_AsVoidPtr(disp); 296 DispersionModel * dispersion = static_cast<DispersionModel *>(temp); 297 298 299 // Ugliness necessary to go from python to C 300 // TODO: refactor this 301 if (!strcmp(par_name, "radius")) { 302 self->model->radius.dispersion = dispersion; 303 } else if (!strcmp(par_name, "length")) { 304 self->model->length.dispersion = dispersion; 305 } else if (!strcmp(par_name, "cyl_theta")) { 306 self->model->cyl_theta.dispersion = dispersion; 307 } else if (!strcmp(par_name, "cyl_phi")) { 308 self->model->cyl_phi.dispersion = dispersion; 309 } else { 310 PyErr_SetString(CCylinderModelError, 311 "CCylinderModel.set_dispersion expects a valid parameter name."); 312 return NULL; 313 } 314 315 DispersionVisitor* visitor = new DispersionVisitor(); 316 PyObject * disp_dict = PyDict_New(); 317 dispersion->accept_as_source(visitor, dispersion, disp_dict); 318 PyDict_SetItemString(self->dispersion, par_name, disp_dict); 319 return Py_BuildValue("i",1); 275 320 } 276 321 … … 283 328 {"reset", (PyCFunction)reset , METH_VARARGS, 284 329 "Reset pair correlation"}, 285 //{"numerical_1D", (PyCFunction)numerical_1D, METH_VARARGS,286 // "Evaluate the 1D model at a given Q"},330 {"set_dispersion", (PyCFunction)set_dispersion , METH_VARARGS, 331 "Set the dispersion model for a given parameter"}, 287 332 {NULL} 288 333 }; … … 332 377 333 378 static PyMethodDef module_methods[] = { 334 {NULL} 379 {NULL} 335 380 }; 336 381 … … 338 383 * Function used to add the model class to a module 339 384 * @param module: module to add the class to 340 */ 385 */ 341 386 void addCCylinderModel(PyObject *module) { 342 387 PyObject *d; 343 388 344 389 if (PyType_Ready(&CCylinderModelType) < 0) 345 390 return; … … 347 392 Py_INCREF(&CCylinderModelType); 348 393 PyModule_AddObject(module, "CCylinderModel", (PyObject *)&CCylinderModelType); 349 394 350 395 d = PyModule_GetDict(module); 351 396 CCylinderModelError = PyErr_NewException("CCylinderModel.error", NULL, NULL); -
sansmodels/src/sans/models/c_models/cylinder.cpp
rfca6936 raf03ddd 32 32 } 33 33 34 Cylinder :: Cylinder() {34 CylinderModel :: CylinderModel() { 35 35 scale = Parameter(1.0); 36 36 radius = Parameter(20.0, true); … … 50 50 * @return: function value 51 51 */ 52 double Cylinder :: operator()(double q) {52 double CylinderModel :: operator()(double q) { 53 53 double dp[5]; 54 54 … … 96 96 * @return: function value 97 97 */ 98 double Cylinder :: operator()(double qx, double qy) {98 double CylinderModel :: operator()(double qx, double qy) { 99 99 CylinderParameters dp; 100 100 // Fill parameter array … … 177 177 * @return: function value 178 178 */ 179 double Cylinder :: evaluate_rphi(double q, double phi) {179 double CylinderModel :: evaluate_rphi(double q, double phi) { 180 180 double qx = q*cos(phi); 181 181 double qy = q*sin(phi); … … 186 186 int main(void) 187 187 { 188 Cylinder c = Cylinder();188 CylinderModel c = CylinderModel(); 189 189 190 190 printf("Length = %g\n", c.length()); -
sansmodels/src/sans/models/c_models/models.hh
rfca6936 raf03ddd 23 23 using namespace std; 24 24 25 class Cylinder {25 class CylinderModel{ 26 26 27 27 public: … … 37 37 38 38 // Constructor 39 Cylinder ();39 CylinderModel(); 40 40 41 41 // Operators to get I(Q) -
sansmodels/src/sans/models/test/utest_models.py
rae3ce4e raf03ddd 50 50 def test2D(self): 51 51 """ Test 2D model of a cylinder """ 52 self.comp.setParam('cyl_theta', 1.0) 53 self.comp.setParam('cyl_phi', 1.0) 52 54 self.assertAlmostEqual(self.comp.run([0.2, 2.5]), 53 55 0.038176446608393366, 4)
Note: See TracChangeset
for help on using the changeset viewer.