Changeset c637521 in sasview for sansmodels


Ignore:
Timestamp:
Jan 5, 2012 10:10:53 AM (13 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:
7ffa8196
Parents:
df88829
Message:

refactor onion model

Location:
sansmodels/src
Files:
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/c_extensions/onion.h

    r67424cd rc637521  
    11#if !defined(o_h) 
    22#define onion_h 
     3#include "parameters.hh" 
    34 
    45/** 
     
    3435 //[ORIENTATION_PARAMS]= <text> </text> 
    3536 
    36 typedef struct { 
    37         /// number of shells 
    38         //  [DEFAULT]=n_shells=1 
    39         int n_shells; 
    40     /// Scale factor 
    41     //  [DEFAULT]=scale= 1.0 
    42         double scale; 
    43     /// Radius of sphere [A] 
    44     //  [DEFAULT]=rad_core0=200.0 [A] 
    45         double rad_core0; 
    46         ///     sld_core [1/A^(2)] 
    47         //  [DEFAULT]=sld_core0= 1.0e-6 [1/A^(2)] 
    48         double sld_core0; 
    49         ///     sld_solv [1/A^(2)] 
    50         //  [DEFAULT]=sld_solv= 6.4e-6 [1/A^(2)] 
    51         double sld_solv; 
    52         /// Incoherent Background [1/cm] 
    53         //  [DEFAULT]=background=0 [1/cm] 
    54         double background; 
     37class OnionModel{ 
     38public: 
     39    // Model parameters 
     40    /// number of shells 
     41    //  [DEFAULT]=n_shells=1 
     42    Parameter n_shells; 
     43      /// Scale factor 
     44      //  [DEFAULT]=scale= 1.0 
     45    Parameter scale; 
     46      /// Radius of sphere [A] 
     47      //  [DEFAULT]=rad_core0=200.0 [A] 
     48    Parameter rad_core0; 
     49    /// sld_core [1/A^(2)] 
     50    //  [DEFAULT]=sld_core0= 1.0e-6 [1/A^(2)] 
     51    Parameter sld_core0; 
     52    /// sld_solv [1/A^(2)] 
     53    //  [DEFAULT]=sld_solv= 6.4e-6 [1/A^(2)] 
     54    Parameter sld_solv; 
     55    /// Incoherent Background [1/cm] 
     56    //  [DEFAULT]=background=0 [1/cm] 
     57    Parameter background; 
    5558 
    5659    //  [DEFAULT]=sld_out_shell1=2.0e-06 [1/A^(2)] 
    57     double sld_out_shell1; 
     60    Parameter sld_out_shell1; 
    5861    //  [DEFAULT]=sld_out_shell2=2.5e-06 [1/A^(2)] 
    59     double sld_out_shell2; 
     62    Parameter sld_out_shell2; 
    6063    //  [DEFAULT]=sld_out_shell3=3.0e-06 [1/A^(2)] 
    61     double sld_out_shell3; 
     64    Parameter sld_out_shell3; 
    6265    //  [DEFAULT]=sld_out_shell4=3.5e-06 [1/A^(2)] 
    63     double sld_out_shell4; 
     66    Parameter sld_out_shell4; 
    6467    //  [DEFAULT]=sld_out_shell5=4.0e-06 [1/A^(2)] 
    65     double sld_out_shell5; 
     68    Parameter sld_out_shell5; 
    6669    //  [DEFAULT]=sld_out_shell6=4.5e-06 [1/A^(2)] 
    67     double sld_out_shell6; 
     70    Parameter sld_out_shell6; 
    6871    //  [DEFAULT]=sld_out_shell7=5.0e-06 [1/A^(2)] 
    69     double sld_out_shell7; 
     72    Parameter sld_out_shell7; 
    7073    //  [DEFAULT]=sld_out_shell8=5.5e-06 [1/A^(2)] 
    71     double sld_out_shell8; 
     74    Parameter sld_out_shell8; 
    7275    //  [DEFAULT]=sld_out_shell9=6.0e-06 [1/A^(2)] 
    73     double sld_out_shell9; 
     76    Parameter sld_out_shell9; 
    7477    //  [DEFAULT]=sld_out_shell10=6.2e-06 [1/A^(2)] 
    75     double sld_out_shell10; 
     78    Parameter sld_out_shell10; 
    7679 
    7780    //  [DEFAULT]=sld_in_shell1=1.7e-06 [1/A^(2)] 
    78     double sld_in_shell1; 
     81    Parameter sld_in_shell1; 
    7982    //  [DEFAULT]=sld_in_shell2=2.2e-06 [1/A^(2)] 
    80     double sld_in_shell2; 
     83    Parameter sld_in_shell2; 
    8184    //  [DEFAULT]=sld_in_shell3=2.7e-06 [1/A^(2)] 
    82     double sld_in_shell3; 
     85    Parameter sld_in_shell3; 
    8386    //  [DEFAULT]=sld_in_shell4=3.2e-06 [1/A^(2)] 
    84     double sld_in_shell4; 
     87    Parameter sld_in_shell4; 
    8588    //  [DEFAULT]=sld_in_shell5=3.7e-06 [1/A^(2)] 
    86     double sld_in_shell5; 
     89    Parameter sld_in_shell5; 
    8790    //  [DEFAULT]=sld_in_shell6=4.2e-06 [1/A^(2)] 
    88     double sld_in_shell6; 
     91    Parameter sld_in_shell6; 
    8992    //  [DEFAULT]=sld_in_shell7=4.7e-06 [1/A^(2)] 
    90     double sld_in_shell7; 
     93    Parameter sld_in_shell7; 
    9194    //  [DEFAULT]=sld_in_shell8=5.2e-06 [1/A^(2)] 
    92     double sld_in_shell8; 
     95    Parameter sld_in_shell8; 
    9396    //  [DEFAULT]=sld_in_shell9=5.7e-06 [1/A^(2)] 
    94     double sld_in_shell9; 
     97    Parameter sld_in_shell9; 
    9598    //  [DEFAULT]=sld_in_shell10=6.0e-06 [1/A^(2)] 
    96     double sld_in_shell10; 
     99    Parameter sld_in_shell10; 
    97100 
    98101    //  [DEFAULT]=A_shell1=1.0 
    99     double A_shell1; 
     102    Parameter A_shell1; 
    100103    //  [DEFAULT]=A_shell2=1.0 
    101     double A_shell2; 
     104    Parameter A_shell2; 
    102105    //  [DEFAULT]=A_shell3=1.0 
    103     double A_shell3; 
     106    Parameter A_shell3; 
    104107    //  [DEFAULT]=A_shell4=1.0 
    105     double A_shell4; 
     108    Parameter A_shell4; 
    106109    //  [DEFAULT]=A_shell5=1.0 
    107     double A_shell5; 
     110    Parameter A_shell5; 
    108111    //  [DEFAULT]=A_shell6=1.0 
    109     double A_shell6; 
     112    Parameter A_shell6; 
    110113    //  [DEFAULT]=A_shell7=1.0 
    111     double A_shell7; 
     114    Parameter A_shell7; 
    112115    //  [DEFAULT]=A_shell8=1.0 
    113     double A_shell8; 
     116    Parameter A_shell8; 
    114117    //  [DEFAULT]=A_shell9=1.0 
    115     double A_shell9; 
     118    Parameter A_shell9; 
    116119    //  [DEFAULT]=A_shell10=1.0 
    117     double A_shell10; 
     120    Parameter A_shell10; 
    118121 
    119122    //  [DEFAULT]=thick_shell1=50.0 [A] 
    120     double thick_shell1; 
     123    Parameter thick_shell1; 
    121124    //  [DEFAULT]=thick_shell2=50.0 [A] 
    122     double thick_shell2; 
     125    Parameter thick_shell2; 
    123126    //  [DEFAULT]=thick_shell3=50.0 [A] 
    124     double thick_shell3; 
     127    Parameter thick_shell3; 
    125128    //  [DEFAULT]=thick_shell4=50.0 [A] 
    126     double thick_shell4; 
     129    Parameter thick_shell4; 
    127130    //  [DEFAULT]=thick_shell5=50.0 [A] 
    128     double thick_shell5; 
     131    Parameter thick_shell5; 
    129132    //  [DEFAULT]=thick_shell6=50.0 [A] 
    130     double thick_shell6; 
     133    Parameter thick_shell6; 
    131134    //  [DEFAULT]=thick_shell7=50.0 [A] 
    132     double thick_shell7; 
     135    Parameter thick_shell7; 
    133136    //  [DEFAULT]=thick_shell8=50.0 [A] 
    134     double thick_shell8; 
     137    Parameter thick_shell8; 
    135138    //  [DEFAULT]=thick_shell9=50.0 [A] 
    136     double thick_shell9; 
     139    Parameter thick_shell9; 
    137140    //  [DEFAULT]=thick_shell10=50.0 [A] 
    138     double thick_shell10; 
     141    Parameter thick_shell10; 
    139142 
    140143    //  [DEFAULT]=func_shell1=2 
    141     int func_shell1; 
     144    Parameter func_shell1; 
    142145    //  [DEFAULT]=func_shell2=2 
    143     int func_shell2; 
     146    Parameter func_shell2; 
    144147    //  [DEFAULT]=func_shell3=2 
    145     int func_shell3; 
     148    Parameter func_shell3; 
    146149    //  [DEFAULT]=func_shell4=2 
    147     int func_shell4; 
     150    Parameter func_shell4; 
    148151    //  [DEFAULT]=func_shell5=2 
    149     int func_shell5; 
     152    Parameter func_shell5; 
    150153    //  [DEFAULT]=func_shell6=2 
    151     int func_shell6; 
     154    Parameter func_shell6; 
    152155    //  [DEFAULT]=func_shell7=2 
    153     int func_shell7; 
     156    Parameter func_shell7; 
    154157    //  [DEFAULT]=func_shell8=2 
    155     int func_shell8; 
     158    Parameter func_shell8; 
    156159    //  [DEFAULT]=func_shell9=2 
    157     int func_shell9; 
     160    Parameter func_shell9; 
    158161    //  [DEFAULT]=func_shell10=2 
    159     int func_shell10; 
    160 } OnionParameters; 
     162    Parameter func_shell10; 
    161163 
    162 double so_kernel(double dq[], double q); 
     164  // Constructor 
     165  OnionModel(); 
    163166 
    164 /// 1D scattering function 
    165 double onion_analytical_1D(OnionParameters *pars, double q); 
    166  
    167 /// 2D scattering function 
    168 double onion_analytical_2D(OnionParameters *pars, double q, double phi); 
    169 double onion_analytical_2DXY(OnionParameters *pars, double qx, double qy); 
     167  // Operators to get I(Q) 
     168  double operator()(double q); 
     169  double operator()(double qx, double qy); 
     170  double calculate_ER(); 
     171  double evaluate_rphi(double q, double phi); 
     172}; 
    170173 
    171174#endif 
  • sansmodels/src/c_models/csparallelepiped.cpp

    rdf88829 rc637521  
    2020 
    2121#include <math.h> 
    22 #include "models.hh" 
    2322#include "parameters.hh" 
    2423#include <stdio.h> 
     
    2625 
    2726extern "C" { 
    28         #include "libCylinder.h" 
    29         #include "libStructureFactor.h" 
    30         #include "csparallelepiped.h" 
    31 } 
     27#include "libCylinder.h" 
     28#include "libStructureFactor.h" 
     29} 
     30#include "csparallelepiped.h" 
    3231 
    3332// Convenience parameter structure 
    3433typedef struct { 
    35     double scale; 
    36     double shortA; 
    37     double midB; 
    38     double longC; 
    39     double rimA; 
    40     double rimB; 
    41     double rimC; 
    42     double sld_rimA; 
    43     double sld_rimB; 
    44     double sld_rimC; 
    45     double sld_pcore; 
    46     double sld_solv; 
    47     double background; 
    48     double parallel_theta; 
    49     double parallel_phi; 
    50     double parallel_psi; 
     34  double scale; 
     35  double shortA; 
     36  double midB; 
     37  double longC; 
     38  double rimA; 
     39  double rimB; 
     40  double rimC; 
     41  double sld_rimA; 
     42  double sld_rimB; 
     43  double sld_rimC; 
     44  double sld_pcore; 
     45  double sld_solv; 
     46  double background; 
     47  double parallel_theta; 
     48  double parallel_phi; 
     49  double parallel_psi; 
    5150} CSParallelepipedParameters; 
    5251 
    5352static double cspkernel(double dp[],double q, double ala, double alb, double alc){ 
    54     // mu passed in is really mu*sqrt(1-sig^2) 
    55     double argA,argB,argC,argtA,argtB,argtC,tmp1,tmp2,tmp3,tmpt1,tmpt2,tmpt3;     //local variables 
     53  // mu passed in is really mu*sqrt(1-sig^2) 
     54  double argA,argB,argC,argtA,argtB,argtC,tmp1,tmp2,tmp3,tmpt1,tmpt2,tmpt3;     //local variables 
    5655 
    5756  double aa,bb,cc, ta,tb,tc; 
     
    8584  tb=(aa+2.0*tb);///bb; 
    8685  tc=(aa+2.0*tc); 
    87     //handle arg=0 separately, as sin(t)/t -> 1 as t->0 
    88     argA = q*aa*ala/2.0; 
    89     argB = q*bb*alb/2.0; 
    90     argC = q*cc*alc/2.0; 
    91     argtA = q*ta*ala/2.0; 
     86  //handle arg=0 separately, as sin(t)/t -> 1 as t->0 
     87  argA = q*aa*ala/2.0; 
     88  argB = q*bb*alb/2.0; 
     89  argC = q*cc*alc/2.0; 
     90  argtA = q*ta*ala/2.0; 
    9291  argtB = q*tb*alb/2.0; 
    9392  argtC = q*tc*alc/2.0; 
    9493 
    95     if(argA==0.0) { 
     94  if(argA==0.0) { 
    9695    tmp1 = 1.0; 
    9796  } else { 
    9897    tmp1 = sin(argA)/argA; 
    99     } 
    100     if (argB==0.0) { 
     98  } 
     99  if (argB==0.0) { 
    101100    tmp2 = 1.0; 
    102101  } else { 
    103102    tmp2 = sin(argB)/argB; 
    104     } 
    105  
    106     if (argC==0.0) { 
     103  } 
     104 
     105  if (argC==0.0) { 
    107106    tmp3 = 1.0; 
    108107  } else { 
    109108    tmp3 = sin(argC)/argC; 
    110     } 
    111     if(argtA==0.0) { 
     109  } 
     110  if(argtA==0.0) { 
    112111    tmpt1 = 1.0; 
    113112  } else { 
    114113    tmpt1 = sin(argtA)/argtA; 
    115     } 
    116     if (argtB==0.0) { 
     114  } 
     115  if (argtB==0.0) { 
    117116    tmpt2 = 1.0; 
    118117  } else { 
    119118    tmpt2 = sin(argtB)/argtB; 
    120     } 
    121     if (argtC==0.0) { 
     119  } 
     120  if (argtC==0.0) { 
    122121    tmpt3 = 1.0; 
    123122  } else { 
    124123    tmpt3 = sin(argtC)*sin(argtC)/argtC/argtC; 
    125     } 
    126     // This expression is different from NIST/IGOR package (I strongly believe the IGOR is wrong!!!). 10/15/2010. 
    127     retVal =( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1+ drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3)* 
    128         ( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1+ drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3);   //  correct FF : square of sum of phase factors 
    129     //retVal *= (tmp3*tmp3); 
    130     retVal /= Vot; 
    131  
    132     return (retVal); 
     124  } 
     125  // This expression is different from NIST/IGOR package (I strongly believe the IGOR is wrong!!!). 10/15/2010. 
     126  retVal =( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1+ drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3)* 
     127      ( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1+ drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3);   //  correct FF : square of sum of phase factors 
     128  //retVal *= (tmp3*tmp3); 
     129  retVal /= Vot; 
     130 
     131  return (retVal); 
    133132 
    134133}//Function cspkernel() 
     
    176175 
    177176 
    178     // parallelepiped c axis orientation 
    179     cparallel_x = sin(theta) * cos(phi); 
    180     cparallel_y = sin(theta) * sin(phi); 
    181     cparallel_z = cos(theta); 
    182  
    183     // q vector 
    184     q_z = 0.0; 
    185  
    186     // Compute the angle btw vector q and the 
    187     // axis of the parallelepiped 
    188     cos_val_c = cparallel_x*q_x + cparallel_y*q_y + cparallel_z*q_z; 
    189     alpha = acos(cos_val_c); 
    190  
    191     // parallelepiped a axis orientation 
    192     parallel_x = sin(psi);//cos(pars->parallel_theta) * sin(pars->parallel_phi)*sin(pars->parallel_psi); 
    193     parallel_y = cos(psi);//cos(pars->parallel_theta) * cos(pars->parallel_phi)*cos(pars->parallel_psi); 
    194  
    195     cos_val_a = parallel_x*q_x + parallel_y*q_y; 
    196  
    197  
    198  
    199     // parallelepiped b axis orientation 
    200     bparallel_x = sqrt(1.0-sin(theta)*cos(phi))*cos(psi);//cos(pars->parallel_theta) * cos(pars->parallel_phi)* cos(pars->parallel_psi); 
    201     bparallel_y = sqrt(1.0-sin(theta)*cos(phi))*sin(psi);//cos(pars->parallel_theta) * sin(pars->parallel_phi)* sin(pars->parallel_psi); 
    202     // axis of the parallelepiped 
    203     cos_val_b = sin(acos(cos_val_a)) ; 
    204  
    205  
    206  
    207     // The following test should always pass 
    208     if (fabs(cos_val_c)>1.0) { 
    209       printf("parallel_ana_2D: Unexpected error: cos(alpha)>1\n"); 
    210       return 0; 
    211     } 
     177  // parallelepiped c axis orientation 
     178  cparallel_x = sin(theta) * cos(phi); 
     179  cparallel_y = sin(theta) * sin(phi); 
     180  cparallel_z = cos(theta); 
     181 
     182  // q vector 
     183  q_z = 0.0; 
     184 
     185  // Compute the angle btw vector q and the 
     186  // axis of the parallelepiped 
     187  cos_val_c = cparallel_x*q_x + cparallel_y*q_y + cparallel_z*q_z; 
     188  alpha = acos(cos_val_c); 
     189 
     190  // parallelepiped a axis orientation 
     191  parallel_x = sin(psi);//cos(pars->parallel_theta) * sin(pars->parallel_phi)*sin(pars->parallel_psi); 
     192  parallel_y = cos(psi);//cos(pars->parallel_theta) * cos(pars->parallel_phi)*cos(pars->parallel_psi); 
     193 
     194  cos_val_a = parallel_x*q_x + parallel_y*q_y; 
     195 
     196 
     197 
     198  // parallelepiped b axis orientation 
     199  bparallel_x = sqrt(1.0-sin(theta)*cos(phi))*cos(psi);//cos(pars->parallel_theta) * cos(pars->parallel_phi)* cos(pars->parallel_psi); 
     200  bparallel_y = sqrt(1.0-sin(theta)*cos(phi))*sin(psi);//cos(pars->parallel_theta) * sin(pars->parallel_phi)* sin(pars->parallel_psi); 
     201  // axis of the parallelepiped 
     202  cos_val_b = sin(acos(cos_val_a)) ; 
     203 
     204 
     205 
     206  // The following test should always pass 
     207  if (fabs(cos_val_c)>1.0) { 
     208    printf("parallel_ana_2D: Unexpected error: cos(alpha)>1\n"); 
     209    return 0; 
     210  } 
    212211 
    213212  // Call the IGOR library function to get the kernel 
     
    235234  double q; 
    236235  q = sqrt(qx*qx+qy*qy); 
    237     return csparallelepiped_analytical_2D_scaled(pars, q, qx/q, qy/q); 
     236  return csparallelepiped_analytical_2D_scaled(pars, q, qx/q, qy/q); 
    238237} 
    239238 
     
    242241 
    243242CSParallelepipedModel :: CSParallelepipedModel() { 
    244         scale      = Parameter(1.0); 
    245         shortA     = Parameter(35.0, true); 
    246         shortA.set_min(1.0); 
    247         midB     = Parameter(75.0, true); 
    248         midB.set_min(1.0); 
    249         longC    = Parameter(400.0, true); 
    250         longC.set_min(1.0); 
    251         rimA     = Parameter(10.0, true); 
    252         rimB     = Parameter(10.0, true); 
    253         rimC     = Parameter(10.0, true); 
    254         sld_rimA     = Parameter(2.0e-6, true); 
    255         sld_rimB     = Parameter(4.0e-6, true); 
    256         sld_rimC    = Parameter(2.0e-6, true); 
    257         sld_pcore   = Parameter(1.0e-6); 
    258         sld_solv   = Parameter(6.0e-6); 
    259         background = Parameter(0.06); 
    260         parallel_theta  = Parameter(0.0, true); 
    261         parallel_phi    = Parameter(0.0, true); 
    262         parallel_psi    = Parameter(0.0, true); 
     243  scale      = Parameter(1.0); 
     244  shortA     = Parameter(35.0, true); 
     245  shortA.set_min(1.0); 
     246  midB     = Parameter(75.0, true); 
     247  midB.set_min(1.0); 
     248  longC    = Parameter(400.0, true); 
     249  longC.set_min(1.0); 
     250  rimA     = Parameter(10.0, true); 
     251  rimB     = Parameter(10.0, true); 
     252  rimC     = Parameter(10.0, true); 
     253  sld_rimA     = Parameter(2.0e-6, true); 
     254  sld_rimB     = Parameter(4.0e-6, true); 
     255  sld_rimC    = Parameter(2.0e-6, true); 
     256  sld_pcore   = Parameter(1.0e-6); 
     257  sld_solv   = Parameter(6.0e-6); 
     258  background = Parameter(0.06); 
     259  parallel_theta  = Parameter(0.0, true); 
     260  parallel_phi    = Parameter(0.0, true); 
     261  parallel_psi    = Parameter(0.0, true); 
    263262} 
    264263 
     
    270269 */ 
    271270double CSParallelepipedModel :: operator()(double q) { 
    272         double dp[13]; 
    273  
    274         // Fill parameter array for IGOR library 
    275         // Add the background after averaging 
    276         dp[0] = scale(); 
    277         dp[1] = shortA(); 
    278         dp[2] = midB(); 
    279         dp[3] = longC(); 
    280         dp[4] = rimA(); 
    281         dp[5] = rimB(); 
    282         dp[6] = rimC(); 
    283         dp[7] = sld_rimA(); 
    284         dp[8] = sld_rimB(); 
    285         dp[9] = sld_rimC(); 
    286         dp[10] = sld_pcore(); 
    287         dp[11] = sld_solv(); 
    288         dp[12] = 0.0; 
    289  
    290         // Get the dispersion points for the short_edgeA 
    291         vector<WeightPoint> weights_shortA; 
    292         shortA.get_weights(weights_shortA); 
    293  
    294         // Get the dispersion points for the longer_edgeB 
    295         vector<WeightPoint> weights_midB; 
    296         midB.get_weights(weights_midB); 
    297  
    298         // Get the dispersion points for the longuest_edgeC 
    299         vector<WeightPoint> weights_longC; 
    300         longC.get_weights(weights_longC); 
    301  
    302  
    303  
    304         // Perform the computation, with all weight points 
    305         double sum = 0.0; 
    306         double norm = 0.0; 
    307         double vol = 0.0; 
    308  
    309         // Loop over short_edgeA weight points 
    310         for(int i=0; i< (int)weights_shortA.size(); i++) { 
    311                 dp[1] = weights_shortA[i].value; 
    312  
    313                 // Loop over longer_edgeB weight points 
    314                 for(int j=0; j< (int)weights_midB.size(); j++) { 
    315                         dp[2] = weights_midB[j].value; 
    316  
    317                         // Loop over longuest_edgeC weight points 
    318                         for(int k=0; k< (int)weights_longC.size(); k++) { 
    319                                 dp[3] = weights_longC[k].value; 
    320                                 //Un-normalize  by volume 
    321                                 sum += weights_shortA[i].weight * weights_midB[j].weight 
    322                                         * weights_longC[k].weight * CSParallelepiped(dp, q) 
    323                                         * weights_shortA[i].value*weights_midB[j].value 
    324                                         * weights_longC[k].value; 
    325                                 //Find average volume 
    326                                 vol += weights_shortA[i].weight * weights_midB[j].weight 
    327                                         * weights_longC[k].weight 
    328                                         * weights_shortA[i].value * weights_midB[j].value 
    329                                         * weights_longC[k].value; 
    330  
    331                                 norm += weights_shortA[i].weight 
    332                                         * weights_midB[j].weight * weights_longC[k].weight; 
    333                         } 
    334                 } 
    335         } 
    336         if (vol != 0.0 && norm != 0.0) { 
    337                 //Re-normalize by avg volume 
    338                 sum = sum/(vol/norm);} 
    339  
    340         return sum/norm + background(); 
     271  double dp[13]; 
     272 
     273  // Fill parameter array for IGOR library 
     274  // Add the background after averaging 
     275  dp[0] = scale(); 
     276  dp[1] = shortA(); 
     277  dp[2] = midB(); 
     278  dp[3] = longC(); 
     279  dp[4] = rimA(); 
     280  dp[5] = rimB(); 
     281  dp[6] = rimC(); 
     282  dp[7] = sld_rimA(); 
     283  dp[8] = sld_rimB(); 
     284  dp[9] = sld_rimC(); 
     285  dp[10] = sld_pcore(); 
     286  dp[11] = sld_solv(); 
     287  dp[12] = 0.0; 
     288 
     289  // Get the dispersion points for the short_edgeA 
     290  vector<WeightPoint> weights_shortA; 
     291  shortA.get_weights(weights_shortA); 
     292 
     293  // Get the dispersion points for the longer_edgeB 
     294  vector<WeightPoint> weights_midB; 
     295  midB.get_weights(weights_midB); 
     296 
     297  // Get the dispersion points for the longuest_edgeC 
     298  vector<WeightPoint> weights_longC; 
     299  longC.get_weights(weights_longC); 
     300 
     301 
     302 
     303  // Perform the computation, with all weight points 
     304  double sum = 0.0; 
     305  double norm = 0.0; 
     306  double vol = 0.0; 
     307 
     308  // Loop over short_edgeA weight points 
     309  for(int i=0; i< (int)weights_shortA.size(); i++) { 
     310    dp[1] = weights_shortA[i].value; 
     311 
     312    // Loop over longer_edgeB weight points 
     313    for(int j=0; j< (int)weights_midB.size(); j++) { 
     314      dp[2] = weights_midB[j].value; 
     315 
     316      // Loop over longuest_edgeC weight points 
     317      for(int k=0; k< (int)weights_longC.size(); k++) { 
     318        dp[3] = weights_longC[k].value; 
     319        //Un-normalize  by volume 
     320        sum += weights_shortA[i].weight * weights_midB[j].weight 
     321            * weights_longC[k].weight * CSParallelepiped(dp, q) 
     322        * weights_shortA[i].value*weights_midB[j].value 
     323        * weights_longC[k].value; 
     324        //Find average volume 
     325        vol += weights_shortA[i].weight * weights_midB[j].weight 
     326            * weights_longC[k].weight 
     327            * weights_shortA[i].value * weights_midB[j].value 
     328            * weights_longC[k].value; 
     329 
     330        norm += weights_shortA[i].weight 
     331            * weights_midB[j].weight * weights_longC[k].weight; 
     332      } 
     333    } 
     334  } 
     335  if (vol != 0.0 && norm != 0.0) { 
     336    //Re-normalize by avg volume 
     337    sum = sum/(vol/norm);} 
     338 
     339  return sum/norm + background(); 
    341340} 
    342341/** 
     
    347346 */ 
    348347double CSParallelepipedModel :: operator()(double qx, double qy) { 
    349         CSParallelepipedParameters dp; 
    350         // Fill parameter array 
    351         dp.scale      = scale(); 
    352         dp.shortA   = shortA(); 
    353         dp.midB   = midB(); 
    354         dp.longC  = longC(); 
    355         dp.rimA   = rimA(); 
    356         dp.rimB   = rimB(); 
    357         dp.rimC  = rimC(); 
    358         dp.sld_rimA   = sld_rimA(); 
    359         dp.sld_rimB   = sld_rimB(); 
    360         dp.sld_rimC  = sld_rimC(); 
    361         dp.sld_pcore   = sld_pcore(); 
    362         dp.sld_solv   = sld_solv(); 
    363         dp.background = 0.0; 
    364         //dp.background = background(); 
    365         dp.parallel_theta  = parallel_theta(); 
    366         dp.parallel_phi    = parallel_phi(); 
    367         dp.parallel_psi    = parallel_psi(); 
    368  
    369  
    370  
    371         // Get the dispersion points for the short_edgeA 
    372         vector<WeightPoint> weights_shortA; 
    373         shortA.get_weights(weights_shortA); 
    374  
    375         // Get the dispersion points for the longer_edgeB 
    376         vector<WeightPoint> weights_midB; 
    377         midB.get_weights(weights_midB); 
    378  
    379         // Get the dispersion points for the longuest_edgeC 
    380         vector<WeightPoint> weights_longC; 
    381         longC.get_weights(weights_longC); 
    382  
    383         // Get angular averaging for theta 
    384         vector<WeightPoint> weights_parallel_theta; 
    385         parallel_theta.get_weights(weights_parallel_theta); 
    386  
    387         // Get angular averaging for phi 
    388         vector<WeightPoint> weights_parallel_phi; 
    389         parallel_phi.get_weights(weights_parallel_phi); 
    390  
    391         // Get angular averaging for psi 
    392         vector<WeightPoint> weights_parallel_psi; 
    393         parallel_psi.get_weights(weights_parallel_psi); 
    394  
    395         // Perform the computation, with all weight points 
    396         double sum = 0.0; 
    397         double norm = 0.0; 
    398         double norm_vol = 0.0; 
    399         double vol = 0.0; 
    400         double pi = 4.0*atan(1.0); 
    401  
    402         // Loop over radius weight points 
    403         for(int i=0; i< (int)weights_shortA.size(); i++) { 
    404                 dp.shortA = weights_shortA[i].value; 
    405  
    406                 // Loop over longer_edgeB weight points 
    407                 for(int j=0; j< (int)weights_midB.size(); j++) { 
    408                         dp.midB = weights_midB[j].value; 
    409  
    410                         // Average over longuest_edgeC distribution 
    411                         for(int k=0; k< (int)weights_longC.size(); k++) { 
    412                                 dp.longC = weights_longC[k].value; 
    413  
    414                                 // Average over theta distribution 
    415                                 for(int l=0; l< (int)weights_parallel_theta.size(); l++) { 
    416                                 dp.parallel_theta = weights_parallel_theta[l].value; 
    417  
    418                                         // Average over phi distribution 
    419                                         for(int m=0; m< (int)weights_parallel_phi.size(); m++) { 
    420                                                 dp.parallel_phi = weights_parallel_phi[m].value; 
    421  
    422                                                 // Average over phi distribution 
    423                                                 for(int n=0; n< (int)weights_parallel_psi.size(); n++) { 
    424                                                         dp.parallel_psi = weights_parallel_psi[n].value; 
    425                                                         //Un-normalize by volume 
    426                                                         double _ptvalue = weights_shortA[i].weight 
    427                                                                 * weights_midB[j].weight 
    428                                                                 * weights_longC[k].weight 
    429                                                                 * weights_parallel_theta[l].weight 
    430                                                                 * weights_parallel_phi[m].weight 
    431                                                                 * weights_parallel_psi[n].weight 
    432                                                                 * csparallelepiped_analytical_2DXY(&dp, qx, qy) 
    433                                                                 * weights_shortA[i].value*weights_midB[j].value 
    434                                                                 * weights_longC[k].value; 
    435  
    436                                                         if (weights_parallel_theta.size()>1) { 
    437                                                                 _ptvalue *= fabs(sin(weights_parallel_theta[l].value*pi/180.0)); 
    438                                                         } 
    439                                                         sum += _ptvalue; 
    440                                                         //Find average volume 
    441                                                         vol += weights_shortA[i].weight 
    442                                                                 * weights_midB[j].weight 
    443                                                                 * weights_longC[k].weight 
    444                                                                 * weights_shortA[i].value*weights_midB[j].value 
    445                                                                 * weights_longC[k].value; 
    446                                                         //Find norm for volume 
    447                                                         norm_vol += weights_shortA[i].weight 
    448                                                                 * weights_midB[j].weight 
    449                                                                 * weights_longC[k].weight; 
    450  
    451                                                         norm += weights_shortA[i].weight 
    452                                                                 * weights_midB[j].weight 
    453                                                                 * weights_longC[k].weight 
    454                                                                 * weights_parallel_theta[l].weight 
    455                                                                 * weights_parallel_phi[m].weight 
    456                                                                 * weights_parallel_psi[n].weight; 
    457                                                 } 
    458                                         } 
    459  
    460                                 } 
    461                         } 
    462                 } 
    463         } 
    464         // Averaging in theta needs an extra normalization 
    465         // factor to account for the sin(theta) term in the 
    466         // integration (see documentation). 
    467         if (weights_parallel_theta.size()>1) norm = norm / asin(1.0); 
    468  
    469         if (vol != 0.0 && norm_vol != 0.0) { 
    470                 //Re-normalize by avg volume 
    471                 sum = sum/(vol/norm_vol);} 
    472  
    473         return sum/norm + background(); 
     348  CSParallelepipedParameters dp; 
     349  // Fill parameter array 
     350  dp.scale      = scale(); 
     351  dp.shortA   = shortA(); 
     352  dp.midB   = midB(); 
     353  dp.longC  = longC(); 
     354  dp.rimA   = rimA(); 
     355  dp.rimB   = rimB(); 
     356  dp.rimC  = rimC(); 
     357  dp.sld_rimA   = sld_rimA(); 
     358  dp.sld_rimB   = sld_rimB(); 
     359  dp.sld_rimC  = sld_rimC(); 
     360  dp.sld_pcore   = sld_pcore(); 
     361  dp.sld_solv   = sld_solv(); 
     362  dp.background = 0.0; 
     363  //dp.background = background(); 
     364  dp.parallel_theta  = parallel_theta(); 
     365  dp.parallel_phi    = parallel_phi(); 
     366  dp.parallel_psi    = parallel_psi(); 
     367 
     368 
     369 
     370  // Get the dispersion points for the short_edgeA 
     371  vector<WeightPoint> weights_shortA; 
     372  shortA.get_weights(weights_shortA); 
     373 
     374  // Get the dispersion points for the longer_edgeB 
     375  vector<WeightPoint> weights_midB; 
     376  midB.get_weights(weights_midB); 
     377 
     378  // Get the dispersion points for the longuest_edgeC 
     379  vector<WeightPoint> weights_longC; 
     380  longC.get_weights(weights_longC); 
     381 
     382  // Get angular averaging for theta 
     383  vector<WeightPoint> weights_parallel_theta; 
     384  parallel_theta.get_weights(weights_parallel_theta); 
     385 
     386  // Get angular averaging for phi 
     387  vector<WeightPoint> weights_parallel_phi; 
     388  parallel_phi.get_weights(weights_parallel_phi); 
     389 
     390  // Get angular averaging for psi 
     391  vector<WeightPoint> weights_parallel_psi; 
     392  parallel_psi.get_weights(weights_parallel_psi); 
     393 
     394  // Perform the computation, with all weight points 
     395  double sum = 0.0; 
     396  double norm = 0.0; 
     397  double norm_vol = 0.0; 
     398  double vol = 0.0; 
     399  double pi = 4.0*atan(1.0); 
     400 
     401  // Loop over radius weight points 
     402  for(int i=0; i< (int)weights_shortA.size(); i++) { 
     403    dp.shortA = weights_shortA[i].value; 
     404 
     405    // Loop over longer_edgeB weight points 
     406    for(int j=0; j< (int)weights_midB.size(); j++) { 
     407      dp.midB = weights_midB[j].value; 
     408 
     409      // Average over longuest_edgeC distribution 
     410      for(int k=0; k< (int)weights_longC.size(); k++) { 
     411        dp.longC = weights_longC[k].value; 
     412 
     413        // Average over theta distribution 
     414        for(int l=0; l< (int)weights_parallel_theta.size(); l++) { 
     415          dp.parallel_theta = weights_parallel_theta[l].value; 
     416 
     417          // Average over phi distribution 
     418          for(int m=0; m< (int)weights_parallel_phi.size(); m++) { 
     419            dp.parallel_phi = weights_parallel_phi[m].value; 
     420 
     421            // Average over phi distribution 
     422            for(int n=0; n< (int)weights_parallel_psi.size(); n++) { 
     423              dp.parallel_psi = weights_parallel_psi[n].value; 
     424              //Un-normalize by volume 
     425              double _ptvalue = weights_shortA[i].weight 
     426                  * weights_midB[j].weight 
     427                  * weights_longC[k].weight 
     428                  * weights_parallel_theta[l].weight 
     429                  * weights_parallel_phi[m].weight 
     430                  * weights_parallel_psi[n].weight 
     431                  * csparallelepiped_analytical_2DXY(&dp, qx, qy) 
     432              * weights_shortA[i].value*weights_midB[j].value 
     433              * weights_longC[k].value; 
     434 
     435              if (weights_parallel_theta.size()>1) { 
     436                _ptvalue *= fabs(sin(weights_parallel_theta[l].value*pi/180.0)); 
     437              } 
     438              sum += _ptvalue; 
     439              //Find average volume 
     440              vol += weights_shortA[i].weight 
     441                  * weights_midB[j].weight 
     442                  * weights_longC[k].weight 
     443                  * weights_shortA[i].value*weights_midB[j].value 
     444                  * weights_longC[k].value; 
     445              //Find norm for volume 
     446              norm_vol += weights_shortA[i].weight 
     447                  * weights_midB[j].weight 
     448                  * weights_longC[k].weight; 
     449 
     450              norm += weights_shortA[i].weight 
     451                  * weights_midB[j].weight 
     452                  * weights_longC[k].weight 
     453                  * weights_parallel_theta[l].weight 
     454                  * weights_parallel_phi[m].weight 
     455                  * weights_parallel_psi[n].weight; 
     456            } 
     457          } 
     458 
     459        } 
     460      } 
     461    } 
     462  } 
     463  // Averaging in theta needs an extra normalization 
     464  // factor to account for the sin(theta) term in the 
     465  // integration (see documentation). 
     466  if (weights_parallel_theta.size()>1) norm = norm / asin(1.0); 
     467 
     468  if (vol != 0.0 && norm_vol != 0.0) { 
     469    //Re-normalize by avg volume 
     470    sum = sum/(vol/norm_vol);} 
     471 
     472  return sum/norm + background(); 
    474473} 
    475474 
     
    483482 */ 
    484483double CSParallelepipedModel :: evaluate_rphi(double q, double phi) { 
    485         double qx = q*cos(phi); 
    486         double qy = q*sin(phi); 
    487         return (*this).operator()(qx, qy); 
     484  double qx = q*cos(phi); 
     485  double qy = q*sin(phi); 
     486  return (*this).operator()(qx, qy); 
    488487} 
    489488/** 
     
    492491 */ 
    493492double CSParallelepipedModel :: calculate_ER() { 
    494         CSParallelepipedParameters dp; 
    495         dp.shortA   = shortA(); 
    496         dp.midB   = midB(); 
    497         dp.longC  = longC(); 
    498         dp.rimA   = rimA(); 
    499         dp.rimB   = rimB(); 
    500         dp.rimC  = rimC(); 
    501  
    502         double rad_out = 0.0; 
    503         double pi = 4.0*atan(1.0); 
    504         double suf_rad = sqrt((dp.shortA*dp.midB+2.0*dp.rimA*dp.midB+2.0*dp.rimA*dp.shortA)/pi); 
    505         double height =(dp.longC + 2.0*dp.rimC); 
    506         // Perform the computation, with all weight points 
    507         double sum = 0.0; 
    508         double norm = 0.0; 
    509  
    510         // Get the dispersion points for the short_edgeA 
    511         vector<WeightPoint> weights_shortA; 
    512         shortA.get_weights(weights_shortA); 
    513  
    514         // Get the dispersion points for the longer_edgeB 
    515         vector<WeightPoint> weights_midB; 
    516         midB.get_weights(weights_midB); 
    517  
    518         // Get angular averaging for the longuest_edgeC 
    519         vector<WeightPoint> weights_longC; 
    520         longC.get_weights(weights_longC); 
    521  
    522         // Loop over radius weight points 
    523         for(int i=0; i< (int)weights_shortA.size(); i++) { 
    524                 dp.shortA = weights_shortA[i].value; 
    525  
    526                 // Loop over longer_edgeB weight points 
    527                 for(int j=0; j< (int)weights_midB.size(); j++) { 
    528                         dp.midB = weights_midB[j].value; 
    529  
    530                         // Average over longuest_edgeC distribution 
    531                         for(int k=0; k< (int)weights_longC.size(); k++) { 
    532                                 dp.longC = weights_longC[k].value; 
    533                                 //Calculate surface averaged radius 
    534                                 //This is rough approximation. 
    535                                 suf_rad = sqrt((dp.shortA*dp.midB+2.0*dp.rimA*dp.midB+2.0*dp.rimA*dp.shortA)/pi); 
    536                                 height =(dp.longC + 2.0*dp.rimC); 
    537                                 //Note: output of "DiamCyl(dp.length,dp.radius)" is a DIAMETER. 
    538                                 sum +=weights_shortA[i].weight* weights_midB[j].weight 
    539                                         * weights_longC[k].weight*DiamCyl(height, suf_rad)/2.0; 
    540                                 norm += weights_shortA[i].weight* weights_midB[j].weight*weights_longC[k].weight; 
    541                         } 
    542                 } 
    543         } 
    544  
    545         if (norm != 0){ 
    546                 //return the averaged value 
    547                 rad_out =  sum/norm;} 
    548         else{ 
    549                 //return normal value 
    550                 //Note: output of "DiamCyl(length,radius)" is DIAMETER. 
    551                 rad_out = DiamCyl(dp.longC, suf_rad)/2.0;} 
    552         return rad_out; 
    553  
    554 } 
     493  CSParallelepipedParameters dp; 
     494  dp.shortA   = shortA(); 
     495  dp.midB   = midB(); 
     496  dp.longC  = longC(); 
     497  dp.rimA   = rimA(); 
     498  dp.rimB   = rimB(); 
     499  dp.rimC  = rimC(); 
     500 
     501  double rad_out = 0.0; 
     502  double pi = 4.0*atan(1.0); 
     503  double suf_rad = sqrt((dp.shortA*dp.midB+2.0*dp.rimA*dp.midB+2.0*dp.rimA*dp.shortA)/pi); 
     504  double height =(dp.longC + 2.0*dp.rimC); 
     505  // Perform the computation, with all weight points 
     506  double sum = 0.0; 
     507  double norm = 0.0; 
     508 
     509  // Get the dispersion points for the short_edgeA 
     510  vector<WeightPoint> weights_shortA; 
     511  shortA.get_weights(weights_shortA); 
     512 
     513  // Get the dispersion points for the longer_edgeB 
     514  vector<WeightPoint> weights_midB; 
     515  midB.get_weights(weights_midB); 
     516 
     517  // Get angular averaging for the longuest_edgeC 
     518  vector<WeightPoint> weights_longC; 
     519  longC.get_weights(weights_longC); 
     520 
     521  // Loop over radius weight points 
     522  for(int i=0; i< (int)weights_shortA.size(); i++) { 
     523    dp.shortA = weights_shortA[i].value; 
     524 
     525    // Loop over longer_edgeB weight points 
     526    for(int j=0; j< (int)weights_midB.size(); j++) { 
     527      dp.midB = weights_midB[j].value; 
     528 
     529      // Average over longuest_edgeC distribution 
     530      for(int k=0; k< (int)weights_longC.size(); k++) { 
     531        dp.longC = weights_longC[k].value; 
     532        //Calculate surface averaged radius 
     533        //This is rough approximation. 
     534        suf_rad = sqrt((dp.shortA*dp.midB+2.0*dp.rimA*dp.midB+2.0*dp.rimA*dp.shortA)/pi); 
     535        height =(dp.longC + 2.0*dp.rimC); 
     536        //Note: output of "DiamCyl(dp.length,dp.radius)" is a DIAMETER. 
     537        sum +=weights_shortA[i].weight* weights_midB[j].weight 
     538            * weights_longC[k].weight*DiamCyl(height, suf_rad)/2.0; 
     539        norm += weights_shortA[i].weight* weights_midB[j].weight*weights_longC[k].weight; 
     540      } 
     541    } 
     542  } 
     543 
     544  if (norm != 0){ 
     545    //return the averaged value 
     546    rad_out =  sum/norm;} 
     547  else{ 
     548    //return normal value 
     549    //Note: output of "DiamCyl(length,radius)" is DIAMETER. 
     550    rad_out = DiamCyl(dp.longC, suf_rad)/2.0;} 
     551  return rad_out; 
     552 
     553} 
  • sansmodels/src/c_models/models.hh

    rdf88829 rc637521  
    2828 
    2929 
    30 class OnionModel{ 
    31 public: 
    32         // Model parameters 
    33         Parameter n_shells; 
    34         Parameter scale; 
    35         Parameter rad_core0; 
    36         Parameter sld_core0; 
    37         Parameter sld_solv; 
    38         Parameter background; 
    39  
    40         Parameter sld_out_shell1; 
    41         Parameter sld_out_shell2; 
    42         Parameter sld_out_shell3; 
    43         Parameter sld_out_shell4; 
    44         Parameter sld_out_shell5; 
    45         Parameter sld_out_shell6; 
    46         Parameter sld_out_shell7; 
    47         Parameter sld_out_shell8; 
    48         Parameter sld_out_shell9; 
    49         Parameter sld_out_shell10; 
    50  
    51         Parameter sld_in_shell1; 
    52         Parameter sld_in_shell2; 
    53         Parameter sld_in_shell3; 
    54         Parameter sld_in_shell4; 
    55         Parameter sld_in_shell5; 
    56         Parameter sld_in_shell6; 
    57         Parameter sld_in_shell7; 
    58         Parameter sld_in_shell8; 
    59         Parameter sld_in_shell9; 
    60         Parameter sld_in_shell10; 
    61  
    62         Parameter A_shell1; 
    63         Parameter A_shell2; 
    64         Parameter A_shell3; 
    65         Parameter A_shell4; 
    66         Parameter A_shell5; 
    67         Parameter A_shell6; 
    68         Parameter A_shell7; 
    69         Parameter A_shell8; 
    70         Parameter A_shell9; 
    71         Parameter A_shell10; 
    72  
    73         Parameter thick_shell1; 
    74         Parameter thick_shell2; 
    75         Parameter thick_shell3; 
    76         Parameter thick_shell4; 
    77         Parameter thick_shell5; 
    78         Parameter thick_shell6; 
    79         Parameter thick_shell7; 
    80         Parameter thick_shell8; 
    81         Parameter thick_shell9; 
    82         Parameter thick_shell10; 
    83  
    84         Parameter func_shell1; 
    85         Parameter func_shell2; 
    86         Parameter func_shell3; 
    87         Parameter func_shell4; 
    88         Parameter func_shell5; 
    89         Parameter func_shell6; 
    90         Parameter func_shell7; 
    91         Parameter func_shell8; 
    92         Parameter func_shell9; 
    93         Parameter func_shell10; 
    94  
    95         // Constructor 
    96         OnionModel(); 
    97  
    98         // Operators to get I(Q) 
    99         double operator()(double q); 
    100         double operator()(double qx, double qy); 
    101         double calculate_ER(); 
    102         double evaluate_rphi(double q, double phi); 
    103 }; 
     30 
    10431 
    10532 
  • sansmodels/src/c_models/onion.cpp

    r67424cd rc637521  
    2121 
    2222#include <math.h> 
    23 #include "models.hh" 
    2423#include "parameters.hh" 
    2524#include <stdio.h> 
     25#include <stdlib.h> 
    2626using namespace std; 
    27  
    28 extern "C" { 
    29         #include "onion.h" 
     27#include "onion.h" 
     28 
     29// Convenience parameter structure 
     30typedef struct { 
     31  int n_shells; 
     32  double scale; 
     33  double rad_core0; 
     34  double sld_core0; 
     35  double sld_solv; 
     36  double background; 
     37  double sld_out_shell1; 
     38  double sld_out_shell2; 
     39  double sld_out_shell3; 
     40  double sld_out_shell4; 
     41  double sld_out_shell5; 
     42  double sld_out_shell6; 
     43  double sld_out_shell7; 
     44  double sld_out_shell8; 
     45  double sld_out_shell9; 
     46  double sld_out_shell10; 
     47  double sld_in_shell1; 
     48  double sld_in_shell2; 
     49  double sld_in_shell3; 
     50  double sld_in_shell4; 
     51  double sld_in_shell5; 
     52  double sld_in_shell6; 
     53  double sld_in_shell7; 
     54  double sld_in_shell8; 
     55  double sld_in_shell9; 
     56  double sld_in_shell10; 
     57 
     58  double A_shell1; 
     59  double A_shell2; 
     60  double A_shell3; 
     61  double A_shell4; 
     62  double A_shell5; 
     63  double A_shell6; 
     64  double A_shell7; 
     65  double A_shell8; 
     66  double A_shell9; 
     67  double A_shell10; 
     68 
     69  double thick_shell1; 
     70  double thick_shell2; 
     71  double thick_shell3; 
     72  double thick_shell4; 
     73  double thick_shell5; 
     74  double thick_shell6; 
     75  double thick_shell7; 
     76  double thick_shell8; 
     77  double thick_shell9; 
     78  double thick_shell10; 
     79 
     80  int func_shell1; 
     81  int func_shell2; 
     82  int func_shell3; 
     83  int func_shell4; 
     84  int func_shell5; 
     85  int func_shell6; 
     86  int func_shell7; 
     87  int func_shell8; 
     88  int func_shell9; 
     89  int func_shell10; 
     90} OnionParameters; 
     91 
     92// some details can be found in sld_cal.c 
     93static double so_kernel(double dp[], double q) { 
     94  int n = dp[0]; 
     95  double scale = dp[1]; 
     96  double rad_core0 = dp[2]; 
     97  double sld_core0 = dp[3]; 
     98  double sld_solv = dp[4]; 
     99  double background = dp[5]; 
     100  int i,j; 
     101  double bes,fun,alpha,f,vol,vol_pre,vol_sub,qr,r,contr,f2; 
     102  double sign; 
     103  double pi; 
     104  double r0 = 0.0; 
     105 
     106  double *sld_out; 
     107  double *slope; 
     108  double *sld_in; 
     109  double *thick; 
     110  double *A; 
     111  int *fun_type; 
     112 
     113  sld_out = (double*)malloc((n+2)*sizeof(double)); 
     114  slope = (double*)malloc((n+2)*sizeof(double)); 
     115  sld_in = (double*)malloc((n+2)*sizeof(double)); 
     116  thick = (double*)malloc((n+2)*sizeof(double)); 
     117  A = (double*)malloc((n+2)*sizeof(double)); 
     118  fun_type = (int*)malloc((n+2)*sizeof(int)); 
     119 
     120  for (i =1; i<=n; i++){ 
     121    sld_out[i] = dp[i+5]; 
     122    sld_in[i] = dp[i+15]; 
     123    A[i] = dp[i+25]; 
     124    thick[i] = dp[i+35]; 
     125    fun_type[i] = dp[i+45]; 
     126  } 
     127  sld_out[0] = sld_core0; 
     128  sld_out[n+1] = sld_solv; 
     129  sld_in[0] = sld_core0; 
     130  sld_in[n+1] = sld_solv; 
     131  thick[0] = rad_core0; 
     132  thick[n+1] = 1e+10; 
     133  A[0] = 0.0; 
     134  A[n+1] = 0.0; 
     135  fun_type[0] = 0; 
     136  fun_type[n+1] = 0; 
     137 
     138 
     139  pi = 4.0*atan(1.0); 
     140  f = 0.0; 
     141  r = 0.0; 
     142  vol = 0.0; 
     143  vol_pre = 0.0; 
     144  vol_sub = 0.0; 
     145 
     146  for (i =0; i<= n+1; i++){ 
     147    if (thick[i] == 0.0){ 
     148      continue; 
     149    } 
     150    if (fun_type[i]== 0 ){ 
     151      slope[i] = 0.0; 
     152      A[i] = 0.0; 
     153    } 
     154    vol_pre = vol; 
     155    switch(fun_type[i]){ 
     156    case 2 : 
     157      r0 = r; 
     158      if (A[i] == 0.0){ 
     159        slope[i] = 0.0; 
     160      } 
     161      else{ 
     162        slope[i] = (sld_out[i]-sld_in[i])/(exp(A[i])-1.0); 
     163      } 
     164      for (j=0; j<2; j++){ 
     165        if ( i == 0 && j == 0){ 
     166          continue; 
     167        } 
     168        if (i == n+1 && j == 1){ 
     169          continue; 
     170        } 
     171        if ( j == 1){ 
     172          sign = 1.0; 
     173          r += thick[i]; 
     174        } 
     175        else{ 
     176          sign = -1.0; 
     177        } 
     178        qr = q * r; 
     179        alpha = A[i] * r/thick[i]; 
     180        fun = 0.0; 
     181        if(qr == 0.0){ 
     182          fun = sign * 1.0; 
     183          bes = sign * 1.0; 
     184        } 
     185        else{ 
     186          if (fabs(A[i]) > 0.0 ){ 
     187            fun = 3.0 * ((alpha*alpha - qr * qr) * sin(qr) - 2.0 * alpha * qr * cos(qr))/ ((alpha * alpha + qr * qr) * (alpha * alpha + qr * qr) * qr); 
     188            fun = fun - 3.0 * (alpha * sin(qr) - qr * cos(qr)) / ((alpha * alpha + qr * qr) * qr); 
     189            fun = - sign *fun; 
     190            bes = sign * 3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr); 
     191          } 
     192          else { 
     193            fun = sign * 3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr); 
     194            bes = sign * 3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr); 
     195          } 
     196        } 
     197        contr = slope[i]*exp(A[i]*(r-r0)/thick[i]); 
     198 
     199        vol = 4.0 * pi / 3.0 * r * r * r; 
     200        //if (j == 1 && fabs(sld_in[i]-sld_solv) < 1e-04*fabs(sld_solv) && A[i]==0.0){ 
     201        //  vol_sub += (vol_pre - vol); 
     202        //} 
     203        f += vol * (contr * (fun) + (sld_in[i]-slope[i]) * bes); 
     204      } 
     205      break; 
     206    default : 
     207      if (fun_type[i]==0){ 
     208        slope[i] = 0.0; 
     209      } 
     210      else{ 
     211        slope[i]= (sld_out[i] -sld_in[i])/thick[i]; 
     212      } 
     213      contr = sld_in[i]-slope[i]*r; 
     214      for (j=0; j<2; j++){ 
     215        if ( i == 0 && j == 0){ 
     216          continue; 
     217        } 
     218        if (i == n+1 && j == 1){ 
     219          continue; 
     220        } 
     221        if ( j == 1){ 
     222          sign = 1.0; 
     223          r += thick[i]; 
     224        } 
     225        else{ 
     226          sign = -1.0; 
     227        } 
     228 
     229        qr = q * r; 
     230        fun = 0.0; 
     231        if(qr == 0.0){ 
     232          bes = sign * 1.0; 
     233        } 
     234        else{ 
     235          bes = sign *  3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr); 
     236          if (fabs(slope[i]) > 0.0 ){ 
     237            fun = sign * 3.0 * r * (2.0*qr*sin(qr)-((qr*qr)-2.0)*cos(qr))/(qr * qr * qr * qr); 
     238          } 
     239        } 
     240        vol = 4.0 * pi / 3.0 * r * r * r; 
     241        //if (j == 1 && fabs(sld_in[i]-sld_solv) < 1e-04*fabs(sld_solv) && fun_type[i]==0){ 
     242        //  vol_sub += (vol_pre - vol); 
     243        //} 
     244        f += vol * (bes * contr + fun * slope[i]); 
     245      } 
     246      break; 
     247    } 
     248 
     249  } 
     250  //vol += vol_sub; 
     251  f2 = f * f / vol * 1.0e8; 
     252  f2 *= scale; 
     253  f2 += background; 
     254 
     255  free(sld_out); 
     256  free(slope); 
     257  free(sld_in); 
     258  free(thick); 
     259  free(A); 
     260  free(fun_type); 
     261 
     262  return (f2); 
    30263} 
    31264 
     265 
    32266OnionModel :: OnionModel() { 
    33         n_shells = Parameter(1.0); 
    34         scale = Parameter(1.0); 
    35         rad_core0 = Parameter(200.0); 
    36         sld_core0 = Parameter(1e-06); 
    37         sld_solv = Parameter(6.4e-06); 
    38     background = Parameter(0.0); 
    39  
    40  
    41     sld_out_shell1 = Parameter(1.0e-06); 
    42     sld_out_shell2 = Parameter(1.0e-06); 
    43     sld_out_shell3 = Parameter(1.0e-06); 
    44     sld_out_shell4 = Parameter(1.0e-06); 
    45     sld_out_shell5 = Parameter(1.0e-06); 
    46     sld_out_shell6 = Parameter(1.0e-06); 
    47     sld_out_shell7 = Parameter(1.0e-06); 
    48     sld_out_shell8 = Parameter(1.0e-06); 
    49     sld_out_shell9 = Parameter(1.0e-06); 
    50     sld_out_shell10 = Parameter(1.0e-06); 
    51  
    52  
    53     sld_in_shell1 = Parameter(2.3e-06); 
    54     sld_in_shell2 = Parameter(2.6e-06); 
    55     sld_in_shell3 = Parameter(2.9e-06); 
    56     sld_in_shell4 = Parameter(3.2e-06); 
    57     sld_in_shell5 = Parameter(3.5e-06); 
    58     sld_in_shell6 = Parameter(3.8e-06); 
    59     sld_in_shell7 = Parameter(4.1e-06); 
    60     sld_in_shell8 = Parameter(4.4e-06); 
    61     sld_in_shell9 = Parameter(4.7e-06); 
    62     sld_in_shell10 = Parameter(5.0e-06); 
    63  
    64  
    65     A_shell1 = Parameter(1.0); 
    66     A_shell2 = Parameter(1.0); 
    67     A_shell3 = Parameter(1.0); 
    68     A_shell4 = Parameter(1.0); 
    69     A_shell5 = Parameter(1.0); 
    70     A_shell6 = Parameter(1.0); 
    71     A_shell7 = Parameter(1.0); 
    72     A_shell8 = Parameter(1.0); 
    73     A_shell9 = Parameter(1.0); 
    74     A_shell10 = Parameter(1.0); 
    75  
    76  
    77     thick_shell1 = Parameter(50.0); 
    78     thick_shell2 = Parameter(50.0); 
    79     thick_shell3 = Parameter(50.0); 
    80     thick_shell4 = Parameter(50.0); 
    81     thick_shell5 = Parameter(50.0); 
    82     thick_shell6 = Parameter(50.0); 
    83     thick_shell7 = Parameter(50.0); 
    84     thick_shell8 = Parameter(50.0); 
    85     thick_shell9 = Parameter(50.0); 
    86     thick_shell10 = Parameter(50.0); 
    87  
    88  
    89     func_shell1 = Parameter(2); 
    90     func_shell2 = Parameter(2); 
    91     func_shell3 = Parameter(2); 
    92     func_shell4 = Parameter(2); 
    93     func_shell5 = Parameter(2); 
    94     func_shell6 = Parameter(2); 
    95     func_shell7 = Parameter(2); 
    96     func_shell8 = Parameter(2); 
    97     func_shell9 = Parameter(2); 
    98     func_shell10 = Parameter(2); 
    99  
     267  n_shells = Parameter(1.0); 
     268  scale = Parameter(1.0); 
     269  rad_core0 = Parameter(200.0); 
     270  sld_core0 = Parameter(1e-06); 
     271  sld_solv = Parameter(6.4e-06); 
     272  background = Parameter(0.0); 
     273 
     274  sld_out_shell1 = Parameter(1.0e-06); 
     275  sld_out_shell2 = Parameter(1.0e-06); 
     276  sld_out_shell3 = Parameter(1.0e-06); 
     277  sld_out_shell4 = Parameter(1.0e-06); 
     278  sld_out_shell5 = Parameter(1.0e-06); 
     279  sld_out_shell6 = Parameter(1.0e-06); 
     280  sld_out_shell7 = Parameter(1.0e-06); 
     281  sld_out_shell8 = Parameter(1.0e-06); 
     282  sld_out_shell9 = Parameter(1.0e-06); 
     283  sld_out_shell10 = Parameter(1.0e-06); 
     284 
     285  sld_in_shell1 = Parameter(2.3e-06); 
     286  sld_in_shell2 = Parameter(2.6e-06); 
     287  sld_in_shell3 = Parameter(2.9e-06); 
     288  sld_in_shell4 = Parameter(3.2e-06); 
     289  sld_in_shell5 = Parameter(3.5e-06); 
     290  sld_in_shell6 = Parameter(3.8e-06); 
     291  sld_in_shell7 = Parameter(4.1e-06); 
     292  sld_in_shell8 = Parameter(4.4e-06); 
     293  sld_in_shell9 = Parameter(4.7e-06); 
     294  sld_in_shell10 = Parameter(5.0e-06); 
     295 
     296  A_shell1 = Parameter(1.0); 
     297  A_shell2 = Parameter(1.0); 
     298  A_shell3 = Parameter(1.0); 
     299  A_shell4 = Parameter(1.0); 
     300  A_shell5 = Parameter(1.0); 
     301  A_shell6 = Parameter(1.0); 
     302  A_shell7 = Parameter(1.0); 
     303  A_shell8 = Parameter(1.0); 
     304  A_shell9 = Parameter(1.0); 
     305  A_shell10 = Parameter(1.0); 
     306 
     307  thick_shell1 = Parameter(50.0); 
     308  thick_shell2 = Parameter(50.0); 
     309  thick_shell3 = Parameter(50.0); 
     310  thick_shell4 = Parameter(50.0); 
     311  thick_shell5 = Parameter(50.0); 
     312  thick_shell6 = Parameter(50.0); 
     313  thick_shell7 = Parameter(50.0); 
     314  thick_shell8 = Parameter(50.0); 
     315  thick_shell9 = Parameter(50.0); 
     316  thick_shell10 = Parameter(50.0); 
     317 
     318  func_shell1 = Parameter(2); 
     319  func_shell2 = Parameter(2); 
     320  func_shell3 = Parameter(2); 
     321  func_shell4 = Parameter(2); 
     322  func_shell5 = Parameter(2); 
     323  func_shell6 = Parameter(2); 
     324  func_shell7 = Parameter(2); 
     325  func_shell8 = Parameter(2); 
     326  func_shell9 = Parameter(2); 
     327  func_shell10 = Parameter(2); 
    100328} 
    101329 
     
    107335 */ 
    108336double OnionModel :: operator()(double q) { 
    109         double dp[56]; 
    110         // Fill parameter array for IGOR library 
    111         // Add the background after averaging 
    112         dp[0] = n_shells(); 
    113         dp[1] = scale(); 
    114         dp[2] = rad_core0(); 
    115         dp[3] = sld_core0(); 
    116         dp[4] = sld_solv(); 
    117         dp[5] = 0.0; 
    118  
    119         dp[6] = sld_out_shell1(); 
    120         dp[7] = sld_out_shell2(); 
    121         dp[8] = sld_out_shell3(); 
    122         dp[9] = sld_out_shell4(); 
    123         dp[10] = sld_out_shell5(); 
    124         dp[11] = sld_out_shell6(); 
    125         dp[12] = sld_out_shell7(); 
    126         dp[13] = sld_out_shell8(); 
    127         dp[14] = sld_out_shell9(); 
    128         dp[15] = sld_out_shell10(); 
    129  
    130         dp[16] = sld_in_shell1(); 
    131         dp[17] = sld_in_shell2(); 
    132         dp[18] = sld_in_shell3(); 
    133         dp[19] = sld_in_shell4(); 
    134         dp[20] = sld_in_shell5(); 
    135         dp[21] = sld_in_shell6(); 
    136         dp[22] = sld_in_shell7(); 
    137         dp[23] = sld_in_shell8(); 
    138         dp[24] = sld_in_shell9(); 
    139         dp[25] = sld_in_shell10(); 
    140  
    141         dp[26] = A_shell1(); 
    142         dp[27] = A_shell2(); 
    143         dp[28] = A_shell3(); 
    144         dp[29] = A_shell4(); 
    145         dp[30] = A_shell5(); 
    146         dp[31] = A_shell6(); 
    147         dp[32] = A_shell7(); 
    148         dp[33] = A_shell8(); 
    149         dp[34] = A_shell9(); 
    150         dp[35] = A_shell10(); 
    151  
    152         dp[36] = thick_shell1(); 
    153         dp[37] = thick_shell2(); 
    154         dp[38] = thick_shell3(); 
    155         dp[39] = thick_shell4(); 
    156         dp[40] = thick_shell5(); 
    157         dp[41] = thick_shell6(); 
    158         dp[42] = thick_shell7(); 
    159         dp[43] = thick_shell8(); 
    160         dp[44] = thick_shell9(); 
    161         dp[45] = thick_shell10(); 
    162  
    163         dp[46] = func_shell1(); 
    164         dp[47] = func_shell2(); 
    165         dp[48] = func_shell3(); 
    166         dp[49] = func_shell4(); 
    167         dp[50] = func_shell5(); 
    168         dp[51] = func_shell6(); 
    169         dp[52] = func_shell7(); 
    170         dp[53] = func_shell8(); 
    171         dp[54] = func_shell9(); 
    172         dp[55] = func_shell10(); 
    173  
    174  
    175         // Get the dispersion points for the radius 
    176         vector<WeightPoint> weights_rad; 
    177         rad_core0.get_weights(weights_rad); 
    178  
    179         // Get the dispersion points for the thick 1 
    180         vector<WeightPoint> weights_s1; 
    181         thick_shell1.get_weights(weights_s1); 
    182  
    183         // Get the dispersion points for the thick 2 
    184         vector<WeightPoint> weights_s2; 
    185         thick_shell2.get_weights(weights_s2); 
    186  
    187         // Get the dispersion points for the thick 3 
    188         vector<WeightPoint> weights_s3; 
    189         thick_shell3.get_weights(weights_s3); 
    190  
    191         // Get the dispersion points for the thick 4 
    192         vector<WeightPoint> weights_s4; 
    193         thick_shell4.get_weights(weights_s4); 
    194  
    195         // Get the dispersion points for the thick 5 
    196         vector<WeightPoint> weights_s5; 
    197         thick_shell5.get_weights(weights_s5); 
    198  
    199         // Get the dispersion points for the thick 6 
    200         vector<WeightPoint> weights_s6; 
    201         thick_shell6.get_weights(weights_s6); 
    202  
    203         // Get the dispersion points for the thick 7 
    204         vector<WeightPoint> weights_s7; 
    205         thick_shell7.get_weights(weights_s7); 
    206  
    207         // Get the dispersion points for the thick 8 
    208         vector<WeightPoint> weights_s8; 
    209         thick_shell8.get_weights(weights_s8); 
    210         // Get the dispersion points for the thick 9 
    211         vector<WeightPoint> weights_s9; 
    212         thick_shell9.get_weights(weights_s9); 
    213  
    214         // Get the dispersion points for the thick 10 
    215         vector<WeightPoint> weights_s10; 
    216         thick_shell10.get_weights(weights_s10); 
    217  
    218  
    219         // Perform the computation, with all weight points 
    220         double sum = 0.0; 
    221         double norm = 0.0; 
    222         double vol = 0.0; 
    223  
    224         // Loop over radius weight points 
    225         for(size_t i=0; i<weights_rad.size(); i++) { 
    226                 dp[2] = weights_rad[i].value; 
    227                 // Loop over radius weight points 
    228                 for(size_t j=0; j<weights_s1.size(); j++) { 
    229                         dp[36] = weights_s1[j].value; 
    230                         // Loop over radius weight points 
    231                         for(size_t k=0; k<weights_s2.size(); k++) { 
    232                                 dp[37] = weights_s2[k].value; 
    233                                 // Loop over radius weight points 
    234                                 for(size_t l=0; l<weights_s3.size(); l++) { 
    235                                         dp[38] = weights_s3[l].value; 
    236                                         // Loop over radius weight points 
    237                                         for(size_t m=0; m<weights_s4.size(); m++) { 
    238                                                 dp[39] = weights_s4[m].value; 
    239                                                 for(size_t n=0; n<weights_s5.size(); n++) { 
    240                                                         dp[40] = weights_s5[n].value; 
    241                                                         for(size_t o=0; o<weights_s6.size(); o++) { 
    242                                                                 dp[41] = weights_s6[o].value; 
    243                                                                 for(size_t p=0; p<weights_s7.size(); p++) { 
    244                                                                         dp[42] = weights_s7[p].value; 
    245                                                                         for(size_t t=0; t<weights_s8.size(); t++) { 
    246                                                                                 dp[43] = weights_s8[t].value; 
    247                                                                                 for(size_t r=0; r<weights_s9.size(); r++) { 
    248                                                                                         dp[44] = weights_s9[r].value; 
    249                                                                                         for(size_t s=0; s<weights_s10.size(); s++) { 
    250                                                                                                 dp[45] = weights_s10[s].value; 
    251                                                                                                 //Un-normalize Shells by volume 
    252                                                                                                 sum += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight 
    253                                                                                                                 *weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight 
    254                                                                                                                 *weights_s9[r].weight*weights_s10[s].weight 
    255                                                                                                                 * so_kernel(dp,q) * pow((weights_rad[i].value+weights_s1[j].value+weights_s2[k].value+weights_s3[l].value+weights_s4[m].value 
    256                                                                                                                                 +weights_s5[n].value+weights_s6[o].value+weights_s7[p].value+weights_s8[t].value 
    257                                                                                                                                 +weights_s9[r].value+weights_s10[s].value),3.0); 
    258                                                                                                 //Find average volume 
    259                                                                                                 vol += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight 
    260                                                                                                         *weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight 
    261                                                                                                         *weights_s9[r].weight*weights_s10[s].weight 
    262                                                                                                         * pow((weights_rad[i].value+weights_s1[j].value+weights_s2[k].value+weights_s3[l].value+weights_s4[m].value 
    263                                                                                                                         +weights_s5[n].value+weights_s6[o].value+weights_s7[p].value+weights_s8[t].value 
    264                                                                                                                         +weights_s9[r].value+weights_s10[s].value),3.0); 
    265                                                                                                 norm += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight 
    266                                                                                                         *weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight 
    267                                                                                                         *weights_s9[r].weight*weights_s10[s].weight; 
    268                                                                                         } 
    269                                                                                 } 
    270                                                                         } 
    271                                                                 } 
    272                                                         } 
    273                                                 } 
    274                                         } 
    275                                 } 
    276                         } 
    277                 } 
    278         } 
    279  
    280         if (vol != 0.0 && norm != 0.0) { 
    281                 //Re-normalize by avg volume 
    282                 sum = sum/(vol/norm);} 
    283  
    284         return sum/norm + background(); 
     337  double dp[56]; 
     338  // Fill parameter array for IGOR library 
     339  // Add the background after averaging 
     340  dp[0] = n_shells(); 
     341  dp[1] = scale(); 
     342  dp[2] = rad_core0(); 
     343  dp[3] = sld_core0(); 
     344  dp[4] = sld_solv(); 
     345  dp[5] = 0.0; 
     346 
     347  dp[6] = sld_out_shell1(); 
     348  dp[7] = sld_out_shell2(); 
     349  dp[8] = sld_out_shell3(); 
     350  dp[9] = sld_out_shell4(); 
     351  dp[10] = sld_out_shell5(); 
     352  dp[11] = sld_out_shell6(); 
     353  dp[12] = sld_out_shell7(); 
     354  dp[13] = sld_out_shell8(); 
     355  dp[14] = sld_out_shell9(); 
     356  dp[15] = sld_out_shell10(); 
     357 
     358  dp[16] = sld_in_shell1(); 
     359  dp[17] = sld_in_shell2(); 
     360  dp[18] = sld_in_shell3(); 
     361  dp[19] = sld_in_shell4(); 
     362  dp[20] = sld_in_shell5(); 
     363  dp[21] = sld_in_shell6(); 
     364  dp[22] = sld_in_shell7(); 
     365  dp[23] = sld_in_shell8(); 
     366  dp[24] = sld_in_shell9(); 
     367  dp[25] = sld_in_shell10(); 
     368 
     369  dp[26] = A_shell1(); 
     370  dp[27] = A_shell2(); 
     371  dp[28] = A_shell3(); 
     372  dp[29] = A_shell4(); 
     373  dp[30] = A_shell5(); 
     374  dp[31] = A_shell6(); 
     375  dp[32] = A_shell7(); 
     376  dp[33] = A_shell8(); 
     377  dp[34] = A_shell9(); 
     378  dp[35] = A_shell10(); 
     379 
     380  dp[36] = thick_shell1(); 
     381  dp[37] = thick_shell2(); 
     382  dp[38] = thick_shell3(); 
     383  dp[39] = thick_shell4(); 
     384  dp[40] = thick_shell5(); 
     385  dp[41] = thick_shell6(); 
     386  dp[42] = thick_shell7(); 
     387  dp[43] = thick_shell8(); 
     388  dp[44] = thick_shell9(); 
     389  dp[45] = thick_shell10(); 
     390 
     391  dp[46] = func_shell1(); 
     392  dp[47] = func_shell2(); 
     393  dp[48] = func_shell3(); 
     394  dp[49] = func_shell4(); 
     395  dp[50] = func_shell5(); 
     396  dp[51] = func_shell6(); 
     397  dp[52] = func_shell7(); 
     398  dp[53] = func_shell8(); 
     399  dp[54] = func_shell9(); 
     400  dp[55] = func_shell10(); 
     401 
     402 
     403  // Get the dispersion points for the radius 
     404  vector<WeightPoint> weights_rad; 
     405  rad_core0.get_weights(weights_rad); 
     406 
     407  // Get the dispersion points for the thick 1 
     408  vector<WeightPoint> weights_s1; 
     409  thick_shell1.get_weights(weights_s1); 
     410 
     411  // Get the dispersion points for the thick 2 
     412  vector<WeightPoint> weights_s2; 
     413  thick_shell2.get_weights(weights_s2); 
     414 
     415  // Get the dispersion points for the thick 3 
     416  vector<WeightPoint> weights_s3; 
     417  thick_shell3.get_weights(weights_s3); 
     418 
     419  // Get the dispersion points for the thick 4 
     420  vector<WeightPoint> weights_s4; 
     421  thick_shell4.get_weights(weights_s4); 
     422 
     423  // Get the dispersion points for the thick 5 
     424  vector<WeightPoint> weights_s5; 
     425  thick_shell5.get_weights(weights_s5); 
     426 
     427  // Get the dispersion points for the thick 6 
     428  vector<WeightPoint> weights_s6; 
     429  thick_shell6.get_weights(weights_s6); 
     430 
     431  // Get the dispersion points for the thick 7 
     432  vector<WeightPoint> weights_s7; 
     433  thick_shell7.get_weights(weights_s7); 
     434 
     435  // Get the dispersion points for the thick 8 
     436  vector<WeightPoint> weights_s8; 
     437  thick_shell8.get_weights(weights_s8); 
     438  // Get the dispersion points for the thick 9 
     439  vector<WeightPoint> weights_s9; 
     440  thick_shell9.get_weights(weights_s9); 
     441 
     442  // Get the dispersion points for the thick 10 
     443  vector<WeightPoint> weights_s10; 
     444  thick_shell10.get_weights(weights_s10); 
     445 
     446 
     447  // Perform the computation, with all weight points 
     448  double sum = 0.0; 
     449  double norm = 0.0; 
     450  double vol = 0.0; 
     451 
     452  // Loop over radius weight points 
     453  for(size_t i=0; i<weights_rad.size(); i++) { 
     454    dp[2] = weights_rad[i].value; 
     455    // Loop over radius weight points 
     456    for(size_t j=0; j<weights_s1.size(); j++) { 
     457      dp[36] = weights_s1[j].value; 
     458      // Loop over radius weight points 
     459      for(size_t k=0; k<weights_s2.size(); k++) { 
     460        dp[37] = weights_s2[k].value; 
     461        // Loop over radius weight points 
     462        for(size_t l=0; l<weights_s3.size(); l++) { 
     463          dp[38] = weights_s3[l].value; 
     464          // Loop over radius weight points 
     465          for(size_t m=0; m<weights_s4.size(); m++) { 
     466            dp[39] = weights_s4[m].value; 
     467            for(size_t n=0; n<weights_s5.size(); n++) { 
     468              dp[40] = weights_s5[n].value; 
     469              for(size_t o=0; o<weights_s6.size(); o++) { 
     470                dp[41] = weights_s6[o].value; 
     471                for(size_t p=0; p<weights_s7.size(); p++) { 
     472                  dp[42] = weights_s7[p].value; 
     473                  for(size_t t=0; t<weights_s8.size(); t++) { 
     474                    dp[43] = weights_s8[t].value; 
     475                    for(size_t r=0; r<weights_s9.size(); r++) { 
     476                      dp[44] = weights_s9[r].value; 
     477                      for(size_t s=0; s<weights_s10.size(); s++) { 
     478                        dp[45] = weights_s10[s].value; 
     479                        //Un-normalize Shells by volume 
     480                        sum += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight 
     481                            *weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight 
     482                            *weights_s9[r].weight*weights_s10[s].weight 
     483                            * so_kernel(dp,q) * pow((weights_rad[i].value+weights_s1[j].value+weights_s2[k].value+weights_s3[l].value+weights_s4[m].value 
     484                                +weights_s5[n].value+weights_s6[o].value+weights_s7[p].value+weights_s8[t].value 
     485                                +weights_s9[r].value+weights_s10[s].value),3.0); 
     486                        //Find average volume 
     487                        vol += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight 
     488                            *weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight 
     489                            *weights_s9[r].weight*weights_s10[s].weight 
     490                            * pow((weights_rad[i].value+weights_s1[j].value+weights_s2[k].value+weights_s3[l].value+weights_s4[m].value 
     491                                +weights_s5[n].value+weights_s6[o].value+weights_s7[p].value+weights_s8[t].value 
     492                                +weights_s9[r].value+weights_s10[s].value),3.0); 
     493                        norm += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight 
     494                            *weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight 
     495                            *weights_s9[r].weight*weights_s10[s].weight; 
     496                      } 
     497                    } 
     498                  } 
     499                } 
     500              } 
     501            } 
     502          } 
     503        } 
     504      } 
     505    } 
     506  } 
     507 
     508  if (vol != 0.0 && norm != 0.0) { 
     509    //Re-normalize by avg volume 
     510    sum = sum/(vol/norm);} 
     511 
     512  return sum/norm + background(); 
    285513} 
    286514 
     
    292520 */ 
    293521double OnionModel :: operator()(double qx, double qy) { 
    294         double q = sqrt(qx*qx + qy*qy); 
    295         return (*this).operator()(q); 
     522  double q = sqrt(qx*qx + qy*qy); 
     523  return (*this).operator()(q); 
    296524} 
    297525 
     
    304532 */ 
    305533double OnionModel :: evaluate_rphi(double q, double phi) { 
    306         return (*this).operator()(q); 
     534  return (*this).operator()(q); 
    307535} 
    308536 
     
    312540 */ 
    313541double OnionModel :: calculate_ER() { 
    314         OnionParameters dp; 
    315         dp.rad_core0 = rad_core0(); 
    316         dp.thick_shell1 = thick_shell1(); 
    317         dp.thick_shell2 = thick_shell2(); 
    318         dp.thick_shell3 = thick_shell3(); 
    319         dp.thick_shell4 = thick_shell4(); 
    320         dp.thick_shell5 = thick_shell5(); 
    321         dp.thick_shell6 = thick_shell6(); 
    322         dp.thick_shell7 = thick_shell7(); 
    323         dp.thick_shell8 = thick_shell8(); 
    324         dp.thick_shell9 = thick_shell9(); 
    325         dp.thick_shell10 = thick_shell10(); 
    326  
    327  
    328         double rad_out = 0.0; 
    329         // Perform the computation, with all weight points 
    330         double sum = 0.0; 
    331         double norm = 0.0; 
    332  
    333         // Get the dispersion points for the radius 
    334         vector<WeightPoint> weights_rad; 
    335         rad_core0.get_weights(weights_rad); 
    336  
    337         // Get the dispersion points for the thick 1 
    338         vector<WeightPoint> weights_s1; 
    339         thick_shell1.get_weights(weights_s1); 
    340  
    341         // Get the dispersion points for the thick 2 
    342         vector<WeightPoint> weights_s2; 
    343         thick_shell2.get_weights(weights_s2); 
    344  
    345         // Get the dispersion points for the thick 3 
    346         vector<WeightPoint> weights_s3; 
    347         thick_shell3.get_weights(weights_s3); 
    348  
    349         // Get the dispersion points for the thick 4 
    350         vector<WeightPoint> weights_s4; 
    351         thick_shell4.get_weights(weights_s4); 
    352         // Get the dispersion points for the thick 5 
    353         vector<WeightPoint> weights_s5; 
    354         thick_shell5.get_weights(weights_s5); 
    355  
    356         // Get the dispersion points for the thick 6 
    357         vector<WeightPoint> weights_s6; 
    358         thick_shell6.get_weights(weights_s6); 
    359  
    360         // Get the dispersion points for the thick 7 
    361         vector<WeightPoint> weights_s7; 
    362         thick_shell7.get_weights(weights_s7); 
    363  
    364         // Get the dispersion points for the thick 8 
    365         vector<WeightPoint> weights_s8; 
    366         thick_shell8.get_weights(weights_s8); 
    367         // Get the dispersion points for the thick 9 
    368         vector<WeightPoint> weights_s9; 
    369         thick_shell9.get_weights(weights_s9); 
    370  
    371         // Get the dispersion points for the thick 10 
    372         vector<WeightPoint> weights_s10; 
    373         thick_shell10.get_weights(weights_s10); 
    374  
    375  
    376         // Loop over radius weight points 
    377         for(size_t i=0; i<weights_rad.size(); i++) { 
    378                 dp.rad_core0 = weights_rad[i].value; 
    379                 // Loop over radius weight points 
    380                 for(size_t j=0; j<weights_s1.size(); j++) { 
    381                         dp.thick_shell1 = weights_s1[j].value; 
    382                         // Loop over radius weight points 
    383                         for(size_t k=0; k<weights_s2.size(); k++) { 
    384                                 dp.thick_shell2 = weights_s2[k].value; 
    385                                 // Loop over radius weight points 
    386                                 for(size_t l=0; l<weights_s3.size(); l++) { 
    387                                         dp.thick_shell3 = weights_s3[l].value; 
    388                                         // Loop over radius weight points 
    389                                         for(size_t m=0; m<weights_s4.size(); m++) { 
    390                                                 dp.thick_shell4 = weights_s4[m].value; 
    391                                                 // Loop over radius weight points 
    392                                                 for(size_t n=0; j<weights_s5.size(); n++) { 
    393                                                         dp.thick_shell5 = weights_s5[n].value; 
    394                                                         // Loop over radius weight points 
    395                                                         for(size_t o=0; k<weights_s6.size(); o++) { 
    396                                                                 dp.thick_shell6 = weights_s6[o].value; 
    397                                                                 // Loop over radius weight points 
    398                                                                 for(size_t p=0; l<weights_s7.size(); p++) { 
    399                                                                         dp.thick_shell7 = weights_s7[p].value; 
    400                                                                         // Loop over radius weight points 
    401                                                                         for(size_t t=0; m<weights_s8.size(); t++) { 
    402                                                                                 dp.thick_shell8 = weights_s8[t].value; 
    403                                                                                 // Loop over radius weight points 
    404                                                                                 for(size_t r=0; l<weights_s9.size(); r++) { 
    405                                                                                         dp.thick_shell8 = weights_s9[r].value; 
    406                                                                                         // Loop over radius weight points 
    407                                                                                         for(size_t s=0; m<weights_s10.size(); s++) { 
    408                                                                                                 dp.thick_shell10 = weights_s10[s].value; 
    409                                                                                                 //Un-normalize FourShell by volume 
    410                                                                                                 sum += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight 
    411                                                                                                         *weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight 
    412                                                                                                         *weights_s9[r].weight*weights_s10[s].weight 
    413                                                                                                         * (dp.rad_core0+dp.thick_shell1+dp.thick_shell2+dp.thick_shell3+dp.thick_shell4+dp.thick_shell5 
    414                                                                                                                         +dp.thick_shell6+dp.thick_shell7+dp.thick_shell8+dp.thick_shell9+dp.thick_shell10); 
    415                                                                                                 norm += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight 
    416                                                                                                         *weights_s4[m].weight*weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight 
    417                                                                                                         *weights_s8[t].weight*weights_s9[r].weight*weights_s10[s].weight; 
    418                                                                                         } 
    419                                                                                 } 
    420                                                                         } 
    421                                                                 } 
    422                                                         } 
    423                                                 } 
    424                                         } 
    425                                 } 
    426                         } 
    427                 } 
    428         } 
    429  
    430         if (norm != 0){ 
    431                 //return the averaged value 
    432                 rad_out =  sum/norm;} 
    433         else{ 
    434                 //return normal value 
    435                 rad_out = dp.rad_core0+dp.thick_shell1+dp.thick_shell2+dp.thick_shell3+dp.thick_shell4 
    436                                         +dp.thick_shell5+dp.thick_shell6+dp.thick_shell7+dp.thick_shell8+dp.thick_shell9+dp.thick_shell10;} 
    437         return rad_out; 
     542  OnionParameters dp; 
     543  dp.rad_core0 = rad_core0(); 
     544  dp.thick_shell1 = thick_shell1(); 
     545  dp.thick_shell2 = thick_shell2(); 
     546  dp.thick_shell3 = thick_shell3(); 
     547  dp.thick_shell4 = thick_shell4(); 
     548  dp.thick_shell5 = thick_shell5(); 
     549  dp.thick_shell6 = thick_shell6(); 
     550  dp.thick_shell7 = thick_shell7(); 
     551  dp.thick_shell8 = thick_shell8(); 
     552  dp.thick_shell9 = thick_shell9(); 
     553  dp.thick_shell10 = thick_shell10(); 
     554 
     555  double rad_out = 0.0; 
     556  // Perform the computation, with all weight points 
     557  double sum = 0.0; 
     558  double norm = 0.0; 
     559 
     560  // Get the dispersion points for the radius 
     561  vector<WeightPoint> weights_rad; 
     562  rad_core0.get_weights(weights_rad); 
     563 
     564  // Get the dispersion points for the thick 1 
     565  vector<WeightPoint> weights_s1; 
     566  thick_shell1.get_weights(weights_s1); 
     567 
     568  // Get the dispersion points for the thick 2 
     569  vector<WeightPoint> weights_s2; 
     570  thick_shell2.get_weights(weights_s2); 
     571 
     572  // Get the dispersion points for the thick 3 
     573  vector<WeightPoint> weights_s3; 
     574  thick_shell3.get_weights(weights_s3); 
     575 
     576  // Get the dispersion points for the thick 4 
     577  vector<WeightPoint> weights_s4; 
     578  thick_shell4.get_weights(weights_s4); 
     579  // Get the dispersion points for the thick 5 
     580  vector<WeightPoint> weights_s5; 
     581  thick_shell5.get_weights(weights_s5); 
     582 
     583  // Get the dispersion points for the thick 6 
     584  vector<WeightPoint> weights_s6; 
     585  thick_shell6.get_weights(weights_s6); 
     586 
     587  // Get the dispersion points for the thick 7 
     588  vector<WeightPoint> weights_s7; 
     589  thick_shell7.get_weights(weights_s7); 
     590 
     591  // Get the dispersion points for the thick 8 
     592  vector<WeightPoint> weights_s8; 
     593  thick_shell8.get_weights(weights_s8); 
     594  // Get the dispersion points for the thick 9 
     595  vector<WeightPoint> weights_s9; 
     596  thick_shell9.get_weights(weights_s9); 
     597 
     598  // Get the dispersion points for the thick 10 
     599  vector<WeightPoint> weights_s10; 
     600  thick_shell10.get_weights(weights_s10); 
     601 
     602 
     603  // Loop over radius weight points 
     604  for(size_t i=0; i<weights_rad.size(); i++) { 
     605    dp.rad_core0 = weights_rad[i].value; 
     606    // Loop over radius weight points 
     607    for(size_t j=0; j<weights_s1.size(); j++) { 
     608      dp.thick_shell1 = weights_s1[j].value; 
     609      // Loop over radius weight points 
     610      for(size_t k=0; k<weights_s2.size(); k++) { 
     611        dp.thick_shell2 = weights_s2[k].value; 
     612        // Loop over radius weight points 
     613        for(size_t l=0; l<weights_s3.size(); l++) { 
     614          dp.thick_shell3 = weights_s3[l].value; 
     615          // Loop over radius weight points 
     616          for(size_t m=0; m<weights_s4.size(); m++) { 
     617            dp.thick_shell4 = weights_s4[m].value; 
     618            // Loop over radius weight points 
     619            for(size_t n=0; j<weights_s5.size(); n++) { 
     620              dp.thick_shell5 = weights_s5[n].value; 
     621              // Loop over radius weight points 
     622              for(size_t o=0; k<weights_s6.size(); o++) { 
     623                dp.thick_shell6 = weights_s6[o].value; 
     624                // Loop over radius weight points 
     625                for(size_t p=0; l<weights_s7.size(); p++) { 
     626                  dp.thick_shell7 = weights_s7[p].value; 
     627                  // Loop over radius weight points 
     628                  for(size_t t=0; m<weights_s8.size(); t++) { 
     629                    dp.thick_shell8 = weights_s8[t].value; 
     630                    // Loop over radius weight points 
     631                    for(size_t r=0; l<weights_s9.size(); r++) { 
     632                      dp.thick_shell8 = weights_s9[r].value; 
     633                      // Loop over radius weight points 
     634                      for(size_t s=0; m<weights_s10.size(); s++) { 
     635                        dp.thick_shell10 = weights_s10[s].value; 
     636                        //Un-normalize FourShell by volume 
     637                        sum += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight 
     638                            *weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight 
     639                            *weights_s9[r].weight*weights_s10[s].weight 
     640                            * (dp.rad_core0+dp.thick_shell1+dp.thick_shell2+dp.thick_shell3+dp.thick_shell4+dp.thick_shell5 
     641                                +dp.thick_shell6+dp.thick_shell7+dp.thick_shell8+dp.thick_shell9+dp.thick_shell10); 
     642                        norm += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight 
     643                            *weights_s4[m].weight*weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight 
     644                            *weights_s8[t].weight*weights_s9[r].weight*weights_s10[s].weight; 
     645                      } 
     646                    } 
     647                  } 
     648                } 
     649              } 
     650            } 
     651          } 
     652        } 
     653      } 
     654    } 
     655  } 
     656 
     657  if (norm != 0){ 
     658    //return the averaged value 
     659    rad_out =  sum/norm;} 
     660  else{ 
     661    //return normal value 
     662    rad_out = dp.rad_core0+dp.thick_shell1+dp.thick_shell2+dp.thick_shell3+dp.thick_shell4 
     663        +dp.thick_shell5+dp.thick_shell6+dp.thick_shell7+dp.thick_shell8+dp.thick_shell9+dp.thick_shell10;} 
     664  return rad_out; 
    438665} 
  • sansmodels/src/python_wrapper/COnionModel.cpp

    r67424cd rc637521  
    1818 * 
    1919 * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY 
    20  *          DO NOT MODIFY THIS FILE, MODIFY onion.h 
     20 *          DO NOT MODIFY THIS FILE, MODIFY ../c_extensions/onion.h 
    2121 *          AND RE-RUN THE GENERATOR SCRIPT 
    2222 * 
     
    3333#include <math.h> 
    3434#include <time.h> 
     35 
     36} 
     37 
    3538#include "onion.h" 
    36 } 
    37  
    38 #include "models.hh" 
    3939#include "dispersion_visitor.hh" 
    4040 
Note: See TracChangeset for help on using the changeset viewer.