Changeset 9bd69098 in sasview for sansmodels/src/sans/models/c_models/CLamellarPSModel.cpp
- Timestamp:
- Aug 7, 2009 9:10:34 AM (15 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:
- 58c6ba6
- Parents:
- 83a25da
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sansmodels/src/sans/models/c_models/CLamellarPSModel.cpp
rb341b16 r9bd69098 22 22 * 23 23 */ 24 #define NO_IMPORT_ARRAY 25 #define PY_ARRAY_UNIQUE_SYMBOL PyArray_API_sans 24 26 25 27 extern "C" { 26 28 #include <Python.h> 29 #include <arrayobject.h> 27 30 #include "structmember.h" 28 31 #include <stdio.h> … … 134 137 } 135 138 } 136 139 /** 140 * Function to call to evaluate model 141 * @param args: input numpy array q[] 142 * @return: numpy array object 143 */ 144 145 static PyObject *evaluateOneDim(LamellarPSModel* model, PyArrayObject *q){ 146 PyArrayObject *result; 147 148 // Check validity of array q , q must be of dimension 1, an array of double 149 if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE) 150 { 151 //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 152 //PyErr_SetString(PyExc_ValueError , message); 153 return NULL; 154 } 155 result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions), 156 PyArray_DOUBLE); 157 if (result == NULL) { 158 const char * message= "Could not create result "; 159 PyErr_SetString(PyExc_RuntimeError , message); 160 return NULL; 161 } 162 for (int i = 0; i < q->dimensions[0]; i++){ 163 double q_value = *(double *)(q->data + i*q->strides[0]); 164 double *result_value = (double *)(result->data + i*result->strides[0]); 165 *result_value =(*model)(q_value); 166 } 167 return PyArray_Return(result); 168 } 169 /** 170 * Function to call to evaluate model 171 * @param args: input numpy array [q[],phi[]] 172 * @return: numpy array object 173 */ 174 static PyObject * evaluateTwoDim( LamellarPSModel* model, 175 PyArrayObject *q, PyArrayObject *phi) 176 { 177 PyArrayObject *result; 178 //check validity of input vectors 179 if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE 180 || phi->nd != 1 || phi->descr->type_num != PyArray_DOUBLE 181 || phi->dimensions[0] != q->dimensions[0]){ 182 183 //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 184 PyErr_SetString(PyExc_ValueError ,"wrong input"); 185 return NULL; 186 } 187 result= (PyArrayObject *)PyArray_FromDims(q->nd,(int*)(q->dimensions), PyArray_DOUBLE); 188 189 if (result == NULL){ 190 const char * message= "Could not create result "; 191 PyErr_SetString(PyExc_RuntimeError , message); 192 return NULL; 193 } 194 195 for (int i = 0; i < q->dimensions[0]; i++) { 196 double q_value = *(double *)(q->data + i*q->strides[0]); 197 double phi_value = *(double *)(phi->data + i*phi->strides[0]); 198 double *result_value = (double *)(result->data + i*result->strides[0]); 199 if (q_value == 0) 200 *result_value = 0.0; 201 else 202 *result_value = model->evaluate_rphi(q_value, phi_value); 203 } 204 return PyArray_Return(result); 205 } 206 /** 207 * Function to call to evaluate model 208 * @param args: input numpy array [x[],y[]] 209 * @return: numpy array object 210 */ 211 static PyObject * evaluateTwoDimXY( LamellarPSModel* model, 212 PyArrayObject *x, PyArrayObject *y) 213 { 214 PyArrayObject *result; 215 int i,j, x_len, y_len, dims[2]; 216 //check validity of input vectors 217 if (x->nd != 2 || x->descr->type_num != PyArray_DOUBLE 218 || y->nd != 2 || y->descr->type_num != PyArray_DOUBLE 219 || y->dimensions[1] != x->dimensions[0]){ 220 const char * message= "evaluateTwoDimXY expect 2 numpy arrays"; 221 PyErr_SetString(PyExc_ValueError , message); 222 return NULL; 223 } 224 225 if (PyArray_Check(x) && PyArray_Check(y)) { 226 x_len = dims[0]= x->dimensions[0]; 227 y_len = dims[1]= y->dimensions[1]; 228 229 // Make a new double matrix of same dims 230 result=(PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE); 231 if (result == NULL){ 232 const char * message= "Could not create result "; 233 PyErr_SetString(PyExc_RuntimeError , message); 234 return NULL; 235 } 236 237 /* Do the calculation. */ 238 for ( i=0; i< x_len; i++) { 239 for ( j=0; j< y_len; j++) { 240 double x_value = *(double *)(x->data + i*x->strides[0]); 241 double y_value = *(double *)(y->data + j*y->strides[1]); 242 double *result_value = (double *)(result->data + 243 i*result->strides[0] + j*result->strides[1]); 244 *result_value = (*model)(x_value, y_value); 245 } 246 } 247 return PyArray_Return(result); 248 249 }else{ 250 PyErr_SetString(CLamellarPSModelError, 251 "CLamellarPSModel.evaluateTwoDimXY couldn't run."); 252 return NULL; 253 } 254 } 255 /** 256 * evalDistribution function evaluate a model function with input vector 257 * @param args: input q as vector or [qx, qy] where qx, qy are vectors 258 * 259 */ 260 static PyObject * evalDistribution(CLamellarPSModel *self, PyObject *args){ 261 PyObject *qx, *qy; 262 PyArrayObject * pars; 263 int npars ,mpars; 264 265 // Get parameters 266 267 // Reader parameter dictionary 268 self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") ); 269 self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 270 self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") ); 271 self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") ); 272 self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") ); 273 self->model->delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") ); 274 self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") ); 275 self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 276 // Read in dispersion parameters 277 PyObject* disp_dict; 278 DispersionVisitor* visitor = new DispersionVisitor(); 279 disp_dict = PyDict_GetItemString(self->dispersion, "spacing"); 280 self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.dispersion, disp_dict); 281 282 283 // Get input and determine whether we have to supply a 1D or 2D return value. 284 if ( !PyArg_ParseTuple(args,"O",&pars) ) { 285 PyErr_SetString(CLamellarPSModelError, 286 "CLamellarPSModel.evalDistribution expects a q value."); 287 return NULL; 288 } 289 // Check params 290 291 if(PyArray_Check(pars)==1) { 292 293 // Length of list should 1 or 2 294 npars = pars->nd; 295 if(npars==1) { 296 // input is a numpy array 297 if (PyArray_Check(pars)) { 298 return evaluateOneDim(self->model, (PyArrayObject*)pars); 299 } 300 }else{ 301 PyErr_SetString(CLamellarPSModelError, 302 "CLamellarPSModel.evalDistribution expect numpy array of one dimension."); 303 return NULL; 304 } 305 }else if( PyList_Check(pars)==1) { 306 // Length of list should be 2 for I(qx,qy) 307 mpars = PyList_GET_SIZE(pars); 308 if(mpars!=2) { 309 PyErr_SetString(CLamellarPSModelError, 310 "CLamellarPSModel.evalDistribution expects a list of dimension 2."); 311 return NULL; 312 } 313 qx = PyList_GET_ITEM(pars,0); 314 qy = PyList_GET_ITEM(pars,1); 315 if (PyArray_Check(qx) && PyArray_Check(qy)) { 316 return evaluateTwoDimXY(self->model, (PyArrayObject*)qx, 317 (PyArrayObject*)qy); 318 }else{ 319 PyErr_SetString(CLamellarPSModelError, 320 "CLamellarPSModel.evalDistribution expect 2 numpy arrays in list."); 321 return NULL; 322 } 323 }else{ 324 PyErr_SetString(CLamellarPSModelError, 325 "CLamellarPSModel.evalDistribution couln't be run."); 326 return NULL; 327 } 328 } 137 329 138 330 /** … … 302 494 {"runXY", (PyCFunction)runXY , METH_VARARGS, 303 495 "Evaluate the model at a given Q or Qx, Qy"}, 496 497 {"evalDistribution", (PyCFunction)evalDistribution , METH_VARARGS, 498 "Evaluate the model at a given Q or Qx, Qy vector "}, 304 499 {"reset", (PyCFunction)reset , METH_VARARGS, 305 500 "Reset pair correlation"}, … … 352 547 353 548 354 static PyMethodDef module_methods[] = {355 {NULL}356 };549 //static PyMethodDef module_methods[] = { 550 // {NULL} 551 //}; 357 552 358 553 /**
Note: See TracChangeset
for help on using the changeset viewer.