Changeset af03ddd in sasview for sansmodels/src/sans/models


Ignore:
Timestamp:
Aug 18, 2008 2:19:47 PM (16 years ago)
Author:
Mathieu Doucet <doucetm@…>
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
Message:

Model C extension update

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  
    11#!/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 
    216""" Provide functionality for a C extension model 
    317 
    418        WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY 
    5                  DO NOT MODIFY THIS FILE, MODIFY cylinder.h 
     19                 DO NOT MODIFY THIS FILE, MODIFY ../c_extensions/cylinder.h 
    620                 AND RE-RUN THE GENERATOR SCRIPT 
    721 
    8     @author: Mathieu Doucet / UTK 
    9     @contact: mathieu.doucet@nist.gov 
    1022""" 
    1123 
     
    1628class CylinderModel(CCylinderModel, BaseComponent): 
    1729    """ 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. 
    1931        Refer to that file and the structure it contains 
    2032        for details of the model. 
     
    7284         
    7385        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         
    7495    
    7596# End of file 
  • sansmodels/src/sans/models/c_extensions/c_models.c

    rae3ce4e raf03ddd  
    11/** c_models 
    22 * 
    3  * Module containing all SANS model extensions  
     3 * Module containing all SANS model extensions 
    44 * 
    55 * @author   M.Doucet / UTK 
     
    1111 */ 
    1212static PyMethodDef module_methods[] = { 
    13     {NULL}  
     13    {NULL} 
    1414}; 
    1515 
     
    1919#endif 
    2020PyMODINIT_FUNC 
    21 initc_models(void)  
     21initc_models(void) 
    2222{ 
    2323    PyObject* m; 
     
    2525    m = Py_InitModule3("c_models", module_methods, 
    2626                       "C extension module for SANS scattering models."); 
    27                         
     27 
    2828        addCCylinderModel(m); 
    2929        addCCoreShellCylinderModel(m); 
  • sansmodels/src/sans/models/c_extensions/cylinder.h

    rae3ce4e raf03ddd  
    22#define cylinder_h 
    33 
    4 /** Structure definition for cylinder parameters  
     4/** Structure definition for cylinder parameters 
    55 * [PYTHONCLASS] = CylinderModel 
     6 * [DISP_PARAMS] = radius, length, cyl_theta, cyl_phi 
    67 * */ 
    78typedef struct { 
    8     /// Scale factor  
     9    /// Scale factor 
    910    //  [DEFAULT]=scale=1.0 
    1011    double scale; 
    1112    /// Radius of the cylinder [A] 
    12     //  [DEFAULT]=radius=20.0 A  
     13    //  [DEFAULT]=radius=20.0 A 
    1314    double radius; 
    1415    /// Length of the cylinder [A] 
     
    2021        /// Incoherent Background (cm-1) 0.000 
    2122        //  [DEFAULT]=background=0 cm-1 
    22         double background;     
     23        double background; 
    2324    /// Orientation of the cylinder axis w/respect incoming beam [rad] 
    2425    //  [DEFAULT]=cyl_theta=1.0 rad 
     
    2627    /// Orientation of the cylinder in the plane of the detector [rad] 
    2728    //  [DEFAULT]=cyl_phi=1.0 rad 
    28     double cyl_phi;     
     29    double cyl_phi; 
    2930} CylinderParameters; 
    3031 
  • 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 
    216 * 
    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 
    422 * 
    523 */ 
     24  
    625extern "C" { 
    726#include <Python.h> 
     
    1433} 
    1534 
    16  
    1735#include "models.hh" 
    1836#include "dispersion_visitor.hh" 
     
    2745    /// Parameters 
    2846    PyObject * params; 
     47    /// Dispersion parameters 
    2948    PyObject * dispersion; 
    30     Cylinder * model; 
     49    /// Underlying model object 
     50    CylinderModel * model; 
    3151    /// Log for unit testing 
    3252    PyObject * log; 
    33     /// Model parameters 
    34         CylinderParameters model_pars; 
    3553} CCylinderModel; 
    3654 
     
    4058{ 
    4159    self->ob_type->tp_free((PyObject*)self); 
    42  
     60     
    4361 
    4462} 
     
    4866{ 
    4967    CCylinderModel *self; 
    50  
     68     
    5169    self = (CCylinderModel *)type->tp_alloc(type, 0); 
    52  
     70    
    5371    return (PyObject *)self; 
    5472} 
     
    5876{ 
    5977    if (self != NULL) { 
    60         printf("Hello cylinder\n"); 
     78         
    6179        // Create parameters 
    6280        self->params = PyDict_New(); 
    6381        self->dispersion = PyDict_New(); 
    64         self->model = new Cylinder(); 
    65  
     82        self->model = new CylinderModel(); 
     83         
    6684        // Initialize parameter dictionary 
    67         PyDict_SetItemString(self->params,"scale",     Py_BuildValue("d", self->model->scale())); 
    68         PyDict_SetItemString(self->params,"length",    Py_BuildValue("d", self->model->length())); 
    69         PyDict_SetItemString(self->params,"cyl_theta", Py_BuildValue("d", self->model->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())); 
    7088        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())); 
    7592        // Initialize dispersion / averaging parameter dict 
    7693        DispersionVisitor* visitor = new DispersionVisitor(); 
    77         PyObject * disp_dict = PyDict_New(); 
     94        PyObject * disp_dict; 
     95        disp_dict = PyDict_New(); 
    7896        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); 
    8198        disp_dict = PyDict_New(); 
    8299        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); 
    85104        disp_dict = PyDict_New(); 
    86105        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          
    93110        // Create empty log 
    94111        self->log = PyDict_New(); 
     112         
     113         
    95114 
    96115    } 
     
    99118 
    100119static PyMemberDef CCylinderModel_members[] = { 
    101         {"params", T_OBJECT, offsetof(CCylinderModel, params), 0, 
    102         "Parameters"}, 
     120    {"params", T_OBJECT, offsetof(CCylinderModel, params), 0, 
     121    "Parameters"}, 
    103122        {"dispersion", T_OBJECT, offsetof(CCylinderModel, dispersion), 0, 
    104           "Dispersion parameters"}, 
     123          "Dispersion parameters"},      
    105124    {"log", T_OBJECT, offsetof(CCylinderModel, log), 0, 
    106125     "Log"}, 
     
    124143} 
    125144 
    126 /** 
    127  * Method to set the dispersion model for a parameter. 
    128  * We need to update the dispersion object of the parameter 
    129  * 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 this 
    132  * 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 string 
    135  * 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  
    142145 
    143146/** 
     
    150153        PyObject* pars; 
    151154        int npars; 
    152  
     155         
    153156        // Get parameters 
    154  
    155         // Reader parameter dictionary 
     157         
     158            // Reader parameter dictionary 
    156159    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 
    157160    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") ); 
     
    161164    self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 
    162165    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") ); 
    163  
    164166    // Read in dispersion parameters 
     167    PyObject* disp_dict; 
    165168    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"); 
    168170    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict); 
     171    disp_dict = PyDict_GetItemString(self->dispersion, "length"); 
    169172    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict); 
     173    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta"); 
    170174    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"); 
    171176    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict); 
    172177 
     178         
    173179        // Get input and determine whether we have to supply a 1D or 2D return value. 
    174180        if ( !PyArg_ParseTuple(args,"O",&pars) ) { 
    175             PyErr_SetString(CCylinderModelError, 
     181            PyErr_SetString(CCylinderModelError,  
    176182                "CCylinderModel.run expects a q value."); 
    177183                return NULL; 
    178184        } 
    179  
     185           
    180186        // Check params 
    181187        if( PyList_Check(pars)==1) { 
    182  
     188                 
    183189                // Length of list should be 2 for I(q,phi) 
    184             npars = PyList_GET_SIZE(pars); 
     190            npars = PyList_GET_SIZE(pars);  
    185191            if(npars!=2) { 
    186                 PyErr_SetString(CCylinderModelError, 
     192                PyErr_SetString(CCylinderModelError,  
    187193                        "CCylinderModel.run expects a double or a list of dimension 2."); 
    188194                return NULL; 
     
    201207 
    202208                // We have a scalar q, we will evaluate I(q) 
    203                 q_value = CCylinderModel_readDouble(pars); 
    204  
     209                q_value = CCylinderModel_readDouble(pars);               
     210                 
    205211                return Py_BuildValue("d",(*(self->model))(q_value)); 
    206         } 
     212        }        
    207213} 
    208214 
     
    216222        PyObject* pars; 
    217223        int npars; 
    218  
     224         
    219225        // Get parameters 
    220  
    221         // Reader parameter dictionary 
     226         
     227            // Reader parameter dictionary 
    222228    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") ); 
    223229    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") ); 
     
    227233    self->model->contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") ); 
    228234    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") ); 
    229  
    230235    // Read in dispersion parameters 
     236    PyObject* disp_dict; 
    231237    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"); 
    234239    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict); 
     240    disp_dict = PyDict_GetItemString(self->dispersion, "length"); 
    235241    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict); 
     242    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta"); 
    236243    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"); 
    237245    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict); 
    238246 
     247         
    239248        // Get input and determine whether we have to supply a 1D or 2D return value. 
    240249        if ( !PyArg_ParseTuple(args,"O",&pars) ) { 
    241             PyErr_SetString(CCylinderModelError, 
     250            PyErr_SetString(CCylinderModelError,  
    242251                "CCylinderModel.run expects a q value."); 
    243252                return NULL; 
    244253        } 
    245  
     254           
    246255        // Check params 
    247256        if( PyList_Check(pars)==1) { 
    248  
     257                 
    249258                // Length of list should be 2 for I(qx, qy)) 
    250             npars = PyList_GET_SIZE(pars); 
     259            npars = PyList_GET_SIZE(pars);  
    251260            if(npars!=2) { 
    252                 PyErr_SetString(CCylinderModelError, 
     261                PyErr_SetString(CCylinderModelError,  
    253262                        "CCylinderModel.run expects a double or a list of dimension 2."); 
    254263                return NULL; 
     
    263272 
    264273                // We have a scalar q, we will evaluate I(q) 
    265                 qx_value = CCylinderModel_readDouble(pars); 
    266  
     274                qx_value = CCylinderModel_readDouble(pars);              
     275                 
    267276                return Py_BuildValue("d",(*(self->model))(qx_value)); 
     277        }        
     278} 
     279 
     280static PyObject * reset(CCylinderModel *self, PyObject *args) { 
     281     
     282 
     283    return Py_BuildValue("d",0.0); 
     284} 
     285 
     286static 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; 
    268294        } 
    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); 
    275320} 
    276321 
     
    283328    {"reset",    (PyCFunction)reset   , METH_VARARGS, 
    284329      "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"}, 
    287332   {NULL} 
    288333}; 
     
    332377 
    333378static PyMethodDef module_methods[] = { 
    334     {NULL} 
     379    {NULL}  
    335380}; 
    336381 
     
    338383 * Function used to add the model class to a module 
    339384 * @param module: module to add the class to 
    340  */ 
     385 */  
    341386void addCCylinderModel(PyObject *module) { 
    342387        PyObject *d; 
    343  
     388         
    344389    if (PyType_Ready(&CCylinderModelType) < 0) 
    345390        return; 
     
    347392    Py_INCREF(&CCylinderModelType); 
    348393    PyModule_AddObject(module, "CCylinderModel", (PyObject *)&CCylinderModelType); 
    349  
     394     
    350395    d = PyModule_GetDict(module); 
    351396    CCylinderModelError = PyErr_NewException("CCylinderModel.error", NULL, NULL); 
  • sansmodels/src/sans/models/c_models/cylinder.cpp

    rfca6936 raf03ddd  
    3232} 
    3333 
    34 Cylinder :: Cylinder() { 
     34CylinderModel :: CylinderModel() { 
    3535        scale      = Parameter(1.0); 
    3636        radius     = Parameter(20.0, true); 
     
    5050 * @return: function value 
    5151 */ 
    52 double Cylinder :: operator()(double q) { 
     52double CylinderModel :: operator()(double q) { 
    5353        double dp[5]; 
    5454 
     
    9696 * @return: function value 
    9797 */ 
    98 double Cylinder :: operator()(double qx, double qy) { 
     98double CylinderModel :: operator()(double qx, double qy) { 
    9999        CylinderParameters dp; 
    100100        // Fill parameter array 
     
    177177 * @return: function value 
    178178 */ 
    179 double Cylinder :: evaluate_rphi(double q, double phi) { 
     179double CylinderModel :: evaluate_rphi(double q, double phi) { 
    180180        double qx = q*cos(phi); 
    181181        double qy = q*sin(phi); 
     
    186186int main(void) 
    187187{ 
    188         Cylinder c = Cylinder(); 
     188        CylinderModel c = CylinderModel(); 
    189189 
    190190        printf("Length = %g\n", c.length()); 
  • sansmodels/src/sans/models/c_models/models.hh

    rfca6936 raf03ddd  
    2323using namespace std; 
    2424 
    25 class Cylinder{ 
     25class CylinderModel{ 
    2626 
    2727public: 
     
    3737 
    3838        // Constructor 
    39         Cylinder(); 
     39        CylinderModel(); 
    4040 
    4141        // Operators to get I(Q) 
  • sansmodels/src/sans/models/test/utest_models.py

    rae3ce4e raf03ddd  
    5050    def test2D(self): 
    5151        """ Test 2D model of a cylinder """  
     52        self.comp.setParam('cyl_theta', 1.0) 
     53        self.comp.setParam('cyl_phi', 1.0) 
    5254        self.assertAlmostEqual(self.comp.run([0.2, 2.5]),  
    5355                               0.038176446608393366, 4) 
Note: See TracChangeset for help on using the changeset viewer.