Changeset 9bd69098 in sasview for sansmodels/src/sans/models/c_models/CParallelepipedModel.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/CParallelepipedModel.cpp
r8a48713 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> … … 146 149 } 147 150 } 148 149 150 151 /** 151 152 * Function to call to evaluate model 152 * @param args: input q or [q,phi]153 * @return: function value153 * @param args: input numpy array q[] 154 * @return: numpy array object 154 155 */ 155 static PyObject * run(CParallelepipedModel *self, PyObject *args) { 156 double q_value, phi_value; 157 PyObject* pars; 158 int npars; 156 157 static PyObject *evaluateOneDim(ParallelepipedModel* model, PyArrayObject *q){ 158 PyArrayObject *result; 159 160 // Check validity of array q , q must be of dimension 1, an array of double 161 if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE) 162 { 163 //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 164 //PyErr_SetString(PyExc_ValueError , message); 165 return NULL; 166 } 167 result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions), 168 PyArray_DOUBLE); 169 if (result == NULL) { 170 const char * message= "Could not create result "; 171 PyErr_SetString(PyExc_RuntimeError , message); 172 return NULL; 173 } 174 for (int i = 0; i < q->dimensions[0]; i++){ 175 double q_value = *(double *)(q->data + i*q->strides[0]); 176 double *result_value = (double *)(result->data + i*result->strides[0]); 177 *result_value =(*model)(q_value); 178 } 179 return PyArray_Return(result); 180 } 181 /** 182 * Function to call to evaluate model 183 * @param args: input numpy array [q[],phi[]] 184 * @return: numpy array object 185 */ 186 static PyObject * evaluateTwoDim( ParallelepipedModel* model, 187 PyArrayObject *q, PyArrayObject *phi) 188 { 189 PyArrayObject *result; 190 //check validity of input vectors 191 if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE 192 || phi->nd != 1 || phi->descr->type_num != PyArray_DOUBLE 193 || phi->dimensions[0] != q->dimensions[0]){ 194 195 //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 196 PyErr_SetString(PyExc_ValueError ,"wrong input"); 197 return NULL; 198 } 199 result= (PyArrayObject *)PyArray_FromDims(q->nd,(int*)(q->dimensions), PyArray_DOUBLE); 200 201 if (result == NULL){ 202 const char * message= "Could not create result "; 203 PyErr_SetString(PyExc_RuntimeError , message); 204 return NULL; 205 } 206 207 for (int i = 0; i < q->dimensions[0]; i++) { 208 double q_value = *(double *)(q->data + i*q->strides[0]); 209 double phi_value = *(double *)(phi->data + i*phi->strides[0]); 210 double *result_value = (double *)(result->data + i*result->strides[0]); 211 if (q_value == 0) 212 *result_value = 0.0; 213 else 214 *result_value = model->evaluate_rphi(q_value, phi_value); 215 } 216 return PyArray_Return(result); 217 } 218 /** 219 * Function to call to evaluate model 220 * @param args: input numpy array [x[],y[]] 221 * @return: numpy array object 222 */ 223 static PyObject * evaluateTwoDimXY( ParallelepipedModel* model, 224 PyArrayObject *x, PyArrayObject *y) 225 { 226 PyArrayObject *result; 227 int i,j, x_len, y_len, dims[2]; 228 //check validity of input vectors 229 if (x->nd != 2 || x->descr->type_num != PyArray_DOUBLE 230 || y->nd != 2 || y->descr->type_num != PyArray_DOUBLE 231 || y->dimensions[1] != x->dimensions[0]){ 232 const char * message= "evaluateTwoDimXY expect 2 numpy arrays"; 233 PyErr_SetString(PyExc_ValueError , message); 234 return NULL; 235 } 236 237 if (PyArray_Check(x) && PyArray_Check(y)) { 238 x_len = dims[0]= x->dimensions[0]; 239 y_len = dims[1]= y->dimensions[1]; 240 241 // Make a new double matrix of same dims 242 result=(PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE); 243 if (result == NULL){ 244 const char * message= "Could not create result "; 245 PyErr_SetString(PyExc_RuntimeError , message); 246 return NULL; 247 } 248 249 /* Do the calculation. */ 250 for ( i=0; i< x_len; i++) { 251 for ( j=0; j< y_len; j++) { 252 double x_value = *(double *)(x->data + i*x->strides[0]); 253 double y_value = *(double *)(y->data + j*y->strides[1]); 254 double *result_value = (double *)(result->data + 255 i*result->strides[0] + j*result->strides[1]); 256 *result_value = (*model)(x_value, y_value); 257 } 258 } 259 return PyArray_Return(result); 260 261 }else{ 262 PyErr_SetString(CParallelepipedModelError, 263 "CParallelepipedModel.evaluateTwoDimXY couldn't run."); 264 return NULL; 265 } 266 } 267 /** 268 * evalDistribution function evaluate a model function with input vector 269 * @param args: input q as vector or [qx, qy] where qx, qy are vectors 270 * 271 */ 272 static PyObject * evalDistribution(CParallelepipedModel *self, PyObject *args){ 273 PyObject *qx, *qy; 274 PyArrayObject * pars; 275 int npars ,mpars; 159 276 160 277 // Get parameters … … 187 304 if ( !PyArg_ParseTuple(args,"O",&pars) ) { 188 305 PyErr_SetString(CParallelepipedModelError, 189 "CParallelepipedModel. run expects a q value.");306 "CParallelepipedModel.evalDistribution expects a q value."); 190 307 return NULL; 191 308 } 192 193 // Check params194 if( PyList_Check(pars)==1) {309 // Check params 310 311 if(PyArray_Check(pars)==1) { 195 312 196 // Length of list should be 2 for I(q,phi) 197 npars = PyList_GET_SIZE(pars); 198 if(npars!=2) { 313 // Length of list should 1 or 2 314 npars = pars->nd; 315 if(npars==1) { 316 // input is a numpy array 317 if (PyArray_Check(pars)) { 318 return evaluateOneDim(self->model, (PyArrayObject*)pars); 319 } 320 }else{ 321 PyErr_SetString(CParallelepipedModelError, 322 "CParallelepipedModel.evalDistribution expect numpy array of one dimension."); 323 return NULL; 324 } 325 }else if( PyList_Check(pars)==1) { 326 // Length of list should be 2 for I(qx,qy) 327 mpars = PyList_GET_SIZE(pars); 328 if(mpars!=2) { 199 329 PyErr_SetString(CParallelepipedModelError, 200 "CParallelepipedModel. run expects a double ora list of dimension 2.");330 "CParallelepipedModel.evalDistribution expects a list of dimension 2."); 201 331 return NULL; 202 332 } 203 // We have a vector q, get the q and phi values at which 204 // to evaluate I(q,phi) 205 q_value = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,0)); 206 phi_value = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,1)); 207 // Skip zero 208 if (q_value==0) { 209 return Py_BuildValue("d",0.0); 210 } 211 return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value)); 212 213 } else { 214 215 // We have a scalar q, we will evaluate I(q) 216 q_value = CParallelepipedModel_readDouble(pars); 217 218 return Py_BuildValue("d",(*(self->model))(q_value)); 219 } 333 qx = PyList_GET_ITEM(pars,0); 334 qy = PyList_GET_ITEM(pars,1); 335 if (PyArray_Check(qx) && PyArray_Check(qy)) { 336 return evaluateTwoDimXY(self->model, (PyArrayObject*)qx, 337 (PyArrayObject*)qy); 338 }else{ 339 PyErr_SetString(CParallelepipedModelError, 340 "CParallelepipedModel.evalDistribution expect 2 numpy arrays in list."); 341 return NULL; 342 } 343 }else{ 344 PyErr_SetString(CParallelepipedModelError, 345 "CParallelepipedModel.evalDistribution couln't be run."); 346 return NULL; 347 } 220 348 } 221 349 222 350 /** 223 * Function to call to evaluate model in cartesian coordinates224 * @param args: input q or [q x, qy]]351 * Function to call to evaluate model 352 * @param args: input q or [q,phi] 225 353 * @return: function value 226 354 */ 227 static PyObject * run XY(CParallelepipedModel *self, PyObject *args) {228 double q x_value, qy_value;355 static PyObject * run(CParallelepipedModel *self, PyObject *args) { 356 double q_value, phi_value; 229 357 PyObject* pars; 230 358 int npars; … … 266 394 if( PyList_Check(pars)==1) { 267 395 396 // Length of list should be 2 for I(q,phi) 397 npars = PyList_GET_SIZE(pars); 398 if(npars!=2) { 399 PyErr_SetString(CParallelepipedModelError, 400 "CParallelepipedModel.run expects a double or a list of dimension 2."); 401 return NULL; 402 } 403 // We have a vector q, get the q and phi values at which 404 // to evaluate I(q,phi) 405 q_value = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,0)); 406 phi_value = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,1)); 407 // Skip zero 408 if (q_value==0) { 409 return Py_BuildValue("d",0.0); 410 } 411 return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value)); 412 413 } else { 414 415 // We have a scalar q, we will evaluate I(q) 416 q_value = CParallelepipedModel_readDouble(pars); 417 418 return Py_BuildValue("d",(*(self->model))(q_value)); 419 } 420 } 421 422 /** 423 * Function to call to evaluate model in cartesian coordinates 424 * @param args: input q or [qx, qy]] 425 * @return: function value 426 */ 427 static PyObject * runXY(CParallelepipedModel *self, PyObject *args) { 428 double qx_value, qy_value; 429 PyObject* pars; 430 int npars; 431 432 // Get parameters 433 434 // Reader parameter dictionary 435 self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 436 self->model->longer_edgeB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longer_edgeB") ); 437 self->model->longuest_edgeC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longuest_edgeC") ); 438 self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") ); 439 self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") ); 440 self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") ); 441 self->model->short_edgeA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_edgeA") ); 442 self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 443 // Read in dispersion parameters 444 PyObject* disp_dict; 445 DispersionVisitor* visitor = new DispersionVisitor(); 446 disp_dict = PyDict_GetItemString(self->dispersion, "short_edgeA"); 447 self->model->short_edgeA.dispersion->accept_as_destination(visitor, self->model->short_edgeA.dispersion, disp_dict); 448 disp_dict = PyDict_GetItemString(self->dispersion, "longer_edgeB"); 449 self->model->longer_edgeB.dispersion->accept_as_destination(visitor, self->model->longer_edgeB.dispersion, disp_dict); 450 disp_dict = PyDict_GetItemString(self->dispersion, "longuest_edgeC"); 451 self->model->longuest_edgeC.dispersion->accept_as_destination(visitor, self->model->longuest_edgeC.dispersion, disp_dict); 452 disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi"); 453 self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict); 454 disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta"); 455 self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.dispersion, disp_dict); 456 457 458 // Get input and determine whether we have to supply a 1D or 2D return value. 459 if ( !PyArg_ParseTuple(args,"O",&pars) ) { 460 PyErr_SetString(CParallelepipedModelError, 461 "CParallelepipedModel.run expects a q value."); 462 return NULL; 463 } 464 465 // Check params 466 if( PyList_Check(pars)==1) { 467 268 468 // Length of list should be 2 for I(qx, qy)) 269 469 npars = PyList_GET_SIZE(pars); … … 338 538 {"runXY", (PyCFunction)runXY , METH_VARARGS, 339 539 "Evaluate the model at a given Q or Qx, Qy"}, 540 541 {"evalDistribution", (PyCFunction)evalDistribution , METH_VARARGS, 542 "Evaluate the model at a given Q or Qx, Qy vector "}, 340 543 {"reset", (PyCFunction)reset , METH_VARARGS, 341 544 "Reset pair correlation"}, … … 388 591 389 592 390 static PyMethodDef module_methods[] = {391 {NULL}392 };593 //static PyMethodDef module_methods[] = { 594 // {NULL} 595 //}; 393 596 394 597 /**
Note: See TracChangeset
for help on using the changeset viewer.