Changes in / [da33725:7050455] in sasmodels
- Files:
-
- 1 added
- 88 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/guide/index.rst
rda5536f rbc69321 12 12 pd/polydispersity.rst 13 13 resolution.rst 14 plugin.rst 15 fitting_sq.rst 14 16 magnetism/magnetism.rst 15 17 orientation/orientation.rst 16 18 sesans/sans_to_sesans.rst 17 19 sesans/sesans_fitting.rst 18 plugin.rst19 20 scripting.rst 20 21 refs.rst -
doc/guide/plugin.rst
rc94ab04 re15a822 303 303 **Note: The order of the parameters in the definition will be the order of the 304 304 parameters in the user interface and the order of the parameters in Fq(), Iq(), 305 Iqac(), Iqabc(), form_volume() and shell_volume().305 Iqac(), Iqabc(), radius_effective(), form_volume() and shell_volume(). 306 306 And** *scale* **and** *background* **parameters are implicit to all models, 307 307 so they do not need to be included in the parameter table.** … … 387 387 can take arbitrary values, even for integer parameters, so your model should 388 388 round the incoming parameter value to the nearest integer inside your model 389 you should round to the nearest integer. In C code, you can do this using:: 389 you should round to the nearest integer. In C code, you can do this using: 390 391 .. code-block:: c 390 392 391 393 static double … … 454 456 ............. 455 457 458 .. note:: 459 460 Pure python models do not yet support direct computation of $<F(Q)^2>$ or 461 $<F(Q)>^2$. Neither do they support orientational distributions or magnetism 462 (use C models if these are required). 463 456 464 For pure python models, define the *Iq* function:: 457 465 … … 499 507 Models should define *form_volume(par1, par2, ...)* where the parameter 500 508 list includes the *volume* parameters in order. This is used for a weighted 501 volume normalization so that scattering is on an absolute scale. If 502 *form_volume* is not defined, then the default *form_volume = 1.0* will be 503 used. 509 volume normalization so that scattering is on an absolute scale. For 510 solid shapes, the *I(q)* function should use *form_volume* squared 511 as its scale factor. If *form_volume* is not defined, then the default 512 *form_volume = 1.0* will be used. 504 513 505 514 Hollow shapes, where the volume fraction of particle corresponds to the 506 515 material in the shell rather than the volume enclosed by the shape, must 507 516 also define a *shell_volume(par1, par2, ...)* function. The parameters 508 are the same as for *form_volume*. The *I(q)* calculation should use 509 *shell_volume* squared as its scale factor for the volume normalization. 510 The structure factor calculation needs *form_volume* in order to properly 511 scale the volume fraction parameter, so both functions are required for 512 hollow shapes. 513 514 **Note: Pure python models do not yet support direct computation of the** 515 **average of $F(q)$ and $F^2(q)$. Neither do they support orientational** 516 **distributions or magnetism (use C models if these are required).** 517 are the same as for *form_volume*. Here the *I(q)* function should use 518 *shell_volume* squared instead of *form_volume* squared so that the scale 519 parameter corresponds to the volume fraction of material in the sample. 520 The structure factor calculation needs the volume fraction of the filled 521 shapes for its calculation, so the volume fraction parameter in the model 522 is automatically scaled by *form_volume/shell_volume* prior to calling the 523 structure factor. 517 524 518 525 Embedded C Models … … 525 532 """ 526 533 527 This expands into the equivalent C code:: 534 This expands into the equivalent C code: 535 536 .. code-block:: c 528 537 529 538 double Iq(double q, double par1, double par2, ...); … … 536 545 includes only the volume parameters. 537 546 538 * form_volume* defines the volume of the shell for hollow shapes. As in547 *shell_volume* defines the volume of the shell for hollow shapes. As in 539 548 python models, it includes only the volume parameters. 540 549 … … 568 577 Rather than returning NAN from Iq, you must define the *INVALID(v)*. The 569 578 *v* parameter lets you access all the parameters in the model using 570 *v.par1*, *v.par2*, etc. For example:: 579 *v.par1*, *v.par2*, etc. For example: 580 581 .. code-block:: c 571 582 572 583 #define INVALID(v) (v.bell_radius < v.radius) … … 583 594 584 595 Instead of defining the *Iq* function, models can define *Fq* as 585 something like:: 596 something like: 597 598 .. code-block:: c 586 599 587 600 double Fq(double q, double *F1, double *F2, double par1, double par2, ...); … … 615 628 laboratory frame and beam travelling along $-z$. 616 629 617 The oriented C model (oriented pure Python models are not supported) 630 The oriented C model (oriented pure Python models are not supported) 618 631 is called using *Iqabc(qa, qb, qc, par1, par2, ...)* where 619 632 *par1*, etc. are the parameters to the model. If the shape is rotationally … … 644 657 645 658 Using the $z, w$ values for Gauss-Legendre integration in "lib/gauss76.c", the 646 numerical integration is then:: 659 numerical integration is then: 660 661 .. code-block:: c 647 662 648 663 double outer_sum = 0.0; … … 987 1002 memory, and wrong answers computed. The conclusion from a very long and 988 1003 strange debugging session was that any arrays that you declare in your 989 model should be a multiple of four. For example:: 1004 model should be a multiple of four. For example: 1005 1006 .. code-block:: c 990 1007 991 1008 double Iq(q, p1, p2, ...) … … 1019 1036 structure factor is the *hardsphere* interaction, which 1020 1037 uses the effective radius of the form factor as an input to the structure 1021 factor model. The effective radius is the average radius of the 1022 form averaged over all the polydispersity values. 1023 1024 :: 1025 1026 def ER(radius, thickness): 1027 """Effective radius of a core-shell sphere.""" 1028 return radius + thickness 1029 1030 Now consider the *core_shell_sphere*, which has a simple effective radius 1031 equal to the radius of the core plus the thickness of the shell, as 1032 shown above. Given polydispersity over *(r1, r2, ..., rm)* in radius and 1033 *(t1, t2, ..., tn)* in thickness, *ER* is called with a mesh 1034 grid covering all possible combinations of radius and thickness. 1035 That is, *radius* is *(r1, r2, ..., rm, r1, r2, ..., rm, ...)* 1036 and *thickness* is *(t1, t1, ... t1, t2, t2, ..., t2, ...)*. 1037 The *ER* function returns one effective radius for each combination. 1038 The effective radius calculator weights each of these according to 1039 the polydispersity distributions and calls the structure factor 1040 with the average *ER*. 1041 1042 :: 1043 1044 def VR(radius, thickness): 1045 """Sphere and shell volumes for a core-shell sphere.""" 1046 whole = 4.0/3.0 * pi * (radius + thickness)**3 1047 core = 4.0/3.0 * pi * radius**3 1048 return whole, whole - core 1049 1050 Core-shell type models have an additional volume ratio which scales 1051 the structure factor. The *VR* function returns the volume of 1052 the whole sphere and the volume of the shell. Like *ER*, there is 1053 one return value for each point in the mesh grid. 1054 1055 *NOTE: we may be removing or modifying this feature soon. As of the 1056 time of writing, core-shell sphere returns (1., 1.) for VR, giving a volume 1057 ratio of 1.0.* 1038 factor model. The effective radius is the weighted average over all 1039 values of the shape in polydisperse systems. 1040 1041 There can be many notions of effective radius, depending on the shape. For 1042 a sphere it is clearly just the radius, but for an ellipsoid of revolution 1043 we provide average curvature, equivalent sphere radius, minimum radius and 1044 maximum radius. These options are listed as *radius_effective_modes* in 1045 the python model defintion, and must be computed by the *radius_effective* 1046 function which takes the *radius_effective_mode* parameter as an integer, 1047 along with the various model parameters. Unlike normal C/Python arrays, 1048 the first mode is 1, the second is 2, etc. Mode 0 indicates that the 1049 effective radius from the shape is to be ignored in favour of the the 1050 effective radius parameter in the structure factor model. 1051 1052 1053 Consider the core-shell sphere, which defines the following effective radius 1054 modes in the python model:: 1055 1056 radius_effective_modes = [ 1057 "outer radius", 1058 "core radius", 1059 ] 1060 1061 and the following function in the C-file for the model: 1062 1063 .. code-block:: c 1064 1065 static double 1066 radius_effective(int mode, double radius, double thickness) 1067 { 1068 switch (mode) { 1069 case 0: return radius + thickness; 1070 case 1: return radius; 1071 default: return 0.; 1072 } 1073 } 1074 1075 static double 1076 form_volume(double radius, double thickness) 1077 { 1078 return M_4PI_3 * cube(radius + thickness); 1079 } 1080 1081 Given polydispersity over *(r1, r2, ..., rm)* in radius and *(t1, t2, ..., tn)* 1082 in thickness, *radius_effective* is called over a mesh grid covering all 1083 possible combinations of radius and thickness, with a single *(ri, tj)* pair 1084 in each call. The weights each of these results according to the 1085 polydispersity distributions and calls the structure factor with the average 1086 effective radius. Similarly, for *form_volume*. 1087 1088 Hollow models have an additional volume ratio which is needed to scale the 1089 structure factor. The structure factor uses the volume fraction of the filled 1090 particles as part of its density estimate, but the scale factor for the 1091 scattering intensity (as non-solvent volume fraction / volume) is determined 1092 by the shell volume only. Therefore the *shell_volume* function is 1093 needed to compute the form:shell volume ratio, which then scales the 1094 *volfraction* parameter prior to calling the structure factor calculator. 1095 In the case of a hollow sphere, this would be: 1096 1097 .. code-block:: c 1098 1099 static double 1100 shell_volume(double radius, double thickness) 1101 { 1102 double whole = M_4PI_3 * cube(radius + thickness); 1103 double core = M_4PI_3 * cube(radius); 1104 return whole - core; 1105 } 1106 1107 If *shell_volume* is not present, then *form_volume* and *shell_volume* are 1108 assumed to be equal, and the shape is considered solid. 1058 1109 1059 1110 Unit Tests … … 1115 1166 ................... 1116 1167 1117 **NB: For now, this more detailed testing is only possible if you have a 1168 **NB: For now, this more detailed testing is only possible if you have a 1118 1169 SasView build environment available!** 1119 1170 … … 1253 1304 | 2016-10-25 Steve King 1254 1305 | 2017-05-07 Paul Kienzle - Moved from sasview to sasmodels docs 1306 | 2019-03-28 Paul Kienzle - Update docs for radius_effective and shell_volume -
doc/guide/resolution.rst
r0db85af rdb1d9d5 1 .. sm_help.rst2 3 .. This is a port of the original SasView html help file to ReSTructured text4 .. by S King, ISIS, during SasView CodeCamp-III in Feb 2015.1 .. resolution.rst 2 3 .. This is a port of the original SasView html help file sm_help to ReSTructured 4 .. text by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 5 5 6 6 … … 17 17 resolution contribution into a model calculation/simulation (which by definition 18 18 will be exact) to make it more representative of what has been measured 19 experimentally - a process called *smearing*. Sasmodels does the latter. 19 experimentally - a process called *smearing*. The Sasmodels component of SasView 20 does the latter. 20 21 21 22 Both smearing and desmearing rely on functions to describe the resolution … … 29 30 for the instrument and stored with the data file. If not, they will need to 30 31 be set manually before fitting. 32 33 .. note:: 34 Problems may be encountered if the data set loaded by SasView is a 35 concatenation of SANS data from several detector distances where, of 36 course, the worst Q resolution is next to the beam stop at each detector 37 distance. (This will also be noticeable in the residuals plot where 38 there will be poor overlap). SasView sensibly orders all the input 39 data points by increasing Q for nicer-looking plots, however, the dQ 40 data can then vary considerably from point to point. If 'Use dQ data' 41 smearing is selected then spikes may appear in the model fits, whereas 42 if 'None' or 'Custom Pinhole Smear' are selected the fits look normal. 43 44 In such instances, possible solutions are to simply remove the data 45 with poor Q resolution from the shorter detector distances, or to fit 46 the data from different detector distances simultaneously. 31 47 32 48 -
explore/beta/sasfit_compare.py
r119073a ra34b811 408 408 #radius_effective=12.59921049894873, 409 409 ) 410 target = sasmodels_theory(q, model, effective_radius_mode=0, structure_factor_mode=1, **pars)410 target = sasmodels_theory(q, model, radius_effective_mode=0, structure_factor_mode=1, **pars) 411 411 actual = ellipsoid_pe(q, norm='sasview', **pars) 412 412 title = " ".join(("sasmodels", model, pd_type)) -
explore/beta/sasfit_compare_new.py
rb6422c7 ra34b811 360 360 #polydispersity for hollow_cylinder 361 361 def hollow_cylinder_pe(q,radius=20, thickness=10, length=80, sld=4, sld_solvent=1, volfraction=0.15, 362 radius_pd=0.1, thickness_pd=0.2, length_pd=0.05, radius_pd_type="gaussian", length_pd_type="gaussian", 362 radius_pd=0.1, thickness_pd=0.2, length_pd=0.05, radius_pd_type="gaussian", length_pd_type="gaussian", 363 363 thickness_pd_type="gaussian", radius_effective=None, background=0, scale=1, 364 364 norm='sasview'): … … 595 595 # this one is only used locally for "actual" 596 596 ) 597 target = sasmodels_theory(q, model, effective_radius_mode=0, structure_factor_mode=1, **pars)597 target = sasmodels_theory(q, model, radius_effective_mode=0, structure_factor_mode=1, **pars) 598 598 actual = sphere_r(q, norm='sasview', **pars) 599 599 title = " ".join(("sasmodels", model, pd_type)) … … 612 612 background=0, 613 613 radius_pd=0.01, thickness_pd=0.01, radius_pd_type=pd_type, thickness_pd_type=pd_type, 614 radius_effective=30. ) 614 radius_effective=30. ) 615 615 # equivalent average sphere radius for local "actual" to match what sasview uses, use None to compute average outer radius here, 616 616 617 target = sasmodels_theory(q, model, effective_radius_mode=0, structure_factor_mode=1, **pars)617 target = sasmodels_theory(q, model, radius_effective_mode=0, structure_factor_mode=1, **pars) 618 618 actual = vesicle_pe(q, norm='sasview', **pars) 619 619 title = " ".join(("sasmodels", model, pd_type)) … … 633 633 background=0, 634 634 radius_pd=0.1, thickness_pd=0.0, length_pd=0.0, radius_pd_type=pd_type, thickness_pd_type=pd_type, length_pd_type=pd_type, 635 radius_effective=40.687) 635 radius_effective=40.687) 636 636 # equivalent average sphere radius for local "actual" to match what sasview uses 637 target = sasmodels_theory(q, model, effective_radius_mode=0, structure_factor_mode=1, **pars)637 target = sasmodels_theory(q, model, radius_effective_mode=0, structure_factor_mode=1, **pars) 638 638 actual = hollow_cylinder_pe(q, norm='sasview', **pars) 639 639 # RKH monodisp was OK, actual = hollow_cylinder_theta(q,radius=20, thickness=10, length=80, sld=4, sld_solvent=1 ) … … 656 656 # if change radius_effective to some other value, the S(Q) from sasview does not agree 657 657 ) 658 target = sasmodels_theory(q, model, effective_radius_mode=0, structure_factor_mode=1, **pars)658 target = sasmodels_theory(q, model, radius_effective_mode=0, structure_factor_mode=1, **pars) 659 659 actual = ellipsoid_pe(q, norm='sasview', **pars) 660 660 # RKH test actual = ellipsoid_theta(q, radius_polar=20, radius_equatorial=400, sld=4, sld_solvent=1, volfraction=0.15, radius_effective=270.) -
sasmodels/core.py
rb297ba9 r9562dd2 376 376 # type: () -> None 377 377 """Check that model load works""" 378 from .product import RADIUS_ID, VOLFRAC_ID, STRUCTURE_MODE_ID, RADIUS_MODE_ID 378 379 #Test the the model produces the parameters that we would expect 379 380 model = load_model("cylinder@hardsphere*sphere") 380 381 actual = [p.name for p in model.info.parameters.kernel_parameters] 381 target = ("sld sld_solvent radius length theta phi" 382 " radius_effective volfraction " 383 " structure_factor_mode radius_effective_mode" 384 " A_sld A_sld_solvent A_radius").split() 382 target = ["sld", "sld_solvent", "radius", "length", "theta", "phi", 383 RADIUS_ID, VOLFRAC_ID, STRUCTURE_MODE_ID, RADIUS_MODE_ID, 384 "A_sld", "A_sld_solvent", "A_radius"] 385 385 assert target == actual, "%s != %s"%(target, actual) 386 386 -
sasmodels/direct_model.py
rb297ba9 re220acc 59 59 """ 60 60 mesh = get_mesh(calculator.info, pars, dim=calculator.dim, mono=mono) 61 #print(" pars", list(zip(*mesh))[0])61 #print("in call_kernel: pars:", list(zip(*mesh))[0]) 62 62 call_details, values, is_magnetic = make_kernel_args(calculator, mesh) 63 #print(" values:", values)63 #print("in call_kernel: values:", values) 64 64 return calculator(call_details, values, cutoff, is_magnetic) 65 65 … … 72 72 73 73 Use parameter *radius_effective_mode* to select the effective radius 74 calculation. 74 calculation to use amongst the *radius_effective_modes* list given in the 75 model. 75 76 """ 76 77 R_eff_type = int(pars.pop(RADIUS_MODE_ID, 1.0)) 77 78 mesh = get_mesh(calculator.info, pars, dim=calculator.dim, mono=mono) 78 #print(" pars", list(zip(*mesh))[0])79 #print("in call_Fq: pars", list(zip(*mesh))[0]) 79 80 call_details, values, is_magnetic = make_kernel_args(calculator, mesh) 80 #print(" values:", values)81 #print("in call_Fq: values:", values) 81 82 return calculator.Fq(call_details, values, cutoff, is_magnetic, R_eff_type) 82 83 … … 118 119 active = lambda name: True 119 120 120 #print(" pars",[p.id for p in parameters.call_parameters])121 #print("in get_mesh: pars:",[p.id for p in parameters.call_parameters]) 121 122 mesh = [_get_par_weights(p, values, active(p.name)) 122 123 for p in parameters.call_parameters] -
sasmodels/generate.py
rb297ba9 ra34b811 27 27 which are hollow. 28 28 29 * effective_radius(mode, p1, p2, ...)* returns the effective radius of29 *radius_effective(mode, p1, p2, ...)* returns the effective radius of 30 30 the form with particular dimensions. Mode determines the type of 31 31 effective radius returned, with mode=1 for equivalent volume. … … 820 820 for p in partable.kernel_parameters)) 821 821 # Define the function calls 822 call_ effective_radius = "#define CALL_EFFECTIVE_RADIUS(_mode, _v) 0.0"822 call_radius_effective = "#define CALL_RADIUS_EFFECTIVE(_mode, _v) 0.0" 823 823 if partable.form_volume_parameters: 824 824 refs = _call_pars("_v.", partable.form_volume_parameters) … … 833 833 "do { _form = _shell = form_volume(%s); } " 834 834 "while (0)") % (",".join(refs)) 835 if model_info. effective_radius_type:836 call_ effective_radius= (837 "#define CALL_ EFFECTIVE_RADIUS(_mode, _v) "838 " effective_radius(_mode, %s)") % (",".join(refs))835 if model_info.radius_effective_modes: 836 call_radius_effective = ( 837 "#define CALL_RADIUS_EFFECTIVE(_mode, _v) " 838 "radius_effective(_mode, %s)") % (",".join(refs)) 839 839 else: 840 840 # Model doesn't have volume. We could make the kernel run a little … … 845 845 "do { _form = _shell = 1.0; } while (0)") 846 846 source.append(call_volume) 847 source.append(call_ effective_radius)847 source.append(call_radius_effective) 848 848 model_refs = _call_pars("_v.", partable.iq_parameters) 849 849 -
sasmodels/kernel.py
rb297ba9 ra34b811 78 78 """ 79 79 _, F2, _, shell_volume, _ = self.Fq(call_details, values, cutoff, 80 magnetic, effective_radius_type=0)80 magnetic, radius_effective_mode=0) 81 81 combined_scale = values[0]/shell_volume 82 82 background = values[1] … … 85 85 86 86 def Fq(self, call_details, values, cutoff, magnetic, 87 effective_radius_type=0):87 radius_effective_mode=0): 88 88 # type: (CallDetails, np.ndarray, np.ndarray, float, bool, int) -> np.ndarray 89 89 r""" … … 143 143 volume fraction of the particles. The model can have several 144 144 different ways to compute effective radius, with the 145 * effective_radius_type* parameter used to select amongst them. The145 *radius_effective_mode* parameter used to select amongst them. The 146 146 volume fraction of particles should be determined from the total 147 147 volume fraction of the form, not just the shell volume fraction. … … 153 153 """ 154 154 self._call_kernel(call_details, values, cutoff, magnetic, 155 effective_radius_type)155 radius_effective_mode) 156 156 #print("returned",self.q_input.q, self.result) 157 157 nout = 2 if self.info.have_Fq and self.dim == '1d' else 1 … … 165 165 form_volume = self.result[nout*self.q_input.nq + 1]/total_weight 166 166 shell_volume = self.result[nout*self.q_input.nq + 2]/total_weight 167 effective_radius= self.result[nout*self.q_input.nq + 3]/total_weight167 radius_effective = self.result[nout*self.q_input.nq + 3]/total_weight 168 168 if shell_volume == 0.: 169 169 shell_volume = 1. … … 171 171 if nout == 2 else None) 172 172 F2 = self.result[0:nout*self.q_input.nq:nout]/total_weight 173 return F1, F2, effective_radius, shell_volume, form_volume/shell_volume173 return F1, F2, radius_effective, shell_volume, form_volume/shell_volume 174 174 175 175 def release(self): … … 181 181 182 182 def _call_kernel(self, call_details, values, cutoff, magnetic, 183 effective_radius_type):183 radius_effective_mode): 184 184 # type: (CallDetails, np.ndarray, np.ndarray, float, bool, int) -> np.ndarray 185 185 """ -
sasmodels/kernel_iq.c
r12f4c19 r8973e0d 27 27 // parameters in the parameter table. 28 28 // CALL_VOLUME(form, shell, table) : assign form and shell values 29 // CALL_ EFFECTIVE_RADIUS(type, table) : call the R_eff function29 // CALL_RADIUS_EFFECTIVE(mode, table) : call the R_eff function 30 30 // CALL_IQ(q, table) : call the Iq function for 1D calcs. 31 31 // CALL_IQ_A(q, table) : call the Iq function with |q| for 2D data. … … 85 85 static void set_spin_weights(double in_spin, double out_spin, double weight[6]) 86 86 { 87 88 double norm; 87 89 in_spin = clip(in_spin, 0.0, 1.0); 88 90 out_spin = clip(out_spin, 0.0, 1.0); … … 94 96 // However, since the weights are applied to the final intensity and 95 97 // are not interned inside the I(q) function, we want the full 96 // weight and not the square root. Any function using 97 // set_spin_weights as part of calculating an amplitude will need to 98 // manually take that square root, but there is currently no such 99 // function. 100 weight[0] = (1.0-in_spin) * (1.0-out_spin); // dd 101 weight[1] = (1.0-in_spin) * out_spin; // du 102 weight[2] = in_spin * (1.0-out_spin); // ud 103 weight[3] = in_spin * out_spin; // uu 98 // weight and not the square root. Anyway no function will ever use 99 // set_spin_weights as part of calculating an amplitude, as the weights are 100 // related to polarisation efficiency of the instrument. The weights serve to 101 // construct various magnet scattering cross sections, which are linear combinations 102 // of the spin-resolved cross sections. The polarisation efficiency e_in and e_out 103 // are parameters ranging from 0.5 (unpolarised) beam to 1 (perfect optics). 104 // For in_spin or out_spin <0.5 one assumes a CS, where the spin is reversed/flipped 105 // with respect to the initial supermirror polariser. The actual polarisation efficiency 106 // in this case is however e_in/out = 1-in/out_spin. 107 108 if (out_spin < 0.5){norm=1-out_spin;} 109 else{norm=out_spin;} 110 111 112 // The norm is needed to make sure that the scattering cross sections are 113 //correctly weighted, such that the sum of spin-resolved measurements adds up to 114 // the unpolarised or half-polarised scattering cross section. No intensity weighting 115 // needed on the incoming polariser side (assuming that a user), has normalised 116 // to the incoming flux with polariser in for SANSPOl and unpolarised beam, respectively. 117 118 119 weight[0] = (1.0-in_spin) * (1.0-out_spin) / norm; // dd 120 weight[1] = (1.0-in_spin) * out_spin / norm; // du 121 weight[2] = in_spin * (1.0-out_spin) / norm; // ud 122 weight[3] = in_spin * out_spin / norm; // uu 104 123 weight[4] = weight[1]; // du.imag 105 124 weight[5] = weight[2]; // ud.imag … … 119 138 switch (xs) { 120 139 default: // keep compiler happy; condition ensures xs in [0,1,2,3] 121 case 0: // uu=> sld - D M_perpx140 case 0: // dd => sld - D M_perpx 122 141 return sld - px*perp; 123 case 1: // ud.real => -D M_perpy142 case 1: // du.real => -D M_perpy 124 143 return py*perp; 125 case 2: // du.real => -D M_perpy144 case 2: // ud.real => -D M_perpy 126 145 return py*perp; 127 case 3: // dd=> sld + D M_perpx146 case 3: // uu => sld + D M_perpx 128 147 return sld + px*perp; 129 148 } … … 285 304 pglobal double *result, // nq+1 return values, again with padding 286 305 const double cutoff, // cutoff in the dispersity weight product 287 int32_t effective_radius_type // which effective radius to compute306 int32_t radius_effective_mode // which effective radius to compute 288 307 ) 289 308 { … … 703 722 weighted_form += weight * form; 704 723 weighted_shell += weight * shell; 705 if ( effective_radius_type != 0) {706 weighted_radius += weight * CALL_ EFFECTIVE_RADIUS(effective_radius_type, local_values.table);724 if (radius_effective_mode != 0) { 725 weighted_radius += weight * CALL_RADIUS_EFFECTIVE(radius_effective_mode, local_values.table); 707 726 } 708 727 BUILD_ROTATION(); -
sasmodels/kernelcl.py
r069743a r9fac5f5 158 158 ENV = None 159 159 def reset_environment(): 160 # type: () -> None161 """ 162 Call to createa new OpenCL context, such as after a change to SAS_OPENCL.160 # type: () -> "GpuEnvironment" 161 """ 162 Return a new OpenCL context, such as after a change to SAS_OPENCL. 163 163 """ 164 164 global ENV 165 165 ENV = GpuEnvironment() if use_opencl() else None 166 166 return ENV 167 167 168 168 def environment(): … … 577 577 578 578 def _call_kernel(self, call_details, values, cutoff, magnetic, 579 effective_radius_type):579 radius_effective_mode): 580 580 # type: (CallDetails, np.ndarray, float, bool, int) -> np.ndarray 581 581 env = environment() … … 601 601 self._result_b, # Result storage. 602 602 self._as_dtype(cutoff), # Probability cutoff. 603 np.uint32( effective_radius_type), # R_eff mode.603 np.uint32(radius_effective_mode), # R_eff mode. 604 604 ] 605 605 -
sasmodels/kernelcuda.py
rb297ba9 ra34b811 473 473 474 474 def _call_kernel(self, call_details, values, cutoff, magnetic, 475 effective_radius_type):475 radius_effective_mode): 476 476 # type: (CallDetails, np.ndarray, float, bool, int) -> np.ndarray 477 477 … … 492 492 self._result_b, # Result storage. 493 493 self._as_dtype(cutoff), # Probability cutoff. 494 np.uint32( effective_radius_type), # R_eff mode.494 np.uint32(radius_effective_mode), # R_eff mode. 495 495 ] 496 496 grid = partition(self.q_input.nq) -
sasmodels/kerneldll.py
rb297ba9 ra34b811 403 403 404 404 def _call_kernel(self, call_details, values, cutoff, magnetic, 405 effective_radius_type):405 radius_effective_mode): 406 406 # type: (CallDetails, np.ndarray, float, bool, int) -> np.ndarray 407 407 … … 417 417 self.result.ctypes.data, # Result storage. 418 418 self._as_dtype(cutoff), # Probability cutoff. 419 effective_radius_type, # R_eff mode.419 radius_effective_mode, # R_eff mode. 420 420 ] 421 421 -
sasmodels/kernelpy.py
rb297ba9 ra34b811 172 172 volume = model_info.form_volume 173 173 shell = model_info.shell_volume 174 radius = model_info. effective_radius174 radius = model_info.radius_effective 175 175 self._volume = ((lambda: (shell(*volume_args), volume(*volume_args))) if shell and volume 176 176 else (lambda: [volume(*volume_args)]*2) if volume … … 180 180 else (lambda mode: 1.0)) 181 181 182 def _call_kernel(self, call_details, values, cutoff, magnetic, effective_radius_type):182 def _call_kernel(self, call_details, values, cutoff, magnetic, radius_effective_mode): 183 183 # type: (CallDetails, np.ndarray, np.ndarray, float, bool) -> np.ndarray 184 184 if magnetic: … … 186 186 #print("Calling python kernel") 187 187 #call_details.show(values) 188 radius = ((lambda: 0.0) if effective_radius_type == 0189 else (lambda: self._radius( effective_radius_type)))188 radius = ((lambda: 0.0) if radius_effective_mode == 0 189 else (lambda: self._radius(radius_effective_mode))) 190 190 self.result = _loops( 191 191 self._parameter_vector, self._form, self._volume, radius, -
sasmodels/model_test.py
rb297ba9 r8795b6f 240 240 s_name = pars.pop('@S') 241 241 ps_test = [pars] + list(test[1:]) 242 #print("PS TEST PARAMS!!!",ps_test) 242 243 # build the P@S model 243 244 s_info = load_model_info(s_name) … … 246 247 platform=self.platform) 247 248 # run the tests 249 #self.info = ps_model.info 250 #print("SELF.INFO PARAMS!!!",[p.id for p in self.info.parameters.call_parameters]) 251 #print("PS MODEL PARAMETERS:",[p.id for p in ps_model.info.parameters.call_parameters]) 248 252 results.append(self.run_one(ps_model, ps_test)) 249 253 … … 303 307 """Run a single test case.""" 304 308 user_pars, x, y = test[:3] 305 pars = expand_pars(self.info.parameters, user_pars) 306 invalid = invalid_pars(self.info.parameters, pars) 309 #print("PS MODEL PARAMETERS:",[p.id for p in model.info.parameters.call_parameters]) 310 pars = expand_pars(model.info.parameters, user_pars) 311 invalid = invalid_pars(model.info.parameters, pars) 307 312 if invalid: 308 313 raise ValueError("Unknown parameters in test: " + ", ".join(invalid)) … … 328 333 else: 329 334 y1 = y 330 y2 = test[3] if notisinstance(test[3], list) else [test[3]]331 F 1, F2, R_eff, volume, volume_ratio = call_Fq(kernel, pars)332 if F 1 is not None: # F1is none for models with Iq instead of Fq333 self._check_vectors(x, y1, F 1, 'F')334 self._check_vectors(x, y2, F 2, 'F^2')335 y2 = test[3] if isinstance(test[3], list) else [test[3]] 336 F, Fsq, R_eff, volume, volume_ratio = call_Fq(kernel, pars) 337 if F is not None: # F is none for models with Iq instead of Fq 338 self._check_vectors(x, y1, F, 'F') 339 self._check_vectors(x, y2, Fsq, 'F^2') 335 340 self._check_scalar(test[4], R_eff, 'R_eff') 336 341 self._check_scalar(test[5], volume, 'volume') 337 342 self._check_scalar(test[6], volume_ratio, 'form:shell ratio') 338 return F 2343 return Fsq 339 344 340 345 def _check_scalar(self, target, actual, name): 341 if target is None: 342 # smoke test --- make sure it runs and produces a value 343 self.assertTrue(not np.isnan(actual), 344 'invalid %s: %s' % (name, actual)) 345 elif np.isnan(target): 346 # make sure nans match 347 self.assertTrue(np.isnan(actual), 348 '%s: expected:%s; actual:%s' 349 % (name, target, actual)) 350 else: 351 # is_near does not work for infinite values, so also test 352 # for exact values. 353 self.assertTrue(target == actual or is_near(target, actual, 5), 354 '%s: expected:%s; actual:%s' 355 % (name, target, actual)) 346 self.assertTrue(is_near(target, actual, 5), 347 '%s: expected:%s; actual:%s' 348 % (name, target, actual)) 356 349 357 350 def _check_vectors(self, x, target, actual, name='I'): … … 363 356 '%s(...) returned wrong length'%name) 364 357 for xi, yi, actual_yi in zip(x, target, actual): 365 if yi is None: 366 # smoke test --- make sure it runs and produces a value 367 self.assertTrue(not np.isnan(actual_yi), 368 'invalid %s(%s): %s' % (name, xi, actual_yi)) 369 elif np.isnan(yi): 370 # make sure nans match 371 self.assertTrue(np.isnan(actual_yi), 372 '%s(%s): expected:%s; actual:%s' 373 % (name, xi, yi, actual_yi)) 374 else: 375 # is_near does not work for infinite values, so also test 376 # for exact values. 377 self.assertTrue(yi == actual_yi or is_near(yi, actual_yi, 5), 378 '%s(%s); expected:%s; actual:%s' 379 % (name, xi, yi, actual_yi)) 358 self.assertTrue(is_near(yi, actual_yi, 5), 359 '%s(%s): expected:%s; actual:%s' 360 % (name, xi, target, actual)) 380 361 381 362 return ModelTestCase … … 389 370 invalid = [] 390 371 for par in sorted(pars.keys()): 391 # special handling of R_eff mode, which is not a usual parameter 372 # Ignore the R_eff mode parameter when checking for valid parameters. 373 # It is an allowed parameter for a model even though it does not exist 374 # in the parameter table. The call_Fq() function pops it from the 375 # parameter list and sends it directly to kernel.Fq(). 392 376 if par == product.RADIUS_MODE_ID: 393 377 continue … … 405 389 """ 406 390 Returns true if *actual* is within *digits* significant digits of *target*. 407 """ 408 import math 409 shift = 10**math.ceil(math.log10(abs(target))) 410 return abs(target-actual)/shift < 1.5*10**-digits 391 392 *taget* zero and inf should match *actual* zero and inf. If you want to 393 accept eps for zero, choose a value such as 1e-10, which must match up to 394 +/- 1e-15 when *digits* is the default value of 5. 395 396 If *target* is None, then just make sure that *actual* is not NaN. 397 398 If *target* is NaN, make sure *actual* is NaN. 399 """ 400 if target is None: 401 # target is None => actual cannot be NaN 402 return not np.isnan(actual) 403 elif target == 0.: 404 # target is 0. => actual must be 0. 405 # Note: if small values are allowed, then use maybe test zero against eps instead? 406 return actual == 0. 407 elif np.isfinite(target): 408 shift = np.ceil(np.log10(abs(target))) 409 return abs(target-actual) < 1.5*10**(shift-digits) 410 elif target == actual: 411 # target is inf => actual must be inf of same sign 412 return True 413 else: 414 # target is NaN => actual must be NaN 415 return np.isnan(target) == np.isnan(actual) 411 416 412 417 # CRUFT: old interface; should be deprecated and removed -
sasmodels/modelinfo.py
rb297ba9 ra34b811 265 265 other sld parameters. The volume parameters are used for calls 266 266 to form_volume within the kernel (required for volume normalization), 267 to shell_volume (for hollow shapes), and to effective_radius(for267 to shell_volume (for hollow shapes), and to radius_effective (for 268 268 structure factor interactions) respectively. 269 269 … … 841 841 info.structure_factor = getattr(kernel_module, 'structure_factor', False) 842 842 # TODO: find Fq by inspection 843 info. effective_radius_type = getattr(kernel_module, 'effective_radius_type', None)843 info.radius_effective_modes = getattr(kernel_module, 'radius_effective_modes', None) 844 844 info.have_Fq = getattr(kernel_module, 'have_Fq', False) 845 845 info.profile_axes = getattr(kernel_module, 'profile_axes', ['x', 'y']) … … 848 848 info.source = getattr(kernel_module, 'source', []) 849 849 info.c_code = getattr(kernel_module, 'c_code', None) 850 info. effective_radius = getattr(kernel_module, 'effective_radius', None)850 info.radius_effective = getattr(kernel_module, 'radius_effective', None) 851 851 # TODO: check the structure of the tests 852 852 info.tests = getattr(kernel_module, 'tests', []) … … 961 961 #: List of options for computing the effective radius of the shape, 962 962 #: or None if the model is not usable as a form factor model. 963 effective_radius_type= None # type: List[str]963 radius_effective_modes = None # type: List[str] 964 964 #: List of C source files used to define the model. The source files 965 965 #: should define the *Iq* function, and possibly *Iqac* or *Iqabc* if the … … 989 989 #: monodisperse approximation for non-dilute solutions, P@S. The first 990 990 #: argument is the integer effective radius mode, with default 0. 991 effective_radius= None # type: Union[None, Callable[[int, np.ndarray], float]]991 radius_effective = None # type: Union[None, Callable[[int, np.ndarray], float]] 992 992 #: Returns *I(q, a, b, ...)* for parameters *a*, *b*, etc. defined 993 993 #: by the parameter table. *Iq* can be defined as a python function, or -
sasmodels/models/_spherepy.py
r0507e09 ra34b811 48 48 ---------------------------- 49 49 50 * **Author: P Kienzle** 51 * **Last Modified by:** 50 * **Author: P Kienzle** 51 * **Last Modified by:** 52 52 * **Last Reviewed by:** S King and P Parker **Date:** 2013/09/09 and 2014/01/06 53 53 * **Source added by :** Steve King **Date:** March 25, 2019 … … 83 83 return 1.333333333333333 * pi * radius ** 3 84 84 85 def effective_radius(mode, radius):85 def radius_effective(mode, radius): 86 86 """Calculate R_eff for sphere""" 87 return radius 87 return radius if mode else 0. 88 88 89 89 def Iq(q, sld, sld_solvent, radius): -
sasmodels/models/barbell.c
r99658f6 ra34b811 85 85 86 86 static double 87 effective_radius(int mode, double radius_bell, double radius, double length)87 radius_effective(int mode, double radius_bell, double radius, double length) 88 88 { 89 89 switch (mode) { -
sasmodels/models/barbell.py
r0507e09 ra34b811 126 126 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "barbell.c"] 127 127 have_Fq = True 128 effective_radius_type= [128 radius_effective_modes = [ 129 129 "equivalent cylinder excluded volume", "equivalent volume sphere", 130 130 "radius", "half length", "half total length", -
sasmodels/models/capped_cylinder.c
r99658f6 ra34b811 107 107 108 108 static double 109 effective_radius(int mode, double radius, double radius_cap, double length)109 radius_effective(int mode, double radius, double radius_cap, double length) 110 110 { 111 111 switch (mode) { -
sasmodels/models/capped_cylinder.py
r0507e09 ra34b811 146 146 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "capped_cylinder.c"] 147 147 have_Fq = True 148 effective_radius_type= [148 radius_effective_modes = [ 149 149 "equivalent cylinder excluded volume", "equivalent volume sphere", 150 150 "radius", "half length", "half total length", -
sasmodels/models/core_multi_shell.c
rd42dd4a ra34b811 26 26 27 27 static double 28 effective_radius(int mode, double core_radius, double fp_n, double thickness[])28 radius_effective(int mode, double core_radius, double fp_n, double thickness[]) 29 29 { 30 30 switch (mode) { -
sasmodels/models/core_multi_shell.py
r0507e09 ra34b811 108 108 source = ["lib/sas_3j1x_x.c", "core_multi_shell.c"] 109 109 have_Fq = True 110 effective_radius_type= ["outer radius", "core radius"]110 radius_effective_modes = ["outer radius", "core radius"] 111 111 112 112 def random(): -
sasmodels/models/core_shell_bicelle.c
r99658f6 ra34b811 60 60 61 61 static double 62 effective_radius(int mode, double radius, double thick_rim, double thick_face, double length)62 radius_effective(int mode, double radius, double thick_rim, double thick_face, double length) 63 63 { 64 64 switch (mode) { -
sasmodels/models/core_shell_bicelle.py
r0507e09 ra34b811 165 165 "core_shell_bicelle.c"] 166 166 have_Fq = True 167 effective_radius_type= [167 radius_effective_modes = [ 168 168 "excluded volume", "equivalent volume sphere", "outer rim radius", 169 169 "half outer thickness", "half diagonal", -
sasmodels/models/core_shell_bicelle_elliptical.c
r99658f6 ra34b811 35 35 36 36 static double 37 effective_radius(int mode, double r_minor, double x_core, double thick_rim, double thick_face, double length)37 radius_effective(int mode, double r_minor, double x_core, double thick_rim, double thick_face, double length) 38 38 { 39 39 switch (mode) { -
sasmodels/models/core_shell_bicelle_elliptical.py
r0507e09 ra34b811 155 155 "core_shell_bicelle_elliptical.c"] 156 156 have_Fq = True 157 effective_radius_type= [157 radius_effective_modes = [ 158 158 "equivalent cylinder excluded volume", "equivalent volume sphere", 159 159 "outer rim average radius", "outer rim min radius", -
sasmodels/models/core_shell_bicelle_elliptical_belt_rough.c
r99658f6 ra34b811 36 36 37 37 static double 38 effective_radius(int mode, double r_minor, double x_core, double thick_rim, double thick_face, double length)38 radius_effective(int mode, double r_minor, double x_core, double thick_rim, double thick_face, double length) 39 39 { 40 40 switch (mode) { -
sasmodels/models/core_shell_bicelle_elliptical_belt_rough.py
r0507e09 ra34b811 168 168 "core_shell_bicelle_elliptical_belt_rough.c"] 169 169 have_Fq = True 170 effective_radius_type= [170 radius_effective_modes = [ 171 171 "equivalent cylinder excluded volume", "equivalent volume sphere", 172 172 "outer rim average radius", "outer rim min radius", -
sasmodels/models/core_shell_cylinder.c
r99658f6 ra34b811 37 37 38 38 static double 39 effective_radius(int mode, double radius, double thickness, double length)39 radius_effective(int mode, double radius, double thickness, double length) 40 40 { 41 41 switch (mode) { -
sasmodels/models/core_shell_cylinder.py
r0507e09 rdb1d9d5 46 46 density of the solvent, and *background* is the background level. The outer 47 47 radius of the shell is given by $R+T$ and the total length of the outer 48 shell is given by $L+2T$. $J 1$ is the first order Bessel function.48 shell is given by $L+2T$. $J_1$ is the first order Bessel function. 49 49 50 50 .. _core-shell-cylinder-geometry: … … 141 141 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "core_shell_cylinder.c"] 142 142 have_Fq = True 143 effective_radius_type= [143 radius_effective_modes = [ 144 144 "excluded volume", "equivalent volume sphere", "outer radius", "half outer length", 145 145 "half min outer dimension", "half max outer dimension", "half outer diagonal", -
sasmodels/models/core_shell_ellipsoid.c
r99658f6 ra34b811 68 68 69 69 static double 70 effective_radius(int mode, double radius_equat_core, double x_core, double thick_shell, double x_polar_shell)70 radius_effective(int mode, double radius_equat_core, double x_core, double thick_shell, double x_polar_shell) 71 71 { 72 72 const double radius_equat_tot = radius_equat_core + thick_shell; -
sasmodels/models/core_shell_ellipsoid.py
r0507e09 rdb1d9d5 3 3 ---------- 4 4 5 Parameters for this model are the core axial ratio X and a shell thickness, 6 which are more often what we would like to determine and makes the model 7 better behaved, particularly when polydispersity is applied than the four 8 independent radii used in the original parameterization of this model. 5 Parameters for this model are the core axial ratio $X_{core}$ and a shell 6 thickness $t_{shell}$, which are more often what we would like to determine 7 and make the model better behaved, particularly when polydispersity is 8 applied, than the four independent radii used in the original parameterization 9 of this model. 9 10 10 11 … … 15 16 the poles, of a prolate ellipsoid. 16 17 17 When *X_core < 1* the core is oblate; when *X_core > 1* it is prolate. 18 *X_core = 1* is a spherical core. 19 20 For a fixed shell thickness *XpolarShell = 1*, to scale the shell thickness 21 pro-rata with the radius set or constrain *XpolarShell = X_core*. 22 23 When including an $S(q)$, the radius in $S(q)$ is calculated to be that of 24 a sphere with the same 2nd virial coefficient of the outer surface of the 25 ellipsoid. This may have some undesirable effects if the aspect ratio of the 26 ellipsoid is large (ie, if $X << 1$ or $X >> 1$ ), when the $S(q)$ 27 - which assumes spheres - will not in any case be valid. Generating a 28 custom product model will enable separate effective volume fraction and 29 effective radius in the $S(q)$. 18 When $X_{core}$ < 1 the core is oblate; when $X_{core}$ > 1 it is prolate. 19 $X_{core}$ = 1 is a spherical core. 20 21 For a fixed shell thickness $X_{polar shell}$ = 1, to scale $t_{shell}$ 22 pro-rata with the radius set or constrain $X_{polar shell}$ = $X_{core}$. 23 24 .. note:: 25 26 When including an $S(q)$, the radius in $S(q)$ is calculated to be that of 27 a sphere with the same 2nd virial coefficient of the outer surface of the 28 ellipsoid. This may have some undesirable effects if the aspect ratio of the 29 ellipsoid is large (ie, if $X << 1$ or $X >> 1$), when the $S(q)$ 30 - which assumes spheres - will not in any case be valid. Generating a 31 custom product model will enable separate effective volume fraction and 32 effective radius in the $S(q)$. 30 33 31 34 If SAS data are in absolute units, and the SLDs are correct, then scale should … … 43 46 where 44 47 48 .. In following equation SK changed radius\_equat\_core to R_e 45 49 .. math:: 46 50 :nowrap: 47 51 48 52 \begin{align*} 49 F(q,\alpha) = &f(q, radius\_equat\_core,radius\_equat\_core.x\_core,\alpha) \\50 &+ f(q, radius\_equat\_core + thick\_shell,51 radius\_equat\_core.x\_core + thick\_shell.x\_polar\_shell,\alpha)53 F(q,\alpha) = &f(q,R_e,R_e.x_{core},\alpha) \\ 54 &+ f(q,R_e + t_{shell}, 55 R_e.x_{core} + t_{shell}.x_{polar shell},\alpha) 52 56 \end{align*} 53 57 … … 71 75 $V = (4/3)\pi R_pR_e^2$ is the volume of the ellipsoid , $R_p$ is the 72 76 polar radius along the rotational axis of the ellipsoid, $R_e$ is the 73 equatorial radius perpendicular to the rotational axis of the ellipsoid 74 and $\Delta \rho$ (contrast) is the scattering length density difference, 75 either $(sld\_core - sld\_shell)$ or $(sld\_shell - sld\_solvent)$. 77 equatorial radius perpendicular to the rotational axis of the ellipsoid, 78 $t_{shell}$ is the thickness of the shell at the equator, 79 and $\Delta \rho$ (the contrast) is the scattering length density difference, 80 either $(\rho_{core} - \rho_{shell})$ or $(\rho_{shell} - \rho_{solvent})$. 76 81 77 82 For randomly oriented particles: … … 104 109 * **Author:** NIST IGOR/DANSE **Date:** pre 2010 105 110 * **Last Modified by:** Richard Heenan (reparametrised model) **Date:** 2015 106 * **Last Reviewed by:** Richard Heenan **Date:** October 6, 2016111 * **Last Reviewed by:** Steve King **Date:** March 27, 2019 107 112 * **Source added by :** Steve King **Date:** March 25, 2019 108 113 """ … … 155 160 source = ["lib/sas_3j1x_x.c", "lib/gauss76.c", "core_shell_ellipsoid.c"] 156 161 have_Fq = True 157 effective_radius_type= [162 radius_effective_modes = [ 158 163 "average outer curvature", "equivalent volume sphere", 159 164 "min outer radius", "max outer radius", -
sasmodels/models/core_shell_parallelepiped.c
r99658f6 ra34b811 75 75 76 76 static double 77 effective_radius(int mode, double length_a, double length_b, double length_c,77 radius_effective(int mode, double length_a, double length_b, double length_c, 78 78 double thick_rim_a, double thick_rim_b, double thick_rim_c) 79 79 { -
sasmodels/models/core_shell_parallelepiped.py
r0507e09 ra34b811 236 236 source = ["lib/gauss76.c", "core_shell_parallelepiped.c"] 237 237 have_Fq = True 238 effective_radius_type= [238 radius_effective_modes = [ 239 239 "equivalent cylinder excluded volume", 240 240 "equivalent volume sphere", -
sasmodels/models/core_shell_sphere.c
rd42dd4a ra34b811 6 6 7 7 static double 8 effective_radius(int mode, double radius, double thickness)8 radius_effective(int mode, double radius, double thickness) 9 9 { 10 10 switch (mode) { -
sasmodels/models/core_shell_sphere.py
r0507e09 ra34b811 60 60 ---------------------------- 61 61 62 * **Author:** 63 * **Last Modified by:** 64 * **Last Reviewed by:** 62 * **Author:** 63 * **Last Modified by:** 64 * **Last Reviewed by:** 65 65 * **Source added by :** Steve King **Date:** March 25, 2019 66 66 """ … … 92 92 source = ["lib/sas_3j1x_x.c", "lib/core_shell.c", "core_shell_sphere.c"] 93 93 have_Fq = True 94 effective_radius_type= ["outer radius", "core radius"]94 radius_effective_modes = ["outer radius", "core radius"] 95 95 96 96 demo = dict(scale=1, background=0, radius=60, thickness=10, -
sasmodels/models/cylinder.c
r99658f6 ra34b811 32 32 33 33 static double 34 effective_radius(int mode, double radius, double length)34 radius_effective(int mode, double radius, double length) 35 35 { 36 36 switch (mode) { -
sasmodels/models/cylinder.py
r0507e09 ra34b811 110 110 ---------------------------- 111 111 112 * **Author:** 113 * **Last Modified by:** 114 * **Last Reviewed by:** 112 * **Author:** 113 * **Last Modified by:** 114 * **Last Reviewed by:** 115 115 * **Source added by :** Steve King **Date:** March 25, 2019 116 116 """ … … 155 155 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "cylinder.c"] 156 156 have_Fq = True 157 effective_radius_type= [157 radius_effective_modes = [ 158 158 "excluded volume", "equivalent volume sphere", "radius", 159 159 "half length", "half min dimension", "half max dimension", "half diagonal", … … 184 184 phi_pd=10, phi_pd_n=5) 185 185 186 # pylint: disable=bad-whitespace, line-too-long186 # Test 1-D and 2-D models 187 187 qx, qy = 0.2 * np.cos(2.5), 0.2 * np.sin(2.5) 188 # After redefinition of angles, find new tests values. Was 10 10 in old coords 188 theta, phi = 80.1534480601659, 10.1510817110481 # (10, 10) in sasview 3.x 189 189 tests = [ 190 190 [{}, 0.2, 0.042761386790780453], 191 191 [{}, [0.2], [0.042761386790780453]], 192 # new coords 193 [{'theta':80.1534480601659, 'phi':10.1510817110481}, (qx, qy), 0.03514647218513852], 194 [{'theta':80.1534480601659, 'phi':10.1510817110481}, [(qx, qy)], [0.03514647218513852]], 195 # old coords 196 #[{'theta':10.0, 'phi':10.0}, (qx, qy), 0.03514647218513852], 197 #[{'theta':10.0, 'phi':10.0}, [(qx, qy)], [0.03514647218513852]], 192 [{'theta': theta, 'phi': phi}, (qx, qy), 0.03514647218513852], 193 [{'theta': theta, 'phi': phi}, [(qx, qy)], [0.03514647218513852]], 198 194 ] 199 del qx, qy # not necessary to delete, but cleaner 200 201 # Default radius and length 202 def calc_volume(radius, length): 203 """Return form volume for cylinder.""" 204 return pi*radius**2*length 205 def calc_r_effs(radius, length): 206 """Return effective radii for modes 0-7 of cylinder.""" 207 return [ 195 del qx, qy, theta, phi # not necessary to delete, but cleaner 196 197 def _extend_with_reff_tests(radius, length): 198 """Test R_eff and form volume calculations""" 199 # V and Vr are the same for each R_eff mode 200 V = pi*radius**2*length # shell volume = form volume for solid objects 201 Vr = 1.0 # form:shell volume ratio 202 # Use test value for I(0.2) from above to check Fsq value. Need to 203 # remove scale and background before testing. 204 q = 0.2 205 scale, background = V, 0.001 206 Fsq = (0.042761386790780453 - background)*scale 207 F = None # Need target value for <F> 208 # Various values for R_eff, depending on mode 209 r_effs = [ 208 210 0., 209 211 0.5*(0.75*radius*(2.0*radius*length … … 216 218 np.sqrt(4*radius**2 + length**2)/2., 217 219 ] 218 r_effs = calc_r_effs(parameters[2][2], parameters[3][2]) 219 cyl_vol = calc_volume(parameters[2][2], parameters[3][2]) 220 tests.extend([ 221 ({'radius_effective_mode': 0}, 0.1, None, None, r_effs[0], cyl_vol, 1.0),222 ({'radius_effective_mode': 1}, 0.1, None, None, r_effs[1], None, None),223 ({'radius_effective_mode': 2}, 0.1, None, None, r_effs[2], None, None),224 ({'radius_effective_mode': 3}, 0.1, None, None, r_effs[3], None, None),225 ({'radius_effective_mode': 4}, 0.1, None, None, r_effs[4], None, None),226 ({'radius_effective_mode': 5}, 0.1, None, None, r_effs[5], None, None),227 ({'radius_effective_mode': 6}, 0.1, None, None, r_effs[6], None, None),228 ({'radius_effective_mode': 7}, 0.1, None, None, r_effs[7], None, None), 229 ]) 230 del r_effs, cyl_vol 231 # pylint: enable=bad-whitespace, line-too-long 220 tests.extend([ 221 ({'radius_effective_mode': 0}, q, F, Fsq, r_effs[0], V, Vr), 222 ({'radius_effective_mode': 1}, q, F, Fsq, r_effs[1], V, Vr), 223 ({'radius_effective_mode': 2}, q, F, Fsq, r_effs[2], V, Vr), 224 ({'radius_effective_mode': 3}, q, F, Fsq, r_effs[3], V, Vr), 225 ({'radius_effective_mode': 4}, q, F, Fsq, r_effs[4], V, Vr), 226 ({'radius_effective_mode': 5}, q, F, Fsq, r_effs[5], V, Vr), 227 ({'radius_effective_mode': 6}, q, F, Fsq, r_effs[6], V, Vr), 228 ({'radius_effective_mode': 7}, q, F, Fsq, r_effs[7], V, Vr), 229 ]) 230 231 # Test Reff and volume with default model parameters 232 _extend_with_reff_tests(parameters[2][2], parameters[3][2]) 233 del _extend_with_reff_tests 232 234 233 235 # ADDED by: RKH ON: 18Mar2016 renamed sld's etc -
sasmodels/models/ellipsoid.c
r99658f6 ra34b811 32 32 33 33 static double 34 effective_radius(int mode, double radius_polar, double radius_equatorial)34 radius_effective(int mode, double radius_polar, double radius_equatorial) 35 35 { 36 36 switch (mode) { -
sasmodels/models/ellipsoid.py
r0507e09 ra34b811 167 167 source = ["lib/sas_3j1x_x.c", "lib/gauss76.c", "ellipsoid.c"] 168 168 have_Fq = True 169 effective_radius_type= [169 radius_effective_modes = [ 170 170 "average curvature", "equivalent volume sphere", "min radius", "max radius", 171 171 ] -
sasmodels/models/elliptical_cylinder.c
r99658f6 ra34b811 41 41 42 42 static double 43 effective_radius(int mode, double radius_minor, double r_ratio, double length)43 radius_effective(int mode, double radius_minor, double r_ratio, double length) 44 44 { 45 45 switch (mode) { -
sasmodels/models/elliptical_cylinder.py
r0507e09 ra34b811 131 131 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "elliptical_cylinder.c"] 132 132 have_Fq = True 133 effective_radius_type= [133 radius_effective_modes = [ 134 134 "equivalent cylinder excluded volume", 135 135 "equivalent volume sphere", "average radius", "min radius", "max radius", -
sasmodels/models/flexible_cylinder.py
r598a354 rdb1d9d5 33 33 and solvent respectively. 34 34 35 Our model uses the form factor calculations i mplemented in a c-library provided36 by the NIST Center for Neutron Research (Kline, 2006). This states:35 Our model uses the form factor calculations in reference [1] as implemented in a 36 c-library provided by the NIST Center for Neutron Research (Kline, 2006). This states: 37 37 38 38 'Method 3 With Excluded Volume' is used. … … 42 42 See equations (13,26-27) in the original reference for the details. 43 43 44 .. note:: 45 46 There are several typos in the original reference that have been corrected 47 by WRC [2]. Details of the corrections are in the reference below. Most notably 48 49 - Equation (13): the term $(1 - w(QR))$ should swap position with $w(QR)$ 50 51 - Equations (23) and (24) are incorrect; WRC has entered these into 52 Mathematica and solved analytically. The results were then converted to 53 code. 54 55 - Equation (27) should be $q0 = max(a3/(Rg^2)^{1/2},3)$ instead of 56 $max(a3*b(Rg^2)^{1/2},3)$ 57 58 - The scattering function is negative for a range of parameter values and 59 q-values that are experimentally accessible. A correction function has been 60 added to give the proper behavior. 61 62 63 **This is a model with complex behaviour depending on the ratio of** $L/b$ **and the 64 reader is strongly encouraged to read reference [1] before use.** 65 66 .. note:: 67 68 There are several typos in the original reference that have been corrected 69 by WRC [2]. Details of the corrections are in the reference below. Most notably 70 71 - Equation (13): the term $(1 - w(QR))$ should swap position with $w(QR)$ 72 73 - Equations (23) and (24) are incorrect; WRC has entered these into 74 Mathematica and solved analytically. The results were then converted to 75 code. 76 77 - Equation (27) should be $q0 = max(a3/(Rg^2)^{1/2},3)$ instead of 78 $max(a3*b(Rg^2)^{1/2},3)$ 79 80 - The scattering function is negative for a range of parameter values and 81 q-values that are experimentally accessible. A correction function has been 82 added to give the proper behavior. 83 84 85 **This is a model with complex behaviour depending on the ratio of** $L/b$ **and the 86 reader is strongly encouraged to read reference [1] before use.** 87 44 88 References 45 89 ---------- … … 58 102 `flexible_cylinder.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/flexible_cylinder.c>`_ 59 103 104 `wrc_cyl.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/lib/wrc_cyl.c>`_ 105 60 106 Authorship and Verification 61 107 ---------------------------- 62 108 63 * **Author:** 64 * **Last Modified by:** 65 * **Last Reviewed by:** 109 * **Author:** 110 * **Last Modified by:** 111 * **Last Reviewed by:** Steve King **Date:** March 26, 2019 66 112 * **Source added by :** Steve King **Date:** March 25, 2019 67 113 """ -
sasmodels/models/flexible_cylinder_elliptical.py
r598a354 rdb1d9d5 4 4 The non-negligible diameter of the cylinder is included by accounting 5 5 for excluded volume interactions within the walk of a single cylinder. 6 **Inter-cylinder interactions are NOT provided for.** 7 6 8 The form factor is normalized by the particle volume such that 7 9 … … 24 26 ----------- 25 27 26 The function calculated in a similar way to that for the flexible_cylinder model 27 from the reference given below using the author's "Method 3 With Excluded Volume". 28 The function is calculated in a similar way to that for the 29 :ref:`flexible-cylinder` model in reference [1] below using the author's 30 "Method 3 With Excluded Volume". 31 28 32 The model is a parameterization of simulations of a discrete representation of 29 33 the worm-like chain model of Kratky and Porod applied in the pseudo-continuous … … 33 37 34 38 There are several typos in the original reference that have been corrected 35 by WRC . Details of the corrections are in the reference below. Most notably39 by WRC [2]. Details of the corrections are in the reference below. Most notably 36 40 37 41 - Equation (13): the term $(1 - w(QR))$ should swap position with $w(QR)$ … … 41 45 code. 42 46 43 - Equation (27) should be $q0 = max(a3/ sqrt(RgSquare),3)$ instead of44 $max(a3*b /sqrt(RgSquare),3)$47 - Equation (27) should be $q0 = max(a3/(Rg^2)^{1/2},3)$ instead of 48 $max(a3*b(Rg^2)^{1/2},3)$ 45 49 46 50 - The scattering function is negative for a range of parameter values and … … 58 62 59 63 The cross section of the cylinder is elliptical, with minor radius $a$ . 60 The major radius is larger, so of course, **the axis ratio (parameter 5)must be64 The major radius is larger, so of course, **the axis_ratio must be 61 65 greater than one.** Simple constraints should be applied during curve fitting to 62 66 maintain this inequality. … … 67 71 these parameters must be held fixed during model fitting. 68 72 69 **No inter-cylinder interference effects are included in this calculation.** 73 **This is a model with complex behaviour depending on the ratio of** $L/b$ **and the 74 reader is strongly encouraged to read reference [1] before use.** 70 75 71 76 References … … 85 90 `flexible_cylinder_elliptical.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/flexible_cylinder_elliptical.c>`_ 86 91 92 `wrc_cyl.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/lib/wrc_cyl.c>`_ 93 87 94 Authorship and Verification 88 95 ---------------------------- 89 96 90 * **Author:** 91 * **Last Modified by:** 92 * **Last Reviewed by:** 97 * **Author:** 98 * **Last Modified by:** Richard Heenan **Date:** December, 2016 99 * **Last Reviewed by:** Steve King **Date:** March 26, 2019 93 100 * **Source added by :** Steve King **Date:** March 25, 2019 94 101 """ -
sasmodels/models/fuzzy_sphere.c
rd42dd4a ra34b811 5 5 6 6 static double 7 effective_radius(int mode, double radius, double fuzziness)7 radius_effective(int mode, double radius, double fuzziness) 8 8 { 9 9 switch (mode) { -
sasmodels/models/fuzzy_sphere.py
r0507e09 ra34b811 63 63 ---------------------------- 64 64 65 * **Author:** 66 * **Last Modified by:** 67 * **Last Reviewed by:** 65 * **Author:** 66 * **Last Modified by:** 67 * **Last Reviewed by:** 68 68 * **Source added by :** Steve King **Date:** March 25, 2019 69 69 """ … … 98 98 source = ["lib/sas_3j1x_x.c", "fuzzy_sphere.c"] 99 99 have_Fq = True 100 effective_radius_type= ["radius", "radius + fuzziness"]100 radius_effective_modes = ["radius", "radius + fuzziness"] 101 101 102 102 def random(): -
sasmodels/models/guinier_porod.py
r0507e09 rdb1d9d5 5 5 such as rods or platelets, and shapes intermediate between spheres 6 6 and rods or between rods and platelets, and overcomes some of the 7 deficiencies of the (Beaucage) Unified_Power_Rgmodel (see Hammouda, 2010).7 deficiencies of the (Beaucage) :ref:`unified-power-rg` model (see Hammouda, 2010). 8 8 9 9 Definition -
sasmodels/models/hardsphere.py
r0507e09 r4d00de6 1 1 # Note: model title and parameter table are inserted automatically 2 r"""Calculate the interparticle structure factor for monodisperse 2 r""" 3 Calculates the interparticle structure factor for monodisperse 3 4 spherical particles interacting through hard sphere (excluded volume) 4 interactions. 5 May be a reasonable approximation for other shapes of particles that 6 freely rotate, and for moderately polydisperse systems. Though strictly 7 the maths needs to be modified (no \Beta(Q) correction yet in sasview). 5 interactions. This $S(q)$ may also be a reasonable approximation for 6 other particle shapes that freely rotate (but see the note below), 7 and for moderately polydisperse systems. 8 9 .. note:: 10 11 This routine is intended for uncharged particles! For charged 12 particles try using the :ref:`hayter-msa` $S(q)$ instead. 13 14 .. note:: 15 16 Earlier versions of SasView did not incorporate the so-called 17 $\beta(q)$ ("beta") correction [1] for polydispersity and non-sphericity. 18 This is only available in SasView versions 5.0 and higher. 8 19 9 20 radius_effective is the effective hard sphere radius. 10 21 volfraction is the volume fraction occupied by the spheres. 11 22 12 In sasview the effective radius may be calculated from the parameters23 In SasView the effective radius may be calculated from the parameters 13 24 used in the form factor $P(q)$ that this $S(q)$ is combined with. 14 25 15 26 For numerical stability the computation uses a Taylor series expansion 16 at very small $qR$, there may be a very minor glitch at the transition point17 in some circumstances.27 at very small $qR$, but there may be a very minor glitch at the 28 transition point in some circumstances. 18 29 19 Th e S(Q) uses the Percus-Yevick closure where the interparticle20 potentialis30 This S(q) uses the Percus-Yevick closure relationship [2] where the 31 interparticle potential $U(r)$ is 21 32 22 33 .. math:: … … 27 38 \end{cases} 28 39 29 where $r$ is the distance from the center of thesphere of a radius $R$.40 where $r$ is the distance from the center of a sphere of a radius $R$. 30 41 31 42 For a 2D plot, the wave transfer is defined as … … 39 50 ---------- 40 51 52 .. [#] M Kotlarchyk & S-H Chen, *J. Chem. Phys.*, 79 (1983) 2461-2469 53 41 54 .. [#] J K Percus, J Yevick, *J. Phys. Rev.*, 110, (1958) 1 42 55 … … 49 62 ---------------------------- 50 63 51 * **Author:** 52 * **Last Modified by:** 53 * **Last Reviewed by:** 64 * **Author:** 65 * **Last Modified by:** 66 * **Last Reviewed by:** 54 67 * **Source added by :** Steve King **Date:** March 25, 2019 55 68 """ … … 63 76 [Hard sphere structure factor, with Percus-Yevick closure] 64 77 Interparticle S(Q) for random, non-interacting spheres. 65 May be a reasonable approximation for other shapes of66 particles that freely rotate, and for moderately polydisperse67 systems. Though strictly the maths needs to be modified -68 which sasview does not do yet.78 May be a reasonable approximation for other particle shapes 79 that freely rotate, and for moderately polydisperse systems 80 . The "beta(q)" correction is available in versions 4.2.2 81 and higher. 69 82 radius_effective is the hard sphere radius 70 83 volfraction is the volume fraction occupied by the spheres. -
sasmodels/models/hayter_msa.py
r0507e09 r4d00de6 1 1 # Note: model title and parameter table are inserted automatically 2 2 r""" 3 This calculates the structure factor (the Fourier transform of the pair 4 correlation function $g(r)$) for a system of charged, spheroidal objects 5 in a dielectric medium. When combined with an appropriate form factor 6 (such as sphere, core+shell, ellipsoid, etc), this allows for inclusion 7 of the interparticle interference effects due to screened coulomb repulsion 8 between charged particles. 3 Calculates the interparticle structure factor for a system of charged, 4 spheroidal, objects in a dielectric medium [1,2]. When combined with an 5 appropriate form factor $P(q)$, this allows for inclusion of the 6 interparticle interference effects due to screened Coulombic 7 repulsion between the charged particles. 9 8 10 **This routine only works for charged particles**. If the charge is set to 11 zero the routine may self-destruct! For non-charged particles use a hard 12 sphere potential. 9 .. note:: 10 11 This routine only works for charged particles! If the charge is set 12 to zero the routine may self-destruct! For uncharged particles use 13 the :ref:`hardsphere` $S(q)$ instead. The upper limit for the charge 14 is limited to 200e to avoid numerical instabilities. 15 16 .. note:: 17 18 Earlier versions of SasView did not incorporate the so-called 19 $\beta(q)$ ("beta") correction [3] for polydispersity and non-sphericity. 20 This is only available in SasView versions 5.0 and higher. 13 21 14 22 The salt concentration is used to compute the ionic strength of the solution 15 which in turn is used to compute the Debye screening length. At present16 there is no provision for entering the ionic strength directly nor for use17 of any multivalent salts, though it should be possible to simulate the effect 18 of this by increasing the salt concentration. The counterions are also 19 assumed to be monovalent.23 which in turn is used to compute the Debye screening length. There is no 24 provision for entering the ionic strength directly. **At present the 25 counterions are assumed to be monovalent**, though it should be possible 26 to simulate the effect of multivalent counterions by increasing the salt 27 concentration. 20 28 21 In sasview the effective radius may be calculated from the parameters 29 Over the range 0 - 100 C the dielectric constant $\kappa$ of water may be 30 approximated with a maximum deviation of 0.01 units by the empirical 31 formula [4] 32 33 .. math:: 34 35 \kappa = 87.740 - 0.40008 T + 9.398x10^{-4} T^2 - 1.410x10^{-6} T^3 36 37 where $T$ is the temperature in celsius. 38 39 In SasView the effective radius may be calculated from the parameters 22 40 used in the form factor $P(q)$ that this $S(q)$ is combined with. 23 41 … … 38 56 39 57 .. [#] J B Hayter and J Penfold, *Molecular Physics*, 42 (1981) 109-118 58 40 59 .. [#] J P Hansen and J B Hayter, *Molecular Physics*, 46 (1982) 651-656 60 61 .. [#] M Kotlarchyk and S-H Chen, *J. Chem. Phys.*, 79 (1983) 2461-2469 62 63 .. [#] C G Malmberg and A A Maryott, *J. Res. Nat. Bureau Standards*, 56 (1956) 2641 41 64 42 65 Source … … 50 73 ---------------------------- 51 74 52 * **Author:** 53 * **Last Modified by:** 54 * **Last Reviewed by:** 75 * **Author:** 76 * **Last Modified by:** 77 * **Last Reviewed by:** Steve King **Date:** March 28, 2019 55 78 * **Source added by :** Steve King **Date:** March 25, 2019 56 79 """ … … 74 97 75 98 name = "hayter_msa" 76 title = "Hayter-Penfold rescaled MSA, charged sphere, interparticle S(Q) structure factor"99 title = "Hayter-Penfold Rescaled Mean Spherical Approximation (RMSA) structure factor for charged spheres" 77 100 description = """\ 78 101 [Hayter-Penfold RMSA charged sphere interparticle S(Q) structure factor] 79 Interparticle structure factor S(Q)for a charged hard spheres. 80 Routine takes absolute value of charge, use HardSphere if charge 81 goes to zero. 82 In sasview the effective radius and volume fraction may be calculated 83 from the parameters used in P(Q). 102 Interparticle structure factor S(Q) for charged hard spheres. 103 This routine only works for charged particles! For uncharged particles 104 use the hardsphere S(q) instead. The "beta(q)" correction is available 105 in versions 4.2.2 and higher. 84 106 """ 85 107 … … 87 109 # pylint: disable=bad-whitespace, line-too-long 88 110 # [ "name", "units", default, [lower, upper], "type", "description" ], 111 # 112 # NOTE: SMK, 28Mar19 The upper limit for charge is set to 200 to avoid instabilities noted by PK in 113 # Ticket #1152. Also see the thread in Ticket 859. The docs above also note that charge=0 will 114 # cause problems, yet the default parameters allowed it! After discussions with PK I have 115 # changed it to (an arbitarily) small but non-zero value. But I haven't changed the low limit 116 # in function random() below. 117 # 89 118 parameters = [ 90 119 ["radius_effective", "Ang", 20.75, [0, inf], "volume", "effective radius of charged sphere"], 91 120 ["volfraction", "None", 0.0192, [0, 0.74], "", "volume fraction of spheres"], 92 ["charge", "e", 19.0, [0 , 200], "", "charge on sphere (in electrons)"],121 ["charge", "e", 19.0, [0.000001, 200], "", "charge on sphere (in electrons)"], 93 122 ["temperature", "K", 318.16, [0, 450], "", "temperature, in Kelvin, for Debye length calculation"], 94 123 ["concentration_salt", "M", 0.0, [0, inf], "", "conc of salt, moles/litre, 1:1 electolyte, for Debye length"], 95 ["dielectconst", "None", 71.08, [-inf, inf], "", "dielectric constant (relative permittivity) of solvent, default water, for Debye length"]124 ["dielectconst", "None", 71.08, [-inf, inf], "", "dielectric constant (relative permittivity) of solvent, kappa, default water, for Debye length"] 96 125 ] 97 126 # pylint: enable=bad-whitespace, line-too-long -
sasmodels/models/hollow_cylinder.c
r99658f6 ra34b811 34 34 35 35 static double 36 effective_radius(int mode, double radius, double thickness, double length)36 radius_effective(int mode, double radius, double thickness, double length) 37 37 { 38 38 switch (mode) { -
sasmodels/models/hollow_cylinder.py
r0507e09 ra34b811 110 110 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "hollow_cylinder.c"] 111 111 have_Fq = True 112 effective_radius_type= [112 radius_effective_modes = [ 113 113 "excluded volume", "equivalent outer volume sphere", 114 114 "outer radius", "half length", -
sasmodels/models/hollow_rectangular_prism.c
r99658f6 ra34b811 30 30 31 31 static double 32 effective_radius(int mode, double length_a, double b2a_ratio, double c2a_ratio, double thickness)32 radius_effective(int mode, double length_a, double b2a_ratio, double c2a_ratio, double thickness) 33 33 // NOTE length_a is external dimension! 34 34 { -
sasmodels/models/hollow_rectangular_prism.py
r0507e09 ra34b811 157 157 source = ["lib/gauss76.c", "hollow_rectangular_prism.c"] 158 158 have_Fq = True 159 effective_radius_type= [159 radius_effective_modes = [ 160 160 "equivalent cylinder excluded volume", "equivalent outer volume sphere", 161 161 "half length_a", "half length_b", "half length_c", -
sasmodels/models/hollow_rectangular_prism_thin_walls.c
r99658f6 ra34b811 26 26 27 27 static double 28 effective_radius(int mode, double length_a, double b2a_ratio, double c2a_ratio)28 radius_effective(int mode, double length_a, double b2a_ratio, double c2a_ratio) 29 29 { 30 30 switch (mode) { -
sasmodels/models/hollow_rectangular_prism_thin_walls.py
r0507e09 ra34b811 117 117 source = ["lib/gauss76.c", "hollow_rectangular_prism_thin_walls.c"] 118 118 have_Fq = True 119 effective_radius_type= [119 radius_effective_modes = [ 120 120 "equivalent cylinder excluded volume", "equivalent outer volume sphere", 121 121 "half length_a", "half length_b", "half length_c", -
sasmodels/models/lib/wrc_cyl.c
r18a2bfc rdb1d9d5 1 1 /* 2 Functions for WRC implementation of flexible cylinders 2 Functions for WRC implementation of flexible cylinders. See 3 W R Chen, P D Butler and L J Magid, 4 Incorporating Intermicellar Interactions in the Fitting of 5 SANS Data from Cationic Wormlike Micelles. 6 Langmuir, 22(15) 2006 6539-6548 3 7 */ 4 8 -
sasmodels/models/mono_gauss_coil.c
r153f8f6 ra34b811 6 6 7 7 static double 8 effective_radius(int mode, double rg)8 radius_effective(int mode, double rg) 9 9 { 10 10 switch (mode) { -
sasmodels/models/mono_gauss_coil.py
r0507e09 ra34b811 59 59 ---------------------------- 60 60 61 * **Author:** 62 * **Last Modified by:** 63 * **Last Reviewed by:** 61 * **Author:** 62 * **Last Modified by:** 63 * **Last Reviewed by:** 64 64 * **Source added by :** Steve King **Date:** March 25, 2019""" 65 65 … … 86 86 source = ["mono_gauss_coil.c"] 87 87 have_Fq = False 88 effective_radius_type= ["R_g", "2R_g", "3R_g", "sqrt(5/3)*R_g"]88 radius_effective_modes = ["R_g", "2R_g", "3R_g", "sqrt(5/3)*R_g"] 89 89 90 90 -
sasmodels/models/multilayer_vesicle.c
ree60aa7 ra34b811 48 48 49 49 static double 50 effective_radius(int mode, double radius, double thick_shell, double thick_solvent, double fp_n_shells)50 radius_effective(int mode, double radius, double thick_shell, double thick_solvent, double fp_n_shells) 51 51 { 52 52 // case 1: outer radius -
sasmodels/models/multilayer_vesicle.py
r0507e09 rdb1d9d5 113 113 * **Converted to sasmodels by:** Piotr Rozyczko **Date:** Feb 24, 2016 114 114 * **Last Modified by:** Paul Kienzle **Date:** Feb 7, 2017 115 * **Last Reviewed by:** Paul Butler **Date:** March 12, 2017115 * **Last Reviewed by:** Steve King **Date:** March 28, 2019 116 116 * **Source added by :** Steve King **Date:** March 25, 2019 117 117 """ … … 121 121 122 122 name = "multilayer_vesicle" 123 title = " P(Q) for a Multi-lamellar vesicle"123 title = "Calculate form factor for a multi-lamellar vesicle" 124 124 description = """ 125 125 multilayer_vesicle model parameters; … … 145 145 ["sld_solvent", "1e-6/Ang^2", 6.4, [-inf, inf], "sld", "solvent scattering length density"], 146 146 ["sld", "1e-6/Ang^2", 0.4, [-inf, inf], "sld", "Shell scattering length density"], 147 ["n_shells", "", 2.0, [1.0, inf], "volume", "Number of shell plus solvent layer pairs "],147 ["n_shells", "", 2.0, [1.0, inf], "volume", "Number of shell plus solvent layer pairs (must be integer)"], 148 148 ] 149 149 # pylint: enable=bad-whitespace, line-too-long … … 154 154 source = ["lib/sas_3j1x_x.c", "multilayer_vesicle.c"] 155 155 have_Fq = True 156 effective_radius_type= ["outer radius"]156 radius_effective_modes = ["outer radius"] 157 157 158 158 def random(): -
sasmodels/models/onion.c
ree60aa7 ra34b811 47 47 48 48 static double 49 effective_radius(int mode, double radius_core, double n_shells, double thickness[])49 radius_effective(int mode, double radius_core, double n_shells, double thickness[]) 50 50 { 51 51 // case 1: outer radius -
sasmodels/models/onion.py
r0507e09 rdb1d9d5 6 6 solvent. We currently provide up to 9 shells with this model. 7 7 8 NB: *radius* represents the core radius $r_0$ and 9 *thickness[k]* represents the thickness of the shell, $r_{k+1} - r_k$. 8 .. note:: 9 10 *radius* represents the core radius $r_0$ and *thickness[k]* represents 11 the thickness of the shell, $r_{k+1} - r_k$. 10 12 11 13 Definition … … 56 58 j_1(x) = \frac{\sin(x)}{x^2} - \frac{\cos(x)}{x} 57 59 58 and the volume is $V(r) = \frac{4\pi}{3}r^3$. The volume of the particle 59 is determined by the radius of the outer shell, so $V_\text{particle} = V(r_N)$. 60 61 Now lets consider the SLD of a shell defined by 60 and the volume is $V(r) = \frac{4\pi}{3}r^3$. 61 62 The volume of the particle is determined by the radius of the outer 63 shell, so $V_\text{particle} = V(r_N)$. 64 65 Now consider the SLD of a shell defined by 62 66 63 67 .. math:: … … 74 78 thickness of the $k^\text{th}$ shell in the equation above, respectively. 75 79 76 For $A > 0$, 80 .. figure:: img/onion_geometry.png 81 82 Example of an onion model profile. 83 84 85 **Exponential SLD profiles** ($A > 0$ or $A < 0$): 77 86 78 87 .. math:: … … 87 96 - 3CV(r_{\text{shell}-1}) \frac{j_1(\beta_\text{in})}{\beta_\text{in}} 88 97 89 for 98 where 90 99 91 100 .. math:: … … 95 104 B&=\frac{\rho_\text{out} - \rho_\text{in}}{e^A-1} 96 105 & C &= \frac{\rho_\text{in}e^A - \rho_\text{out}}{e^A-1} \\ 106 97 107 \alpha_\text{in} &= A\frac{r_{\text{shell}-1}}{\Delta t_\text{shell}} 98 108 & \alpha_\text{out} &= A\frac{r_\text{shell}}{\Delta t_\text{shell}} \\ 109 99 110 \beta_\text{in} &= qr_{\text{shell}-1} 100 111 & \beta_\text{out} &= qr_\text{shell} \\ 101 112 \end{align*} 102 113 103 where $h$ is 114 and 104 115 105 116 .. math:: 106 117 107 h(x,y) = \frac{x \sin(y) - y\cos(y)}{(x^2+y^2)y}118 h(x,y) = \frac{x \sin(y) - y\cos(y)}{(x^2+y^2)y} 108 119 - \frac{(x^2-y^2)\sin(y) - 2xy\cos(y)}{(x^2+y^2)^2y} 109 120 110 121 111 For $A \sim 0$, e.g., $A = -0.0001$, this function converges to that of the 112 linear SLD profile with 113 $\rho_\text{shell}(r) \approx A(r-r_{\text{shell}-1})/\Delta t_\text{shell})+B$, 114 so this case is equivalent to 122 123 **Linear SLD profile** ($A \sim 0$): 124 125 For small $A$, say, $A = -0.0001$, the function converges to that of of a linear 126 SLD profile with 127 128 $\rho_\text{shell}(r) \approx A(r-r_{\text{shell}-1})/\Delta t_\text{shell})+B$, 129 130 which is equivalent to 115 131 116 132 .. math:: … … 140 156 \end{align*} 141 157 142 For $A = 0$, the exponential function has no dependence on the radius (so that 158 159 **Constant SLD** ($A = 0$): 160 161 When $A = 0$ the exponential function has no dependence on the radius (meaning 143 162 $\rho_\text{out}$ is ignored in this case) and becomes flat. We set the constant 144 163 to $\rho_\text{in}$ for convenience, and thus the form factor contributed by … … 153 172 \frac{j_1(qr_\text{in})}{qr_\text{in}} 154 173 155 .. figure:: img/onion_geometry.png156 157 Example of an onion model profile.158 159 174 The 2D scattering intensity is the same as $P(q)$ above, regardless of the 160 175 orientation of the $q$ vector which is defined as … … 182 197 ---------------------------- 183 198 184 * **Author:** 185 * **Last Modified by:** 186 * **Last Reviewed by:** 199 * **Author:** 200 * **Last Modified by:** 201 * **Last Reviewed by:** Steve King **Date:** March 28, 2019 187 202 * **Source added by :** Steve King **Date:** March 25, 2019 188 203 """ … … 284 299 285 300 description = """\ 286 Form factor of mu tishells normalized by the volume. Here each shell is301 Form factor of multishells normalized by the volume. Here each shell is 287 302 described by an exponential function; 288 303 … … 297 312 II) For the exact point of A_shell == 0, 298 313 f(r) = sld_in ,i.e., it crosses over flat function 299 Note that the 'sld_out' bec aomes NULL in this case.314 Note that the 'sld_out' becomes NULL in this case. 300 315 301 316 background:background, … … 312 327 # TODO: n is a volume parameter that is not polydisperse 313 328 329 # NOTE: Joachim Wuttke has suggested an alternative parameterisation 330 # in Ticket #1107 331 314 332 # pylint: disable=bad-whitespace, line-too-long 315 333 # ["name", "units", default, [lower, upper], "type","description"], … … 318 336 ["radius_core", "Ang", 200., [0, inf], "volume", "Radius of the core"], 319 337 ["sld_solvent", "1e-6/Ang^2", 6.4, [-inf, inf], "sld", "Solvent scattering length density"], 320 ["n_shells", "", 1, [0, 10], "volume", "number of shells "],338 ["n_shells", "", 1, [0, 10], "volume", "number of shells (must be integer)"], 321 339 ["sld_in[n_shells]", "1e-6/Ang^2", 1.7, [-inf, inf], "sld", "scattering length density at the inner radius of shell k"], 322 340 ["sld_out[n_shells]", "1e-6/Ang^2", 2.0, [-inf, inf], "sld", "scattering length density at the outer radius of shell k"], … … 329 347 single = False 330 348 have_Fq = True 331 effective_radius_type= ["outer radius"]349 radius_effective_modes = ["outer radius"] 332 350 333 351 profile_axes = ['Radius (A)', 'SLD (1e-6/A^2)'] -
sasmodels/models/parallelepiped.c
r99658f6 ra34b811 37 37 38 38 static double 39 effective_radius(int mode, double length_a, double length_b, double length_c)39 radius_effective(int mode, double length_a, double length_b, double length_c) 40 40 { 41 41 switch (mode) { -
sasmodels/models/parallelepiped.py
r0507e09 ra34b811 240 240 source = ["lib/gauss76.c", "parallelepiped.c"] 241 241 have_Fq = True 242 effective_radius_type= [242 radius_effective_modes = [ 243 243 "equivalent cylinder excluded volume", "equivalent volume sphere", 244 244 "half length_a", "half length_b", "half length_c", -
sasmodels/models/pearl_necklace.c
r4453136 ra34b811 86 86 87 87 static double 88 effective_radius(int mode, double radius, double edge_sep, double thick_string, double fp_num_pearls)88 radius_effective(int mode, double radius, double edge_sep, double thick_string, double fp_num_pearls) 89 89 { 90 90 switch (mode) { -
sasmodels/models/pearl_necklace.py
r0507e09 rdb1d9d5 25 25 .. math:: 26 26 27 S_{ss}(q) &= sm_s^2\psi^2(q)[\frac{N}{1-sin(qA)/qA}-\frac{N}{2}-28 \frac{1-(sin(qA)/qA)^N}{(1-sin(qA)/qA)^2}\cdot\frac{sin(qA)}{qA} ] \\29 S_{ff}(q) &= sm_r^2[M\{2\Lambda(q)-(\frac{sin(ql/2)}{ql/2})\}+27 S_{ss}(q) &= 2m_s^2\psi^2(q)\left[\frac{N}{1-sin(qA)/qA}-\frac{N}{2}- 28 \frac{1-(sin(qA)/qA)^N}{(1-sin(qA)/qA)^2}\cdot\frac{sin(qA)}{qA}\right] \\ 29 S_{ff}(q) &= m_r^2\left[M\left\{2\Lambda(q)-\left(\frac{sin(ql/2)}{ql/2}\right)\right\}+ 30 30 \frac{2M\beta^2(q)}{1-sin(qA)/qA}-2\beta^2(q)\cdot 31 \frac{1-(sin(qA)/qA)^M}{(1-sin(qA)/qA)^2} ] \\32 S_{fs}(q) &= m_r \beta (q) \cdot m_s \psi (q) \cdot 4 [31 \frac{1-(sin(qA)/qA)^M}{(1-sin(qA)/qA)^2}\right] \\ 32 S_{fs}(q) &= m_r \beta (q) \cdot m_s \psi (q) \cdot 4\left[ 33 33 \frac{N-1}{1-sin(qA)/qA}-\frac{1-(sin(qA)/qA)^{N-1}}{(1-sin(qA)/qA)^2} 34 \cdot \frac{sin(qA)}{qA} ] \\34 \cdot \frac{sin(qA)}{qA}\right] \\ 35 35 \psi(q) &= 3 \cdot \frac{sin(qR)-(qR)\cdot cos(qR)}{(qR)^3} \\ 36 36 \Lambda(q) &= \frac{\int_0^{ql}\frac{sin(t)}{t}dt}{ql} \\ … … 40 40 (volume of the *N* pearls/rods). *V* is the total volume of the necklace. 41 41 42 .. note:: 43 44 *num_pearls* must be an integer. 45 42 46 The 2D scattering intensity is the same as $P(q)$ above, regardless of the 43 47 orientation of the *q* vector. 44 45 The returned value is scaled to units of |cm^-1| and the parameters of the46 pearl_necklace model are the following47 48 NB: *num_pearls* must be an integer.49 48 50 49 References … … 52 51 53 52 .. [#] R Schweins and K Huber, *Particle Scattering Factor of Pearl Necklace Chains*, 54 *Macromol. Symp.* 211 (2004) 25-42 2004 53 *Macromol. Symp.* 211 (2004) 25-42 2004 54 55 55 .. [#] L. Onsager, *Ann. New York Acad. Sci.*, 51 (1949) 627-659 56 56 … … 65 65 ---------------------------- 66 66 67 * **Author:** 68 * **Last Modified by:** 69 * **Last Reviewed by:** 67 * **Author:** 68 * **Last Modified by:** Andrew Jackson **Date:** March 28, 2019 69 * **Last Reviewed by:** Steve King **Date:** March 28, 2019 70 70 * **Source added by :** Steve King **Date:** March 25, 2019 71 71 """ … … 111 111 source = ["lib/sas_Si.c", "lib/sas_3j1x_x.c", "pearl_necklace.c"] 112 112 single = False # use double precision unless told otherwise 113 effective_radius_type= ["equivalent volume sphere"]113 radius_effective_modes = ["equivalent volume sphere"] 114 114 115 115 def random(): -
sasmodels/models/poly_gauss_coil.py
r0507e09 ra34b811 58 58 ---------------------------- 59 59 60 * **Author:** 61 * **Last Modified by:** 62 * **Last Reviewed by:** 60 * **Author:** 61 * **Last Modified by:** 62 * **Last Reviewed by:** 63 63 * **Source added by :** Steve King **Date:** March 25, 2019 64 64 """ -
sasmodels/models/pringle.c
r99658f6 ra34b811 111 111 112 112 static double 113 effective_radius(int mode, double radius, double thickness, double alpha, double beta)113 radius_effective(int mode, double radius, double thickness, double alpha, double beta) 114 114 { 115 115 switch (mode) { -
sasmodels/models/pringle.py
r0507e09 ra34b811 85 85 source = ["lib/polevl.c", "lib/sas_J0.c", "lib/sas_J1.c", 86 86 "lib/sas_JN.c", "lib/gauss76.c", "pringle.c"] 87 effective_radius_type= [87 radius_effective_modes = [ 88 88 "equivalent cylinder excluded volume", 89 89 "equivalent volume sphere", -
sasmodels/models/raspberry.c
rd42dd4a ra34b811 15 15 16 16 static double 17 effective_radius(int mode, double radius_lg, double radius_sm, double penetration)17 radius_effective(int mode, double radius_lg, double radius_sm, double penetration) 18 18 { 19 19 switch (mode) { -
sasmodels/models/raspberry.py
r0507e09 ra34b811 161 161 162 162 source = ["lib/sas_3j1x_x.c", "raspberry.c"] 163 effective_radius_type= ["radius_large", "radius_outer"]163 radius_effective_modes = ["radius_large", "radius_outer"] 164 164 165 165 def random(): -
sasmodels/models/rectangular_prism.c
r99658f6 ra34b811 14 14 15 15 static double 16 effective_radius(int mode, double length_a, double b2a_ratio, double c2a_ratio)16 radius_effective(int mode, double length_a, double b2a_ratio, double c2a_ratio) 17 17 { 18 18 switch (mode) { -
sasmodels/models/rectangular_prism.py
r0507e09 ra34b811 110 110 ---------------------------- 111 111 112 * **Author:** 113 * **Last Modified by:** 114 * **Last Reviewed by:** 112 * **Author:** 113 * **Last Modified by:** 114 * **Last Reviewed by:** 115 115 * **Source added by :** Steve King **Date:** March 25, 2019 116 116 """ … … 151 151 source = ["lib/gauss76.c", "rectangular_prism.c"] 152 152 have_Fq = True 153 effective_radius_type= [153 radius_effective_modes = [ 154 154 "equivalent cylinder excluded volume", "equivalent volume sphere", 155 155 "half length_a", "half length_b", "half length_c", -
sasmodels/models/rpa.py
r0507e09 rdb1d9d5 30 30 These case numbers are different from those in the NIST SANS package! 31 31 32 The models are based on the papers by Akcasu *et al.* and by33 Hammouda assuming the polymer follows Gaussian statistics such32 The models are based on the papers by Akcasu *et al.* [1] and by 33 Hammouda [2] assuming the polymer follows Gaussian statistics such 34 34 that $R_g^2 = n b^2/6$ where $b$ is the statistical segment length and $n$ is 35 35 the number of statistical segment lengths. A nice tutorial on how these are 36 constructed and implemented can be found in chapters 28 and 39 of Boualem37 Hammouda's 'SANS Toolbox'.36 constructed and implemented can be found in chapters 28, 31 and 34, and Part H, 37 of Hammouda's 'SANS Toolbox' [3]. 38 38 39 In brief the macroscopic cross sections are derived from the general forms40 for homopolymer scattering and the multiblock cross-terms while the inter 39 In brief, the macroscopic cross sections are derived from the general forms 40 for homopolymer scattering and the multiblock cross-terms while the inter, 41 41 polymer cross terms are described in the usual way by the $\chi$ parameter. 42 42 … … 48 48 * **Component D is assumed to be the "background" component (ie, all contrasts 49 49 are calculated with respect to component D).** So the scattering contrast 50 for a C/D blend = [SLD(component C) - SLD(component D)]\ :sup:`2`.50 for a C/D blend $\rho_{C/D} = [\rho_C - \rho_D]$\ :sup:`2`. 51 51 * Depending on which case is being used, the number of fitting parameters can 52 52 vary. … … 80 80 * **Converted to sasmodels by:** Paul Kienzle **Date:** July 18, 2016 81 81 * **Last Modified by:** Paul Butler **Date:** March 12, 2017 82 * **Last Reviewed by:** Paul Butler **Date:** March 12, 201782 * **Last Reviewed by:** Steve King **Date:** March 27, 2019 83 83 * **Source added by :** Steve King **Date:** March 25, 2019 84 84 """ -
sasmodels/models/sphere.c
ree60aa7 ra34b811 5 5 6 6 static double 7 effective_radius(int mode, double radius)7 radius_effective(int mode, double radius) 8 8 { 9 9 // case 1: radius -
sasmodels/models/sphere.py
r0507e09 r934a001 36 36 References 37 37 ---------- 38 39 .. [#] A Guinier and G. Fournet, *Small-Angle Scattering of X-Rays*, John Wiley and Sons, New York, (1955) 38 39 .. [#] A Guinier and G. Fournet, *Small-Angle Scattering of X-Rays*, 40 John Wiley and Sons, New York, (1955) 40 41 41 42 Source … … 49 50 ---------------------------- 50 51 51 * **Author:** 52 * **Last Modified by:** 52 * **Author:** 53 * **Last Modified by:** 53 54 * **Last Reviewed by:** S King and P Parker **Date:** 2013/09/09 and 2014/01/06 54 55 * **Source added by :** Steve King **Date:** March 25, 2019 … … 81 82 source = ["lib/sas_3j1x_x.c", "sphere.c"] 82 83 have_Fq = True 83 effective_radius_type= ["radius"]84 radius_effective_modes = ["radius"] 84 85 85 86 def random(): … … 90 91 ) 91 92 return pars 92 93 #2345678901234567890123456789012345678901234567890123456789012345678901234567890 93 94 tests = [ 94 [{}, 0.2, 0.726362], 95 [{}, 0.2, 0.726362], # each test starts with default parameter values 96 # inside { }, unless modified. Then Q and expected value of I(Q) 97 # putting None for an expected result will pass the test if there are no 98 # errors from the routine, but without any check on the value of the result 95 99 [{"scale": 1., "background": 0., "sld": 6., "sld_solvent": 1., 96 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 97 0.2, 0.228843], 100 "radius": 120.}, [0.01,0.1,0.2], 101 [1.34836265e+04, 6.20114062e+00, 1.04733914e-01]], 102 [{"scale": 1., "background": 0., "sld": 6., "sld_solvent": 1., 103 # careful tests here R=120 Pd=.2, then with S(Q) at default Reff=50 104 # (but this gets changed to 120) phi=0,2 105 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 106 [0.01,0.1,0.2], [1.74395295e+04, 3.68016987e+00, 2.28843099e-01]], 107 # a list of Q values and list of expected results is also possible 108 [{"scale": 1., "background": 0., "sld": 6., "sld_solvent": 1., 109 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 110 0.01, 335839.88055473, 1.41045057e+11, 120.0, 8087664.122641933, 1.0], 111 # the longer list here checks F1, F2, R_eff, volume, volume_ratio 98 112 [{"radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 99 0.1, None, None, 120., None, 1.0], 100 [{"@S": "hardsphere"}, 0.1, None], 113 0.1, 482.93824329, 29763977.79867414, 120.0, 8087664.122641933, 1.0], 114 [{"radius": 120., "radius_pd": 0.2, "radius_pd_n":45}, 115 0.2, 1.23330406, 1850806.1197361, 120.0, 8087664.122641933, 1.0], 116 # But note P(Q) = F2/volume 117 # F and F^2 are "unscaled", with for n <F F*>S(q) or for beta approx 118 # I(q) = n [<F F*> + <F><F*> (S(q) - 1)] 119 # for n the number density and <.> the orientation average, and 120 # F = integral rho(r) exp(i q . r) dr. 121 # The number density is volume fraction divided by particle volume. 122 # Effectively, this leaves F = V drho form, where form is the usual 123 # 3 j1(qr)/(qr) or whatever depending on the shape. 124 # @S RESULTS using F1 and F2 from the longer test strng above: 125 # 126 # I(Q) = (F2 + F1^2*(S(Q) -1))*volfraction*scale/Volume + background 127 # 128 # with by default scale=1.0, background=0.001 129 # NOTE currently S(Q) volfraction is also included in scaling 130 # structure_factor_mode 0 = normal decoupling approx, 131 # 1 = beta(Q) approx 132 # radius_effective_mode 0 is for free choice, 133 # 1 is use radius from F2(Q) 134 # (sphere only has two choices, other models may have more) 135 [{"@S": "hardsphere", 136 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45,"volfraction":0.2, 137 #"radius_effective":50.0, # hard sphere structure factor 138 "structure_factor_mode": 1, # mode 0 = normal decoupling approx, 139 # 1 = beta(Q) approx 140 "radius_effective_mode": 0 # this used default hardsphere Reff=50 141 }, [0.01,0.1,0.2], [1.32473756e+03, 7.36633631e-01, 4.67686201e-02] ], 142 [{"@S": "hardsphere", 143 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45, 144 "volfraction":0.2, 145 "radius_effective":45.0, # explicit Reff over rides either 50 or 120 146 "structure_factor_mode": 1, # beta approx 147 "radius_effective_mode": 0 # 148 }, 0.01, 1316.2990966463444 ], 149 [{"@S": "hardsphere", 150 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45, 151 "volfraction":0.2, 152 "radius_effective":120.0, # over ride Reff 153 "structure_factor_mode": 1, # beta approx 154 "radius_effective_mode": 0 # (mode=1 here also uses 120) 155 }, [0.01,0.1,0.2], [1.57928589e+03, 7.37067923e-01, 4.67686197e-02 ]], 156 [{"@S": "hardsphere", 157 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45, 158 "volfraction":0.2, 159 #"radius_effective":120.0, # hard sphere structure factor 160 "structure_factor_mode": 0, # normal decoupling approximation 161 "radius_effective_mode": 1 # this uses 120 from the form factor 162 }, [0.01,0.1,0.2], [1.10112335e+03, 7.41366536e-01, 4.66630207e-02]], 163 [{"@S": "hardsphere", 164 "radius": 120., "radius_pd": 0.2, "radius_pd_n":45, 165 "volfraction":0.2, 166 #"radius_effective":50.0, # hard sphere structure factor 167 "structure_factor_mode": 0, # normal decoupling approximation 168 "radius_effective_mode": 0 # this used 50 the default for hardsphere 169 }, [0.01,0.1,0.2], [7.82803598e+02, 6.85943611e-01, 4.71586457e-02 ]] 101 170 ] 171 # -
sasmodels/models/spherical_sld.c
ree60aa7 ra34b811 19 19 20 20 static double 21 effective_radius(int mode, double fp_n_shells, double thickness[], double interface[])21 radius_effective(int mode, double fp_n_shells, double thickness[], double interface[]) 22 22 { 23 23 // case 1: outer radius -
sasmodels/models/spherical_sld.py
r0507e09 r627b68b 18 18 sub-shell is described by a line function, with *n_steps* sub-shells per 19 19 interface. The form factor is normalized by the total volume of the sphere. 20 21 .. note:: 22 23 *n_shells* must be an integer. *n_steps* must be an ODD integer. 20 24 21 25 Interface shapes are as follows: … … 73 77 3 \rho_\text{solvent} V(r_N) 74 78 \Big[ \frac{\sin(qr_N) - qr_N \cos(qr_N)} {qr_N^3} \Big] 75 76 79 77 80 Here we assumed that the SLDs of the core and solvent are constant in $r$. … … 156 159 \end{align*} 157 160 158 159 161 We assume $\rho_{\text{inter}_j} (r)$ is approximately linear 160 162 within the sub-shell $j$. … … 179 181 when $P(Q) * S(Q)$ is applied. 180 182 181 182 183 References 183 184 ---------- … … 194 195 195 196 Authorship and Verification 196 --------------------------- -197 --------------------------- 197 198 198 199 * **Author:** Jae-Hie Cho **Date:** Nov 1, 2010 199 200 * **Last Modified by:** Paul Kienzle **Date:** Dec 20, 2016 200 * **Last Reviewed by:** Paul Butler **Date:** September 8, 2018201 * **Last Reviewed by:** Steve King **Date:** March 29, 2019 201 202 * **Source added by :** Steve King **Date:** March 25, 2019 202 203 """ … … 207 208 208 209 name = "spherical_sld" 209 title = "Sp erical SLD intensity calculation"210 title = "Spherical SLD intensity calculation" 210 211 description = """ 211 212 I(q) = … … 219 220 # pylint: disable=bad-whitespace, line-too-long 220 221 # ["name", "units", default, [lower, upper], "type", "description"], 221 parameters = [["n_shells", "", 1, [1, 10], "volume", "number of shells "],222 parameters = [["n_shells", "", 1, [1, 10], "volume", "number of shells (must be integer)"], 222 223 ["sld_solvent", "1e-6/Ang^2", 1.0, [-inf, inf], "sld", "solvent sld"], 223 224 ["sld[n_shells]", "1e-6/Ang^2", 4.06, [-inf, inf], "sld", "sld of the shell"], … … 232 233 single = False # TODO: fix low q behaviour 233 234 have_Fq = True 234 effective_radius_type= ["outer radius"]235 radius_effective_modes = ["outer radius"] 235 236 236 237 profile_axes = ['Radius (A)', 'SLD (1e-6/A^2)'] -
sasmodels/models/squarewell.py
r0507e09 r4d00de6 1 1 # Note: model title and parameter table are inserted automatically 2 2 r""" 3 This calculates the interparticle structure factor for a square wellfluid4 spherical particles. The mean spherical approximation (MSA) closure was 5 used for this calculation, and is not the most appropriate closure for 6 a n attractive interparticle potential. This solution has been compared7 t o Monte Carlo simulations for a square well fluid, showing this calculation8 to be limited in applicability to well depths $\epsilon < 1.5$ kT and 9 volume fractions $\phi < 0.08$.3 Calculates the interparticle structure factor for a hard sphere fluid 4 with a narrow, attractive, square well potential. **The Mean Spherical 5 Approximation (MSA) closure relationship is used, but it is not the most 6 appropriate closure for an attractive interparticle potential.** However, 7 the solution has been compared to Monte Carlo simulations for a square 8 well fluid and these show the MSA calculation to be limited to well 9 depths $\epsilon < 1.5$ kT and volume fractions $\phi < 0.08$. 10 10 11 11 Positive well depths correspond to an attractive potential well. Negative 12 12 well depths correspond to a potential "shoulder", which may or may not be 13 physically reasonable. The stickyhardsphere model may be a better choice in 14 some circumstances. Computed values may behave badly at extremely small $qR$. 13 physically reasonable. The :ref:`stickyhardsphere` model may be a better 14 choice in some circumstances. 15 16 Computed values may behave badly at extremely small $qR$. 17 18 .. note:: 19 20 Earlier versions of SasView did not incorporate the so-called 21 $\beta(q)$ ("beta") correction [2] for polydispersity and non-sphericity. 22 This is only available in SasView versions 5.0 and higher. 15 23 16 24 The well width $(\lambda)$ is defined as multiples of the particle diameter … … 18 26 19 27 The interaction potential is: 20 21 .. image:: img/squarewell.png22 28 23 29 .. math:: … … 29 35 \end{cases} 30 36 31 where $r$ is the distance from the center of thesphere of a radius $R$.37 where $r$ is the distance from the center of a sphere of a radius $R$. 32 38 33 In sasview the effective radius may be calculated from the parameters39 In SasView the effective radius may be calculated from the parameters 34 40 used in the form factor $P(q)$ that this $S(q)$ is combined with. 35 41 … … 46 52 .. [#] R V Sharma, K C Sharma, *Physica*, 89A (1977) 213 47 53 54 .. [#] M Kotlarchyk and S-H Chen, *J. Chem. Phys.*, 79 (1983) 2461-2469 55 48 56 Source 49 57 ------ … … 54 62 ---------------------------- 55 63 56 * **Author:** 57 * **Last Modified by:** 58 * **Last Reviewed by:** 64 * **Author:** 65 * **Last Modified by:** 66 * **Last Reviewed by:** Steve King **Date:** March 27, 2019 59 67 * **Source added by :** Steve King **Date:** March 25, 2019 60 68 """ … … 64 72 65 73 name = "squarewell" 66 title = "Square well structure factor , with MSAclosure"74 title = "Square well structure factor with Mean Spherical Approximation closure" 67 75 description = """\ 68 76 [Square well structure factor, with MSA closure] 69 Interparticle structure factor S(Q) for a hard sphere fluid with70 a narrow attractive well. Fits are prone to deliver non-physical71 parameters, use with care and read the references in the full manual.72 In sasview the effective radius will be calculated from the73 parameters used in P(Q).77 Interparticle structure factor S(Q) for a hard sphere fluid 78 with a narrow attractive well. Fits are prone to deliver non- 79 physical parameters; use with care and read the references in 80 the model documentation.The "beta(q)" correction is available 81 in versions 4.2.2 and higher. 74 82 """ 75 83 category = "structure-factor" -
sasmodels/models/stickyhardsphere.py
r0507e09 r4d00de6 1 1 # Note: model title and parameter table are inserted automatically 2 2 r""" 3 This calculates the interparticle structure factor for a hard sphere fluid4 with a narrow attractive well. A perturbative solution of the Percus-Yevick5 closure is used. The strength of the attractive well is described in terms 6 of "stickiness" as defined below. 7 8 The perturb (perturbation parameter), $\epsilon$, should be held between 0.01 9 and 0.1. It is best to hold the perturbation parameter fixed and let 10 the "stickiness" vary to adjust the interaction strength. The stickiness, 11 $\tau$, is defined in the equation below and is a function of both the 12 perturbation parameter and the interaction strength. $\tau$ and $\epsilon$ 13 are defined in terms of the hard sphere diameter $(\sigma = 2 R)$, the 14 width of the square well, $\Delta$ (same units as $R$\ ), and the depth of 15 the well, $U_o$, in units of $kT$. From the definition, it is clear that16 smaller $\tau$ meansstronger attraction.3 Calculates the interparticle structure factor for a hard sphere fluid 4 with a narrow, attractive, potential well. Unlike the :ref:`squarewell` 5 model, here a perturbative solution of the Percus-Yevick closure 6 relationship is used. The strength of the attractive well is described 7 in terms of "stickiness" as defined below. 8 9 The perturbation parameter (perturb), $\tau$, should be fixed between 0.01 10 and 0.1 and the "stickiness", $\epsilon$, allowed to vary to adjust the 11 interaction strength. The "stickiness" is defined in the equation below and is 12 a function of both the perturbation parameter and the interaction strength. 13 $\epsilon$ and $\tau$ are defined in terms of the hard sphere diameter $(\sigma = 2 R)$, 14 the width of the square well, $\Delta$ (having the same units as $R$\ ), 15 and the depth of the well, $U_o$, in units of $kT$. From the definition, it 16 is clear that smaller $\epsilon$ means a stronger attraction. 17 17 18 18 .. math:: 19 19 20 \ tau &= \frac{1}{12\epsilon} \exp(u_o / kT) \\21 \ epsilon&= \Delta / (\sigma + \Delta)20 \epsilon &= \frac{1}{12\tau} \exp(u_o / kT) \\ 21 \tau &= \Delta / (\sigma + \Delta) 22 22 23 23 where the interaction potential is … … 31 31 \end{cases} 32 32 33 The Percus-Yevick (PY) closure was used for this calculation, and is an34 adequate closure for an attractive interparticle potential. Th issolution33 The Percus-Yevick (PY) closure is used for this calculation, and is an 34 adequate closure for an attractive interparticle potential. The solution 35 35 has been compared to Monte Carlo simulations for a square well fluid, with 36 36 good agreement. 37 37 38 The true particle volume fraction, $\phi$, is not equal to $h$, which appears 39 in most of the reference. The two are related in equation (24) of the 40 reference. The reference also describes the relationship between this 41 perturbation solution and the original sticky hard sphere (or adhesive 42 sphere) model by Baxter. 43 44 **NB**: The calculation can go haywire for certain combinations of the input 45 parameters, producing unphysical solutions - in this case errors are 46 reported to the command window and the $S(q)$ is set to -1 (so it will 47 disappear on a log-log plot). Use tight bounds to keep the parameters to 48 values that you know are physical (test them) and keep nudging them until 49 the optimization does not hit the constraints. 50 51 In sasview the effective radius may be calculated from the parameters 38 The true particle volume fraction, $\phi$, is not equal to $h$ which appears 39 in most of reference [1]. The two are related in equation (24). Reference 40 [1] also describes the relationship between this perturbative solution and 41 the original sticky hard sphere (or "adhesive sphere") model of Baxter [2]. 42 43 .. note:: 44 45 The calculation can go haywire for certain combinations of the input 46 parameters, producing unphysical solutions. In this case errors are 47 reported to the command window and $S(q)$ is set to -1 (so it will 48 disappear on a log-log plot!). 49 50 Use tight bounds to keep the parameters to values that you know are 51 physical (test them), and keep nudging them until the optimization 52 does not hit the constraints. 53 54 .. note:: 55 56 Earlier versions of SasView did not incorporate the so-called 57 $\beta(q)$ ("beta") correction [3] for polydispersity and non-sphericity. 58 This is only available in SasView versions 5.0 and higher. 59 60 In SasView the effective radius may be calculated from the parameters 52 61 used in the form factor $P(q)$ that this $S(q)$ is combined with. 53 62 … … 65 74 .. [#] S V G Menon, C Manohar, and K S Rao, *J. Chem. Phys.*, 95(12) (1991) 9186-9190 66 75 76 .. [#] R J Baxter, *J. Chem. Phys.*, 49 (1968), 2770-2774 77 78 .. [#] M Kotlarchyk and S-H Chen, *J. Chem. Phys.*, 79 (1983) 2461-2469 79 67 80 Source 68 81 ------ … … 73 86 ---------------------------- 74 87 75 * **Author:** 76 * **Last Modified by:** 77 * **Last Reviewed by:** 88 * **Author:** 89 * **Last Modified by:** 90 * **Last Reviewed by:** Steve King **Date:** March 27, 2019 78 91 * **Source added by :** Steve King **Date:** March 25, 2019 79 92 """ … … 85 98 86 99 name = "stickyhardsphere" 87 title = " Sticky hard sphere structure factor,with Percus-Yevick closure"100 title = "'Sticky' hard sphere structure factor with Percus-Yevick closure" 88 101 description = """\ 89 102 [Sticky hard sphere structure factor, with Percus-Yevick closure] 90 Interparticle structure factor S(Q) for a hard sphere fluid with91 a narrow attractive well. Fits are prone to deliver non-physical92 parameters, use with care and read the references in the full manual.93 In sasview the effective radius will be calculated from the94 parameters used in P(Q).103 Interparticle structure factor S(Q) for a hard sphere fluid 104 with a narrow attractive well. Fits are prone to deliver non- 105 physical parameters; use with care and read the references in 106 the model documentation.The "beta(q)" correction is available 107 in versions 4.2.2 and higher. 95 108 """ 96 109 category = "structure-factor" … … 107 120 "volume fraction of hard spheres"], 108 121 ["perturb", "", 0.05, [0.01, 0.1], "", 109 "perturbation parameter, epsilon"],122 "perturbation parameter, tau"], 110 123 ["stickiness", "", 0.20, [-inf, inf], "", 111 "stickiness, tau"],124 "stickiness, epsilon"], 112 125 ] 113 126 -
sasmodels/models/triaxial_ellipsoid.c
r99658f6 ra34b811 76 76 77 77 static double 78 effective_radius(int mode, double radius_equat_minor, double radius_equat_major, double radius_polar)78 radius_effective(int mode, double radius_equat_minor, double radius_equat_major, double radius_polar) 79 79 { 80 80 switch (mode) { -
sasmodels/models/triaxial_ellipsoid.py
r0507e09 ra34b811 164 164 source = ["lib/sas_3j1x_x.c", "lib/gauss76.c", "triaxial_ellipsoid.c"] 165 165 have_Fq = True 166 effective_radius_type= [166 radius_effective_modes = [ 167 167 "equivalent biaxial ellipsoid average curvature", 168 168 "equivalent volume sphere", "min radius", "max radius", -
sasmodels/models/unified_power_Rg.py
r0507e09 rb606805 22 22 artefacts that appear as kinks in the fitted model function. 23 23 24 Also see the Guinier_Porodmodel.24 Also see the :ref:`guinier-porod` model. 25 25 26 26 The empirical fit function is: -
sasmodels/models/vesicle.c
r12f4c19 ra34b811 13 13 14 14 static double 15 effective_radius(int mode, double radius, double thickness)15 radius_effective(int mode, double radius, double thickness) 16 16 { 17 17 // case 1: outer radius -
sasmodels/models/vesicle.py
r0507e09 ra34b811 107 107 source = ["lib/sas_3j1x_x.c", "vesicle.c"] 108 108 have_Fq = True 109 effective_radius_type= ["outer radius"]109 radius_effective_modes = ["outer radius"] 110 110 111 111 def random(): -
sasmodels/product.py
rb297ba9 r065d77d 31 31 # pylint: enable=unused-import 32 32 33 # TODO: make estimates available to constraints33 # TODO: make shape averages available to constraints 34 34 #ESTIMATED_PARAMETERS = [ 35 # ["est_radius_effective", "A", 0.0, [0, np.inf], "", "Estimated effective radius"], 36 # ["est_volume_ratio", "", 1.0, [0, np.inf], "", "Estimated volume ratio"], 35 # ["mean_radius_effective", "A", 0.0, [0, np.inf], "", "mean effective radius"], 36 # ["mean_volume", "A", 0.0, [0, np.inf], "", "mean volume"], 37 # ["mean_volume_ratio", "", 1.0, [0, np.inf], "", "mean form: mean shell volume ratio"], 37 38 #] 38 39 39 STRUCTURE_MODE_ID = "structure_factor_mode" 40 40 RADIUS_MODE_ID = "radius_effective_mode" … … 44 44 # type: (ModelInfo) -> List[Parameter] 45 45 """ 46 Create parameters for structure _factor_mode and radius_effective_mode.46 Create parameters for structure factor and effective radius modes. 47 47 """ 48 48 pars = [] … … 56 56 "Structure factor calculation") 57 57 pars.append(par) 58 if p_info. effective_radius_typeis not None:58 if p_info.radius_effective_modes is not None: 59 59 par = parse_parameter( 60 60 RADIUS_MODE_ID, 61 61 "", 62 62 1, 63 [["unconstrained"] + p_info. effective_radius_type],63 [["unconstrained"] + p_info.radius_effective_modes], 64 64 "", 65 65 "Effective radius calculation") … … 177 177 S, # type: np.ndarray 178 178 scale, # type: float 179 effective_radius, # type: float179 radius_effective, # type: float 180 180 beta_mode, # type: bool 181 181 ): … … 185 185 The result may be an array or a float. 186 186 """ 187 # CRUFT: remove effective_radius once SasView 5.0 is released. 187 188 if beta_mode: 188 189 # TODO: 1. include calculated Q vector … … 193 194 ("beta(Q)", F1**2 / F2), 194 195 ("S_eff(Q)", 1 + (F1**2 / F2)*(S-1)), 195 ("effective_radius", effective_radius), 196 ("effective_radius", radius_effective), 197 ("radius_effective", radius_effective), 196 198 # ("I(Q)", scale*(F2 + (F1**2)*(S-1)) + bg), 197 199 )) … … 200 202 ("P(Q)", scale*F2), 201 203 ("S(Q)", S), 202 ("effective_radius", effective_radius), 204 ("effective_radius", radius_effective), 205 ("radius_effective", radius_effective), 203 206 )) 204 207 return parts … … 281 284 # R_eff type parameter is the second parameter after P and S parameters 282 285 # unless the model doesn't support beta mode, in which case it is first 283 have_radius_type = p_info.effective_radius_type is not None 286 have_radius_type = p_info.radius_effective_modes is not None 287 #print(p_npars,s_npars) 284 288 radius_type_offset = 2+p_npars+s_npars + (1 if have_beta_mode else 0) 289 #print(values[radius_type_offset]) 285 290 radius_type = int(values[radius_type_offset]) if have_radius_type else 0 286 291 … … 331 336 # Call the form factor kernel to compute <F> and <F^2>. 332 337 # If the model doesn't support Fq the returned <F> will be None. 333 F1, F2, effective_radius, shell_volume, volume_ratio = self.p_kernel.Fq(338 F1, F2, radius_effective, shell_volume, volume_ratio = self.p_kernel.Fq( 334 339 p_details, p_values, cutoff, magnetic, radius_type) 335 340 … … 341 346 # implementation details in kernel_iq.c. 342 347 #print("R_eff=%d:%g, volfrac=%g, volume ratio=%g" 343 # % (radius_type, effective_radius, volfrac, volume_ratio))348 # % (radius_type, radius_effective, volfrac, volume_ratio)) 344 349 if radius_type > 0: 345 350 # set the value to the model R_eff and set the weight to 1 346 s_values[2] = s_values[2+s_npars+s_offset[0]] = effective_radius351 s_values[2] = s_values[2+s_npars+s_offset[0]] = radius_effective 347 352 s_values[2+s_npars+s_offset[0]+nweights] = 1.0 348 353 s_values[3] = s_values[2+s_npars+s_offset[1]] = volfrac*volume_ratio … … 370 375 # the results directly rather than through a lazy evaluator. 371 376 self.results = lambda: _intermediates( 372 F1, F2, S, combined_scale, effective_radius, beta_mode)377 F1, F2, S, combined_scale, radius_effective, beta_mode) 373 378 374 379 return final_result -
sasmodels/sasview_model.py
rb297ba9 ra34b811 299 299 attrs['category'] = model_info.category 300 300 attrs['is_structure_factor'] = model_info.structure_factor 301 attrs['is_form_factor'] = model_info. effective_radius_typeis not None301 attrs['is_form_factor'] = model_info.radius_effective_modes is not None 302 302 attrs['is_multiplicity_model'] = variants[0] > 1 303 303 attrs['multiplicity_info'] = variants … … 763 763 # if er_mode > 0: 764 764 # res = calculator.Fq(call_details, values, cutoff=self.cutoff, 765 # magnetic=False, effective_radius_type=mode)765 # magnetic=False, radius_effective_mode=mode) 766 766 # R_eff, form_shell_ratio = res[2], res[4] 767 767 # return R_eff, form_shell_ratio
Note: See TracChangeset
for help on using the changeset viewer.