Changeset 9bd69098 in sasview for sansmodels/src/sans/models/c_models/CTriaxialEllipsoidModel.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/CTriaxialEllipsoidModel.cpp
r5068697 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> … … 137 140 } 138 141 } 139 142 /** 143 * Function to call to evaluate model 144 * @param args: input numpy array q[] 145 * @return: numpy array object 146 */ 147 148 static PyObject *evaluateOneDim(TriaxialEllipsoidModel* model, PyArrayObject *q){ 149 PyArrayObject *result; 150 151 // Check validity of array q , q must be of dimension 1, an array of double 152 if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE) 153 { 154 //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 155 //PyErr_SetString(PyExc_ValueError , message); 156 return NULL; 157 } 158 result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions), 159 PyArray_DOUBLE); 160 if (result == NULL) { 161 const char * message= "Could not create result "; 162 PyErr_SetString(PyExc_RuntimeError , message); 163 return NULL; 164 } 165 for (int i = 0; i < q->dimensions[0]; i++){ 166 double q_value = *(double *)(q->data + i*q->strides[0]); 167 double *result_value = (double *)(result->data + i*result->strides[0]); 168 *result_value =(*model)(q_value); 169 } 170 return PyArray_Return(result); 171 } 172 /** 173 * Function to call to evaluate model 174 * @param args: input numpy array [q[],phi[]] 175 * @return: numpy array object 176 */ 177 static PyObject * evaluateTwoDim( TriaxialEllipsoidModel* model, 178 PyArrayObject *q, PyArrayObject *phi) 179 { 180 PyArrayObject *result; 181 //check validity of input vectors 182 if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE 183 || phi->nd != 1 || phi->descr->type_num != PyArray_DOUBLE 184 || phi->dimensions[0] != q->dimensions[0]){ 185 186 //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 187 PyErr_SetString(PyExc_ValueError ,"wrong input"); 188 return NULL; 189 } 190 result= (PyArrayObject *)PyArray_FromDims(q->nd,(int*)(q->dimensions), PyArray_DOUBLE); 191 192 if (result == NULL){ 193 const char * message= "Could not create result "; 194 PyErr_SetString(PyExc_RuntimeError , message); 195 return NULL; 196 } 197 198 for (int i = 0; i < q->dimensions[0]; i++) { 199 double q_value = *(double *)(q->data + i*q->strides[0]); 200 double phi_value = *(double *)(phi->data + i*phi->strides[0]); 201 double *result_value = (double *)(result->data + i*result->strides[0]); 202 if (q_value == 0) 203 *result_value = 0.0; 204 else 205 *result_value = model->evaluate_rphi(q_value, phi_value); 206 } 207 return PyArray_Return(result); 208 } 209 /** 210 * Function to call to evaluate model 211 * @param args: input numpy array [x[],y[]] 212 * @return: numpy array object 213 */ 214 static PyObject * evaluateTwoDimXY( TriaxialEllipsoidModel* model, 215 PyArrayObject *x, PyArrayObject *y) 216 { 217 PyArrayObject *result; 218 int i,j, x_len, y_len, dims[2]; 219 //check validity of input vectors 220 if (x->nd != 2 || x->descr->type_num != PyArray_DOUBLE 221 || y->nd != 2 || y->descr->type_num != PyArray_DOUBLE 222 || y->dimensions[1] != x->dimensions[0]){ 223 const char * message= "evaluateTwoDimXY expect 2 numpy arrays"; 224 PyErr_SetString(PyExc_ValueError , message); 225 return NULL; 226 } 227 228 if (PyArray_Check(x) && PyArray_Check(y)) { 229 x_len = dims[0]= x->dimensions[0]; 230 y_len = dims[1]= y->dimensions[1]; 231 232 // Make a new double matrix of same dims 233 result=(PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE); 234 if (result == NULL){ 235 const char * message= "Could not create result "; 236 PyErr_SetString(PyExc_RuntimeError , message); 237 return NULL; 238 } 239 240 /* Do the calculation. */ 241 for ( i=0; i< x_len; i++) { 242 for ( j=0; j< y_len; j++) { 243 double x_value = *(double *)(x->data + i*x->strides[0]); 244 double y_value = *(double *)(y->data + j*y->strides[1]); 245 double *result_value = (double *)(result->data + 246 i*result->strides[0] + j*result->strides[1]); 247 *result_value = (*model)(x_value, y_value); 248 } 249 } 250 return PyArray_Return(result); 251 252 }else{ 253 PyErr_SetString(CTriaxialEllipsoidModelError, 254 "CTriaxialEllipsoidModel.evaluateTwoDimXY couldn't run."); 255 return NULL; 256 } 257 } 258 /** 259 * evalDistribution function evaluate a model function with input vector 260 * @param args: input q as vector or [qx, qy] where qx, qy are vectors 261 * 262 */ 263 static PyObject * evalDistribution(CTriaxialEllipsoidModel *self, PyObject *args){ 264 PyObject *qx, *qy; 265 PyArrayObject * pars; 266 int npars ,mpars; 267 268 // Get parameters 269 270 // Reader parameter dictionary 271 self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 272 self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") ); 273 self->model->semi_axisA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisA") ); 274 self->model->semi_axisB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisB") ); 275 self->model->semi_axisC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisC") ); 276 self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") ); 277 self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") ); 278 self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 279 // Read in dispersion parameters 280 PyObject* disp_dict; 281 DispersionVisitor* visitor = new DispersionVisitor(); 282 disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta"); 283 self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict); 284 disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi"); 285 self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict); 286 287 288 // Get input and determine whether we have to supply a 1D or 2D return value. 289 if ( !PyArg_ParseTuple(args,"O",&pars) ) { 290 PyErr_SetString(CTriaxialEllipsoidModelError, 291 "CTriaxialEllipsoidModel.evalDistribution expects a q value."); 292 return NULL; 293 } 294 // Check params 295 296 if(PyArray_Check(pars)==1) { 297 298 // Length of list should 1 or 2 299 npars = pars->nd; 300 if(npars==1) { 301 // input is a numpy array 302 if (PyArray_Check(pars)) { 303 return evaluateOneDim(self->model, (PyArrayObject*)pars); 304 } 305 }else{ 306 PyErr_SetString(CTriaxialEllipsoidModelError, 307 "CTriaxialEllipsoidModel.evalDistribution expect numpy array of one dimension."); 308 return NULL; 309 } 310 }else if( PyList_Check(pars)==1) { 311 // Length of list should be 2 for I(qx,qy) 312 mpars = PyList_GET_SIZE(pars); 313 if(mpars!=2) { 314 PyErr_SetString(CTriaxialEllipsoidModelError, 315 "CTriaxialEllipsoidModel.evalDistribution expects a list of dimension 2."); 316 return NULL; 317 } 318 qx = PyList_GET_ITEM(pars,0); 319 qy = PyList_GET_ITEM(pars,1); 320 if (PyArray_Check(qx) && PyArray_Check(qy)) { 321 return evaluateTwoDimXY(self->model, (PyArrayObject*)qx, 322 (PyArrayObject*)qy); 323 }else{ 324 PyErr_SetString(CTriaxialEllipsoidModelError, 325 "CTriaxialEllipsoidModel.evalDistribution expect 2 numpy arrays in list."); 326 return NULL; 327 } 328 }else{ 329 PyErr_SetString(CTriaxialEllipsoidModelError, 330 "CTriaxialEllipsoidModel.evalDistribution couln't be run."); 331 return NULL; 332 } 333 } 140 334 141 335 /** … … 311 505 {"runXY", (PyCFunction)runXY , METH_VARARGS, 312 506 "Evaluate the model at a given Q or Qx, Qy"}, 507 508 {"evalDistribution", (PyCFunction)evalDistribution , METH_VARARGS, 509 "Evaluate the model at a given Q or Qx, Qy vector "}, 313 510 {"reset", (PyCFunction)reset , METH_VARARGS, 314 511 "Reset pair correlation"}, … … 361 558 362 559 363 static PyMethodDef module_methods[] = {364 {NULL}365 };560 //static PyMethodDef module_methods[] = { 561 // {NULL} 562 //}; 366 563 367 564 /**
Note: See TracChangeset
for help on using the changeset viewer.