Ignore:
Timestamp:
Nov 7, 2017 10:00:25 AM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
54b0650
Parents:
0fc5a03
Message:

convert sldi from C++ to C

Location:
src/sas/sascalc/calculator/c_extensions
Files:
1 added
1 deleted
2 moved

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/calculator/c_extensions/sld2i.c

    rb523c0e r0957bb3a  
    22Computes the (magnetic) scattering form sld (n and m) profile 
    33 */ 
    4 #include "sld2i.hh" 
    54#include <stdio.h> 
    65#include <math.h> 
    7 using namespace std; 
    8 extern "C" { 
    9         #include "libfunc.h" 
    10         #include "librefl.h" 
    11 } 
     6#include "sld2i.h" 
     7#include "libfunc.h" 
     8#include "librefl.h" 
    129/** 
    1310 * Constructor for GenI 
     
    2825 * @param s_theta: angle (from x-axis) of the up spin in degree 
    2926 */ 
    30 GenI :: GenI(int npix, double* x, double* y, double* z, double* sldn, 
     27void initGenI(GenI* this, int npix, double* x, double* y, double* z, double* sldn, 
    3128                        double* mx, double* my, double* mz, double* voli, 
    3229                        double in_spin, double out_spin, 
    3330                        double s_theta) { 
    34         //this->qx_val = qx; 
    35         //this->qy_val = qy; 
    36         //this->qz_val = qz; 
    3731        this->n_pix = npix; 
    3832        this->x_val = x; 
     
    4741        this->outspin = out_spin; 
    4842        this->stheta = s_theta; 
    49 }; 
     43} 
    5044 
    5145/** 
    5246 * Compute 2D anisotropic 
    5347 */ 
    54 void GenI :: genicomXY(int npoints, double *qx, double *qy, double *I_out){ 
    55         //npoints is given negative for angular averaging  
     48void genicomXY(GenI* this, int npoints, double *qx, double *qy, double *I_out){ 
     49        //npoints is given negative for angular averaging 
    5650        // Assumes that q doesn't have qz component and sld_n is all real 
    5751        //double q = 0.0; 
     
    7670        //int y_size = 0; //in Ang 
    7771        //int z_size = 0; //in Ang 
    78          
     72 
    7973        // Loop over q-values and multiply apply matrix 
    80          
     74 
    8175        for(int i=0; i<npoints; i++){ 
    8276                //I_out[i] = 0.0; 
     
    8478                sumj_ud = cassign(0.0, 0.0); 
    8579                sumj_du = cassign(0.0, 0.0); 
    86                 sumj_dd = cassign(0.0, 0.0);             
     80                sumj_dd = cassign(0.0, 0.0); 
    8781                //printf ("%d ", i); 
    8882                //q = sqrt(qx[i]*qx[i] + qy[i]*qy[i]); // + qz[i]*qz[i]); 
    8983 
    90                 for(int j=0; j<n_pix; j++){ 
    91                         if (sldn_val[j]!=0.0||mx_val[j]!=0.0||my_val[j]!=0.0||mz_val[j]!=0.0) 
    92                         {        
     84                for(int j=0; j<this->n_pix; j++){ 
     85                        if (this->sldn_val[j]!=0.0 
     86                                ||this->mx_val[j]!=0.0 
     87                                ||this->my_val[j]!=0.0 
     88                                ||this->mz_val[j]!=0.0) 
     89                        { 
    9390                                //anisotropic 
    9491                                temp_fi = cassign(0.0, 0.0); 
    95                                 b_sld = cal_msld(0, qx[i], qy[i], sldn_val[j], 
    96                                                          mx_val[j], my_val[j], mz_val[j], 
    97                                                          inspin, outspin, stheta); 
    98                                 qr = (qx[i]*x_val[j] + qy[i]*y_val[j]); 
     92                                b_sld = cal_msld(0, qx[i], qy[i], this->sldn_val[j], 
     93                                                         this->mx_val[j], this->my_val[j], this->mz_val[j], 
     94                                                         this->inspin, this->outspin, this->stheta); 
     95                                qr = (qx[i]*this->x_val[j] + qy[i]*this->y_val[j]); 
    9996                                iqr = cassign(0.0, qr); 
    10097                                ephase = cplx_exp(iqr); 
    101                                  
     98 
    10299                                //Let's multiply pixel(atomic) volume here 
    103                                 ephase = rcmult(vol_pix[j], ephase); 
     100                                ephase = rcmult(this->vol_pix[j], ephase); 
    104101                                //up_up 
    105                                 if (inspin > 0.0 && outspin > 0.0){ 
     102                                if (this->inspin > 0.0 && this->outspin > 0.0){ 
    106103                                        comp_sld = cassign(b_sld.uu, 0.0); 
    107104                                        temp_fi = cplx_mult(comp_sld, ephase); 
     
    109106                                } 
    110107                                //down_down 
    111                                 if (inspin < 1.0 && outspin < 1.0){ 
     108                                if (this->inspin < 1.0 && this->outspin < 1.0){ 
    112109                                        comp_sld = cassign(b_sld.dd, 0.0); 
    113110                                        temp_fi = cplx_mult(comp_sld, ephase); 
     
    115112                                } 
    116113                                //up_down 
    117                                 if (inspin > 0.0 && outspin < 1.0){ 
     114                                if (this->inspin > 0.0 && this->outspin < 1.0){ 
    118115                                        comp_sld = cassign(b_sld.re_ud, b_sld.im_ud); 
    119116                                        temp_fi = cplx_mult(comp_sld, ephase); 
     
    121118                                } 
    122119                                //down_up 
    123                                 if (inspin < 1.0 && outspin > 0.0){ 
     120                                if (this->inspin < 1.0 && this->outspin > 0.0){ 
    124121                                        comp_sld = cassign(b_sld.re_du, b_sld.im_du); 
    125122                                        temp_fi = cplx_mult(comp_sld, ephase); 
     
    129126 
    130127                                if (i == 0){ 
    131                                         count += vol_pix[j]; 
     128                                        count += this->vol_pix[j]; 
    132129                                } 
    133130                        } 
     
    149146 * Also assumes there is no polarization: No dependency on spin 
    150147 */ 
    151 void GenI :: genicom(int npoints, double *q, double *I_out){ 
    152         //npoints is given negative for angular averaging  
     148void genicom(GenI* this, int npoints, double *q, double *I_out){ 
     149        //npoints is given negative for angular averaging 
    153150        // Assumes that q doesn't have qz component and sld_n is all real 
    154151        //double Pi = 4.0*atan(1.0); 
    155         int is_sym = 0; 
     152        int is_sym = this->n_pix < 0; 
    156153        double qr = 0.0; 
    157154        double sumj; 
    158155        double sld_j = 0.0; 
    159156        double count = 0.0; 
    160         if (n_pix < 0 ){ 
    161                 is_sym = 1; 
    162                 n_pix = n_pix * -1; 
    163         } 
     157        int n_pix = is_sym ? -this->n_pix : this->n_pix; 
    164158        //Assume that pixel volumes are given in vol_pix in A^3 unit 
    165159        // Loop over q-values and multiply apply matrix 
    166160        for(int i=0; i<npoints; i++){ 
    167                 sumj =0.0;               
     161                sumj =0.0; 
    168162                for(int j=0; j<n_pix; j++){ 
    169163                        //Isotropic: Assumes all slds are real (no magnetic) 
     
    171165                        if (is_sym == 1){ 
    172166                                // approximation for a spherical symmetric particle 
    173                                 qr = sqrt(x_val[j]*x_val[j]+y_val[j]*y_val[j]+z_val[j]*z_val[j])*q[i]; 
     167                                qr = sqrt(this->x_val[j]*this->x_val[j]+this->y_val[j]*this->y_val[j]+this->z_val[j]*this->z_val[j])*q[i]; 
    174168                                if (qr > 0.0){ 
    175169                                        qr = sin(qr) / qr; 
    176                                         sumj += sldn_val[j] * vol_pix[j] * qr; 
     170                                        sumj += this->sldn_val[j] * this->vol_pix[j] * qr; 
    177171                                } 
    178172                                else{ 
    179                                         sumj += sldn_val[j] * vol_pix[j]; 
     173                                        sumj += this->sldn_val[j] * this->vol_pix[j]; 
    180174                                } 
    181175                        } 
     
    184178                                //pragma omp parallel for 
    185179                                for(int k=0; k<n_pix; k++){ 
    186                                         sld_j =  sldn_val[j] * sldn_val[k] * vol_pix[j] * vol_pix[k]; 
    187                                         qr = (x_val[j]-x_val[k])*(x_val[j]-x_val[k])+ 
    188                                                       (y_val[j]-y_val[k])*(y_val[j]-y_val[k])+  
    189                                                       (z_val[j]-z_val[k])*(z_val[j]-z_val[k]); 
     180                                        sld_j =  this->sldn_val[j] * this->sldn_val[k] * this->vol_pix[j] * this->vol_pix[k]; 
     181                                        qr = (this->x_val[j]-this->x_val[k])*(this->x_val[j]-this->x_val[k])+ 
     182                                                      (this->y_val[j]-this->y_val[k])*(this->y_val[j]-this->y_val[k])+ 
     183                                                      (this->z_val[j]-this->z_val[k])*(this->z_val[j]-this->z_val[k]); 
    190184                                        qr = sqrt(qr) * q[i]; 
    191185                                        if (qr > 0.0){ 
     
    198192                        } 
    199193                        if (i == 0){ 
    200                                 count += vol_pix[j]; 
     194                                count += this->vol_pix[j]; 
    201195                        } 
    202196                } 
  • src/sas/sascalc/calculator/c_extensions/sld2i_module.c

    r1d014cb r0957bb3a  
    44#include <Python.h> 
    55#include <stdio.h> 
    6 #include <sld2i.hh> 
     6#include <sld2i.h> 
    77 
    88#if PY_MAJOR_VERSION < 3 
     
    3535void 
    3636del_sld2i(PyObject *obj){ 
    37         GenI* sld2i = static_cast<GenI *>(PyCapsule_GetPointer(obj, "GenI")); 
    38         delete sld2i; 
    39         return; 
     37        GenI* sld2i = (GenI *)(PyCapsule_GetPointer(obj, "GenI")); 
     38        PyMem_Free((void *)sld2i); 
    4039} 
    4140 
     
    4342 * Create a GenI as a python object by supplying arrays 
    4443 */ 
    45 PyObject * new_GenI(PyObject *, PyObject *args) { 
     44PyObject * new_GenI(PyObject *self, PyObject *args) { 
    4645        PyObject *x_val_obj; 
    4746        PyObject *y_val_obj; 
     
    7978        OUTVECTOR(mz_val_obj, mz_val, n_x); 
    8079        OUTVECTOR(vol_pix_obj, vol_pix, n_x); 
    81         GenI* sld2i = new GenI(n_pix,x_val,y_val,z_val,sldn_val,mx_val,my_val,mz_val,vol_pix,inspin,outspin,stheta); 
     80        GenI* sld2i =  PyMem_Malloc(sizeof(GenI)); 
     81        if (sld2i != NULL) { 
     82                initGenI(sld2i, n_pix,x_val,y_val,z_val,sldn_val,mx_val,my_val,mz_val,vol_pix,inspin,outspin,stheta); 
     83        } 
    8284        return PyCapsule_New(sld2i, "GenI", del_sld2i); 
    8385} 
     
    8688 * GenI the given input (2D) according to a given object 
    8789 */ 
    88 PyObject * genicom_inputXY(PyObject *, PyObject *args) { 
     90PyObject * genicom_inputXY(PyObject *self, PyObject *args) { 
    8991        int npoints; 
    9092        PyObject *qx_obj; 
     
    106108 
    107109        // Set the array pointers 
    108         void *temp = PyCapsule_GetPointer(gen_obj, "GenI"); 
    109         GenI* s = static_cast<GenI *>(temp); 
    110  
    111         s->genicomXY(npoints, qx, qy, I_out); 
     110        GenI* sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI"); 
     111 
     112        genicomXY(sld2i, npoints, qx, qy, I_out); 
    112113        //return PyCObject_FromVoidPtr(s, del_genicom); 
    113114        return Py_BuildValue("i",1); 
     
    117118 * GenI the given 1D input according to a given object 
    118119 */ 
    119 PyObject * genicom_input(PyObject *, PyObject *args) { 
     120PyObject * genicom_input(PyObject *self, PyObject *args) { 
    120121        int npoints; 
    121122        PyObject *q_obj; 
     
    134135 
    135136        // Set the array pointers 
    136         void *temp = PyCapsule_GetPointer(gen_obj, "GenI"); 
    137         GenI* s = static_cast<GenI *>(temp); 
    138  
    139         s->genicom(npoints, q, I_out); 
     137        GenI *sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI"); 
     138 
     139        genicom(sld2i, npoints, q, I_out); 
    140140        //return PyCObject_FromVoidPtr(s, del_genicom); 
    141141        return Py_BuildValue("i",1); 
Note: See TracChangeset for help on using the changeset viewer.