Ignore:
Timestamp:
Aug 7, 2009 9:10:34 AM (15 years ago)
Author:
Jae Cho <jhjcho@…>
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
Message:

recompiled all due to Alina's new eval(run) function

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/sans/models/c_models/CCylinderModel.cpp

    r4176435 r9bd69098  
    2222 * 
    2323 */ 
     24#define NO_IMPORT_ARRAY 
     25#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API_sans 
    2426  
    2527extern "C" { 
    2628#include <Python.h> 
     29#include <arrayobject.h> 
    2730#include "structmember.h" 
    2831#include <stdio.h> 
     
    142145    } 
    143146} 
    144  
     147/** 
     148 * Function to call to evaluate model 
     149 * @param args: input numpy array q[]  
     150 * @return: numpy array object  
     151 */ 
     152  
     153static PyObject *evaluateOneDim(CylinderModel* model, PyArrayObject *q){ 
     154    PyArrayObject *result; 
     155    
     156    // Check validity of array q , q must be of dimension 1, an array of double 
     157    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE) 
     158    { 
     159        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 
     160        //PyErr_SetString(PyExc_ValueError , message); 
     161        return NULL; 
     162    } 
     163    result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions),  
     164                                                                                  PyArray_DOUBLE); 
     165        if (result == NULL) { 
     166        const char * message= "Could not create result "; 
     167        PyErr_SetString(PyExc_RuntimeError , message); 
     168                return NULL; 
     169        } 
     170         for (int i = 0; i < q->dimensions[0]; i++){ 
     171      double q_value  = *(double *)(q->data + i*q->strides[0]); 
     172      double *result_value = (double *)(result->data + i*result->strides[0]); 
     173      *result_value =(*model)(q_value); 
     174        } 
     175    return PyArray_Return(result);  
     176 } 
     177/** 
     178 * Function to call to evaluate model 
     179 * @param args: input numpy array  [q[],phi[]] 
     180 * @return: numpy array object  
     181 */ 
     182static PyObject * evaluateTwoDim( CylinderModel* model,  
     183                              PyArrayObject *q, PyArrayObject *phi) 
     184 { 
     185    PyArrayObject *result; 
     186    //check validity of input vectors 
     187    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE 
     188        || phi->nd != 1 || phi->descr->type_num != PyArray_DOUBLE 
     189        || phi->dimensions[0] != q->dimensions[0]){ 
     190      
     191        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num; 
     192        PyErr_SetString(PyExc_ValueError ,"wrong input");  
     193        return NULL; 
     194    } 
     195        result= (PyArrayObject *)PyArray_FromDims(q->nd,(int*)(q->dimensions), PyArray_DOUBLE); 
     196 
     197        if (result == NULL){ 
     198            const char * message= "Could not create result "; 
     199        PyErr_SetString(PyExc_RuntimeError , message); 
     200            return NULL; 
     201        } 
     202         
     203    for (int i = 0; i < q->dimensions[0]; i++) { 
     204      double q_value = *(double *)(q->data + i*q->strides[0]); 
     205      double phi_value = *(double *)(phi->data + i*phi->strides[0]); 
     206      double *result_value = (double *)(result->data + i*result->strides[0]); 
     207      if (q_value == 0) 
     208          *result_value = 0.0; 
     209      else 
     210          *result_value = model->evaluate_rphi(q_value, phi_value); 
     211    } 
     212    return PyArray_Return(result);  
     213 } 
     214 /** 
     215 * Function to call to evaluate model 
     216 * @param args: input numpy array  [x[],y[]] 
     217 * @return: numpy array object  
     218 */ 
     219 static PyObject * evaluateTwoDimXY( CylinderModel* model,  
     220                              PyArrayObject *x, PyArrayObject *y) 
     221 { 
     222    PyArrayObject *result; 
     223    int i,j, x_len, y_len, dims[2]; 
     224    //check validity of input vectors 
     225    if (x->nd != 2 || x->descr->type_num != PyArray_DOUBLE 
     226        || y->nd != 2 || y->descr->type_num != PyArray_DOUBLE 
     227        || y->dimensions[1] != x->dimensions[0]){ 
     228        const char * message= "evaluateTwoDimXY  expect 2 numpy arrays"; 
     229        PyErr_SetString(PyExc_ValueError , message);  
     230        return NULL; 
     231    } 
     232    
     233        if (PyArray_Check(x) && PyArray_Check(y)) { 
     234            x_len = dims[0]= x->dimensions[0]; 
     235        y_len = dims[1]= y->dimensions[1]; 
     236             
     237            // Make a new double matrix of same dims 
     238        result=(PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE); 
     239        if (result == NULL){ 
     240            const char * message= "Could not create result "; 
     241        PyErr_SetString(PyExc_RuntimeError , message); 
     242            return NULL; 
     243            } 
     244        
     245        /* Do the calculation. */ 
     246        for ( i=0; i< x_len; i++) { 
     247            for ( j=0; j< y_len; j++) { 
     248                double x_value = *(double *)(x->data + i*x->strides[0]); 
     249                    double y_value = *(double *)(y->data + j*y->strides[1]); 
     250                        double *result_value = (double *)(result->data + 
     251                              i*result->strides[0] + j*result->strides[1]); 
     252                        *result_value = (*model)(x_value, y_value); 
     253            }            
     254        } 
     255        return PyArray_Return(result);  
     256         
     257        }else{ 
     258                    PyErr_SetString(CCylinderModelError,  
     259                   "CCylinderModel.evaluateTwoDimXY couldn't run."); 
     260                return NULL; 
     261                }        
     262} 
     263/** 
     264 *  evalDistribution function evaluate a model function with input vector 
     265 *  @param args: input q as vector or [qx, qy] where qx, qy are vectors 
     266 * 
     267 */  
     268static PyObject * evalDistribution(CCylinderModel *self, PyObject *args){ 
     269        PyObject *qx, *qy; 
     270        PyArrayObject * pars; 
     271        int npars ,mpars; 
     272         
     273        // Get parameters 
     274         
     275            // Reader parameter dictionary 
     276    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 
     277    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") ); 
     278    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") ); 
     279    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") ); 
     280    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") ); 
     281    self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 
     282    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") ); 
     283    // Read in dispersion parameters 
     284    PyObject* disp_dict; 
     285    DispersionVisitor* visitor = new DispersionVisitor(); 
     286    disp_dict = PyDict_GetItemString(self->dispersion, "radius"); 
     287    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict); 
     288    disp_dict = PyDict_GetItemString(self->dispersion, "length"); 
     289    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict); 
     290    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta"); 
     291    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict); 
     292    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi"); 
     293    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict); 
     294 
     295         
     296        // Get input and determine whether we have to supply a 1D or 2D return value. 
     297        if ( !PyArg_ParseTuple(args,"O",&pars) ) { 
     298            PyErr_SetString(CCylinderModelError,  
     299                "CCylinderModel.evalDistribution expects a q value."); 
     300                return NULL; 
     301        } 
     302    // Check params 
     303         
     304    if(PyArray_Check(pars)==1) { 
     305                 
     306            // Length of list should 1 or 2 
     307            npars = pars->nd;  
     308            if(npars==1) { 
     309                // input is a numpy array 
     310                if (PyArray_Check(pars)) { 
     311                        return evaluateOneDim(self->model, (PyArrayObject*)pars);  
     312                    } 
     313                }else{ 
     314                    PyErr_SetString(CCylinderModelError,  
     315                   "CCylinderModel.evalDistribution expect numpy array of one dimension."); 
     316                return NULL; 
     317                } 
     318    }else if( PyList_Check(pars)==1) { 
     319        // Length of list should be 2 for I(qx,qy) 
     320            mpars = PyList_GET_SIZE(pars);  
     321            if(mpars!=2) { 
     322                PyErr_SetString(CCylinderModelError,  
     323                        "CCylinderModel.evalDistribution expects a list of dimension 2."); 
     324                return NULL; 
     325            } 
     326             qx = PyList_GET_ITEM(pars,0); 
     327             qy = PyList_GET_ITEM(pars,1); 
     328             if (PyArray_Check(qx) && PyArray_Check(qy)) { 
     329                 return evaluateTwoDimXY(self->model, (PyArrayObject*)qx, 
     330                           (PyArrayObject*)qy); 
     331                 }else{ 
     332                    PyErr_SetString(CCylinderModelError,  
     333                   "CCylinderModel.evalDistribution expect 2 numpy arrays in list."); 
     334                return NULL; 
     335             } 
     336        }else{ 
     337            PyErr_SetString(CCylinderModelError,  
     338                   "CCylinderModel.evalDistribution couln't be run."); 
     339            return NULL; 
     340        } 
     341} 
    145342 
    146343/** 
     
    326523    {"runXY",      (PyCFunction)runXY     , METH_VARARGS, 
    327524      "Evaluate the model at a given Q or Qx, Qy"}, 
     525       
     526    {"evalDistribution",  (PyCFunction)evalDistribution , METH_VARARGS, 
     527      "Evaluate the model at a given Q or Qx, Qy vector "}, 
    328528    {"reset",    (PyCFunction)reset   , METH_VARARGS, 
    329529      "Reset pair correlation"}, 
     
    376576 
    377577 
    378 static PyMethodDef module_methods[] = { 
    379     {NULL}  
    380 }; 
     578//static PyMethodDef module_methods[] = { 
     579//    {NULL}  
     580//}; 
    381581 
    382582/** 
Note: See TracChangeset for help on using the changeset viewer.