Changes in / [9c44b7b:0011ecc] in sasmodels
- Location:
- sasmodels
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/conversion_table.py
rd3e3f756 rbb584b3 549 549 "radius": "core_radius", 550 550 "sld_solvent": "core_sld", 551 "n_ shells": "n_pairs",551 "n_pairs": "n_pairs", 552 552 "thick_shell": "s_thickness", 553 553 "sld": "shell_sld", -
sasmodels/modelinfo.py
rf88e248 r5124c969 230 230 defined as a sublist with the following elements: 231 231 232 *name* is the name that will be displayed to the user. Names 232 *name* is the name that will be used in the call to the kernel 233 function and the name that will be displayed to the user. Names 233 234 should be lower case, with words separated by underscore. If 234 acronyms are used, the whole acronym should be upper case. For vector 235 parameters, the name will be followed by *[len]* where *len* is an 236 integer length of the vector, or the name of the parameter which 237 controls the length. The attribute *id* will be created from name 238 without the length. 235 acronyms are used, the whole acronym should be upper case. 239 236 240 237 *units* should be one of *degrees* for angles, *Ang* for lengths, … … 606 603 # Using the call_parameters table, we already have expanded forms 607 604 # for each of the vector parameters; put them in a lookup table 608 # Note: p.id and p.name are currently identical for the call parameters 609 expanded_pars = dict((p.id, p) for p in self.call_parameters) 605 expanded_pars = dict((p.name, p) for p in self.call_parameters) 610 606 611 607 def append_group(name): -
sasmodels/models/multilayer_vesicle.c
rec1d4bc r925ad6e 1 static double 2 form_volume(double radius, 3 double thick_shell, 4 double thick_solvent, 5 double fp_n_shells) 6 { 7 int n_shells = (int)(fp_n_shells + 0.5); 8 double R_N = radius + n_shells*(thick_shell+thick_solvent) - thick_solvent; 9 return M_4PI_3*cube(R_N); 10 } 11 12 static double 13 multilayer_vesicle_kernel(double q, 1 static 2 double multilayer_vesicle_kernel(double q, 14 3 double volfraction, 15 4 double radius, … … 18 7 double sld_solvent, 19 8 double sld, 20 int n_ shells)9 int n_pairs) 21 10 { 22 11 //calculate with a loop, two shells at a time … … 40 29 41 30 //do 2 layers at a time 42 ii ++;31 ii += 1; 43 32 44 } while(ii <= n_ shells-1); //change to make 0 < n_shells < 2 correspond to33 } while(ii <= n_pairs-1); //change to make 0 < n_pairs < 2 correspond to 45 34 //unilamellar vesicles (C. Glinka, 11/24/03) 46 35 47 return 1.0e-4*volfraction*fval*fval; // Volume normalization happens in caller 36 fval *= volfraction*1.0e-4*fval/voli; 37 38 return(fval); 48 39 } 49 40 50 static double51 Iq(double q,41 static 42 double Iq(double q, 52 43 double volfraction, 53 44 double radius, … … 56 47 double sld_solvent, 57 48 double sld, 58 double fp_n_ shells)49 double fp_n_pairs) 59 50 { 60 int n_ shells = (int)(fp_n_shells + 0.5);51 int n_pairs = (int)(fp_n_pairs + 0.5); 61 52 return multilayer_vesicle_kernel(q, 62 53 volfraction, … … 66 57 sld_solvent, 67 58 sld, 68 n_ shells);59 n_pairs); 69 60 } 70 61 -
sasmodels/models/multilayer_vesicle.py
r68f45cb r925ad6e 5 5 This model is a trivial extension of the core_shell_sphere function to include 6 6 *N* shells where the core is filled with solvent and the shells are interleaved 7 with layers of solvent. For $N = 1$, this returns the same as the vesicle model,7 with layers of solvent. For *N = 1*, this returns the same as the vesicle model, 8 8 except for the normalisation, which here is to outermost volume. 9 9 The shell thicknessess and SLD are constant for all shells as expected for … … 19 19 20 20 .. math:: 21 P(q) = \text{scale} \cdot \frac{\phi}{V(R_N)} F^2(q) + \text{background} 22 23 where 24 25 .. math:: 26 F(q) = (\rho_\text{shell}-\rho_\text{solv}) \sum_{i=1}^{N} \left[ 27 3V(r_i)\frac{\sin(qr_i) - qr_i\cos(qr_i)}{(qr_i)^3} 28 - 3V(R_i)\frac{\sin(qR_i) - qR_i\cos(qR_i)}{(qR_i)^3} 29 \right] 21 P(q) = \text{scale} \cdot \frac{V_f}{V_t} F^2(q) + \text{background} 30 22 31 23 for 32 24 33 25 .. math:: 26 F(q) = (\rho_\text{shell}-\rho_\text{solv}) \sum_{i=1}^{n_\text{pairs}} 27 \left[ 28 3V(R_i)\frac{\sin(qR_i)-qR_i\cos(qR_i)}{(qR_i)^3} \\ 29 - 3V(R_i+t_s)\frac{\sin(q(R_i+t_s))-q(R_i+t_s)\cos(q(R_i+t_s))}{(q(R_i+t_s))^3} 30 \right] 34 31 35 r_i &= r_c + (i-1)(t_s + t_w) && \text{ solvent radius before shell } i \\ 36 R_i &= r_i + t_s && \text{ shell radius for shell } i 32 and 37 33 38 $\phi$ is the volume fraction of particles, $V(r)$ is the volume of a sphere 39 of radius $r$, $r_c$ is the radius of the core, $t_s$ is the thickness of 40 the shell, $t_w$ is the thickness of the solvent layer between the shells, 41 $\rho_\text{shell}$ is the scattering length density of a shell, and 42 $\rho_\text{solv}$ is the scattering length density of the solvent. 34 .. math:: 35 R_i = r_c + (i-1)(t_s + t_w) 43 36 44 The outer-most shell radius $R_N$ is used as the effective radius 45 for $P(Q)$ when $P(Q) * S(Q)$ is applied. 37 where $V_f$ is the volume fraction of particles, $V_t$ is the volume of the 38 whole particle, $V(r)$ is the volume of a sphere of radius $r$, $r_c$ is the 39 radius of the core, $\rho_\text{shell}$ is the scattering length density of a 40 shell, $\rho_\text{solv}$ is the scattering length density of the solvent. 46 41 47 For mixed systems in which some vesicles have 1 shell, some have 2, 48 etc., use polydispersity on $N$ to model the data. For example, 49 create a file such as *shell_dist.txt* containing the relative portion 50 of each vesicle size:: 51 52 1 20 53 2 4 54 3 1 55 56 Turn on polydispersity and select an array distribution for the *n_shells* 57 parameter. Choose the above *shell_dist.txt* file, and the model will be 58 computed with 80% 1-shell vesicles, 16% 2-shell vesicles and 4% 59 3-shell vesicles. 42 The outer most radius, $r_o = R_n + t_s$, is used for both the volume fraction 43 normalization and for the effective radius for *S(Q)* when $P(Q) * S(Q)$ 44 is applied. 60 45 61 46 The 2D scattering intensity is the same as 1D, regardless of the orientation … … 101 86 sld_solvent: solvent scattering length density 102 87 sld: shell scattering length density 103 n_ shells:number of "shell plus solvent" layer pairs88 n_pairs:number of "shell plus solvent" layer pairs 104 89 background: incoherent background 105 90 """ … … 110 95 parameters = [ 111 96 ["volfraction", "", 0.05, [0.0, 1], "", "volume fraction of vesicles"], 112 ["radius", "Ang", 60.0, [0.0, inf], " volume", "radius of solvent filled core"],113 ["thick_shell", "Ang", 10.0, [0.0, inf], " volume", "thickness of one shell"],114 ["thick_solvent", "Ang", 10.0, [0.0, inf], " volume", "solvent thickness between shells"],97 ["radius", "Ang", 60.0, [0.0, inf], "", "radius of solvent filled core"], 98 ["thick_shell", "Ang", 10.0, [0.0, inf], "", "thickness of one shell"], 99 ["thick_solvent", "Ang", 10.0, [0.0, inf], "", "solvent thickness between shells"], 115 100 ["sld_solvent", "1e-6/Ang^2", 6.4, [-inf, inf], "sld", "solvent scattering length density"], 116 101 ["sld", "1e-6/Ang^2", 0.4, [-inf, inf], "sld", "Shell scattering length density"], 117 ["n_ shells", "", 2.0, [1.0, inf], "volume", "Number of shell plus solvent layer pairs"],102 ["n_pairs", "", 2.0, [1.0, inf], "", "Number of shell plus solvent layer pairs"], 118 103 ] 119 104 # pylint: enable=bad-whitespace, line-too-long 120 105 121 # TODO: proposed syntax for specifying which parameters can be polydisperse122 #polydispersity = ["radius", "thick_shell"]123 124 106 source = ["lib/sas_3j1x_x.c", "multilayer_vesicle.c"] 125 107 126 def ER(radius, thick_shell, thick_solvent, n_shells): 127 n_shells = int(n_shells+0.5) 128 return radius + n_shells * (thick_shell + thick_solvent) - thick_solvent 108 # TODO: the following line does nothing 109 polydispersity = ["radius", "n_pairs"] 129 110 130 111 demo = dict(scale=1, background=0, … … 135 116 sld_solvent=6.4, 136 117 sld=0.4, 137 n_ shells=2.0)118 n_pairs=2.0) 138 119 139 120 tests = [ … … 144 125 'sld_solvent': 6.4, 145 126 'sld': 0.4, 146 'n_ shells': 2.0,127 'n_pairs': 2.0, 147 128 'scale': 1.0, 148 129 'background': 0.001, … … 155 136 'sld_solvent': 6.4, 156 137 'sld': 0.4, 157 'n_ shells': 2.0,138 'n_pairs': 2.0, 158 139 'scale': 1.0, 159 140 'background': 0.001, -
sasmodels/product.py
rf88e248 r9951a86 45 45 # structure factor calculator. Structure factors should not 46 46 # have any magnetic parameters 47 if not s_info.parameters.kernel_parameters[0].id == ER_ID: 48 raise TypeError("S needs %s as first parameter"%ER_ID) 49 if not s_info.parameters.kernel_parameters[1].id == VF_ID: 50 raise TypeError("S needs %s as second parameter"%VF_ID) 51 if not s_info.parameters.magnetism_index == []: 52 raise TypeError("S should not have SLD parameters") 47 assert(s_info.parameters.kernel_parameters[0].id == ER_ID) 48 assert(s_info.parameters.kernel_parameters[1].id == VF_ID) 49 assert(s_info.parameters.magnetism_index == []) 53 50 p_id, p_name, p_pars = p_info.id, p_info.name, p_info.parameters 54 51 s_id, s_name, s_pars = s_info.id, s_info.name, s_info.parameters 55 56 # Create list of parameters for the combined model. Skip the first 57 # parameter of S, which we verified above is effective radius. If there 58 # are any names in P that overlap with those in S, modify the name in S 59 # to distinguish it. 60 p_set = set(p.id for p in p_pars.kernel_parameters) 61 s_list = [(_tag_parameter(par) if par.id in p_set else par) 62 for par in s_pars.kernel_parameters[1:]] 63 # Check if still a collision after renaming. This could happen if for 64 # example S has volfrac and P has both volfrac and volfrac_S. 65 if any(p.id in p_set for p in s_list): 66 raise TypeError("name collision: P has P.name and P.name_S while S has S.name") 67 52 p_set = set(p.id for p in p_pars.call_parameters) 53 s_set = set(p.id for p in s_pars.call_parameters) 54 55 if p_set & s_set: 56 # there is some overlap between the parameter names; tag the 57 # overlapping S parameters with name_S. 58 # Skip the first parameter of s, which is effective radius 59 s_list = [(suffix_parameter(par) if par.id in p_set else par) 60 for par in s_pars.kernel_parameters[1:]] 61 else: 62 # Skip the first parameter of s, which is effective radius 63 s_list = s_pars.kernel_parameters[1:] 68 64 translate_name = dict((old.id, new.id) for old, new 69 65 in zip(s_pars.kernel_parameters[1:], s_list)) 70 66 demo = {} 71 demo.update(p_info.demo.items()) 67 demo.update((k, v) for k, v in p_info.demo.items() 68 if k not in ("background", "scale")) 72 69 demo.update((translate_name[k], v) for k, v in s_info.demo.items() 73 70 if k not in ("background", "scale") and not k.startswith(ER_ID)) … … 93 90 # Remember the component info blocks so we can build the model 94 91 model_info.composition = ('product', [p_info, s_info]) 95 model_info.demo = demo 96 97 ## Show the parameter table with the demo values 98 #from .compare import get_pars, parlist 99 #print("==== %s ====="%model_info.name) 100 #values = get_pars(model_info, use_demo=True) 101 #print(parlist(model_info, values, is2d=True)) 92 model_info.demo = {} 102 93 return model_info 103 94 104 def _tag_parameter(par): 105 """ 106 Tag the parameter name with _S to indicate that the parameter comes from 107 the structure factor parameter set. This is only necessary if the 108 form factor model includes a parameter of the same name as a parameter 109 in the structure factor. 110 """ 95 def suffix_parameter(par, suffix): 111 96 par = copy(par) 112 # Protect against a vector parameter in S by appending the vector length 113 # to the renamed parameter. Note: haven't tested this since no existing 114 # structure factor models contain vector parameters. 115 vector_length = par.name[len(par.id):] 97 par.name = par.name + " S" 116 98 par.id = par.id + "_S" 117 par.name = par.id + vector_length118 99 return par 119 100
Note: See TracChangeset
for help on using the changeset viewer.