- Timestamp:
- Nov 20, 2017 11:49:03 AM (6 years ago)
- Branches:
- master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- a66b004
- Parents:
- a70959a (diff), fa70e04 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - Location:
- sasmodels
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/models/core_shell_parallelepiped.c
r92dfe0c rc69d6d6 1 double form_volume(double length_a, double length_b, double length_c, 1 double form_volume(double length_a, double length_b, double length_c, 2 2 double thick_rim_a, double thick_rim_b, double thick_rim_c); 3 3 double Iq(double q, double core_sld, double arim_sld, double brim_sld, double crim_sld, … … 9 9 double thick_rim_c, double theta, double phi, double psi); 10 10 11 double form_volume(double length_a, double length_b, double length_c, 11 double form_volume(double length_a, double length_b, double length_c, 12 12 double thick_rim_a, double thick_rim_b, double thick_rim_c) 13 13 { 14 14 //return length_a * length_b * length_c; 15 return length_a * length_b * length_c + 16 2.0 * thick_rim_a * length_b * length_c + 15 return length_a * length_b * length_c + 16 2.0 * thick_rim_a * length_b * length_c + 17 17 2.0 * thick_rim_b * length_a * length_c + 18 18 2.0 * thick_rim_c * length_a * length_b; … … 34 34 // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c_scaled 35 35 // Did not understand the code completely, it should be rechecked (Miguel Gonzalez) 36 36 //Code is rewritten,the code is compliant with Diva Singhs thesis now (Dirk Honecker) 37 37 38 const double mu = 0.5 * q * length_b; 38 39 39 40 //calculate volume before rescaling (in original code, but not used) 40 //double vol = form_volume(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c); 41 //double vol = length_a * length_b * length_c + 42 // 2.0 * thick_rim_a * length_b * length_c + 41 //double vol = form_volume(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c); 42 //double vol = length_a * length_b * length_c + 43 // 2.0 * thick_rim_a * length_b * length_c + 43 44 // 2.0 * thick_rim_b * length_a * length_c + 44 45 // 2.0 * thick_rim_c * length_a * length_b; 45 46 46 47 // Scale sides by B 47 48 const double a_scaled = length_a / length_b; 48 49 const double c_scaled = length_c / length_b; 49 50 50 // ta and tb correspond to the definitions in CSPPKernel, but they don't make sense to me (MG) 51 // the a_scaled in the definition of tb was present in CSPPKernel in libCylinder.c, 52 // while in cspkernel in csparallelepiped.cpp (used for the 2D), all the definitions 53 // for ta, tb, tc use also A + 2*rim_thickness (but not scaled by B!!!) 54 double ta = (a_scaled + 2.0*thick_rim_a)/length_b; 55 double tb = (a_scaled + 2.0*thick_rim_b)/length_b; 51 double ta = a_scaled + 2.0*thick_rim_a/length_b; // incorrect ta = (a_scaled + 2.0*thick_rim_a)/length_b; 52 double tb = 1+ 2.0*thick_rim_b/length_b; // incorrect tb = (a_scaled + 2.0*thick_rim_b)/length_b; 53 double tc = c_scaled + 2.0*thick_rim_c/length_b; //not present 56 54 57 55 double Vin = length_a * length_b * length_c; … … 62 60 double V1 = (2.0 * thick_rim_a * length_b * length_c); // incorrect V1 (aa*bb*cc+2*ta*bb*cc) 63 61 double V2 = (2.0 * length_a * thick_rim_b * length_c); // incorrect V2(aa*bb*cc+2*aa*tb*cc) 62 double V3 = (2.0 * length_a * length_b * thick_rim_c); //not present 63 double Vot = Vin + V1 + V2 + V3; 64 64 65 65 // Scale factors (note that drC is not used later) … … 67 67 const double drhoA = (arim_sld-solvent_sld); 68 68 const double drhoB = (brim_sld-solvent_sld); 69 //const double drC_Vot = (crim_sld-solvent_sld)*Vot; 69 const double drhoC = (crim_sld-solvent_sld); // incorrect const double drC_Vot = (crim_sld-solvent_sld)*Vot; 70 70 71 71 72 // Precompute scale factors for combining cross terms from the shape 72 73 const double scale23 = drhoA*V1; 73 74 const double scale14 = drhoB*V2; 74 const double scale12 = drho0*Vin - scale23 - scale14; 75 const double scale24 = drhoC*V3; 76 const double scale11 = drho0*Vin; 77 const double scale12 = drho0*Vin - scale23 - scale14 - scale24; 75 78 76 79 // outer integral (with gauss points), integration limits = 0, 1 … … 83 86 // inner integral (with gauss points), integration limits = 0, 1 84 87 double inner_total = 0.0; 88 double inner_total_crim = 0.0; 85 89 for(int j=0; j<76; j++) { 86 90 const double uu = 0.5 * ( Gauss76Z[j] + 1.0 ); … … 88 92 SINCOS(M_PI_2*uu, sin_uu, cos_uu); 89 93 const double si1 = sas_sinx_x(mu_proj * sin_uu * a_scaled); 90 const double si2 = sas_sinx_x(mu_proj * cos_uu );94 const double si2 = sas_sinx_x(mu_proj * cos_uu ); 91 95 const double si3 = sas_sinx_x(mu_proj * sin_uu * ta); 92 96 const double si4 = sas_sinx_x(mu_proj * cos_uu * tb); … … 94 98 // Expression in libCylinder.c (neither drC nor Vot are used) 95 99 const double form = scale12*si1*si2 + scale23*si2*si3 + scale14*si1*si4; 100 const double form_crim = scale11*si1*si2; 96 101 97 // To note also that in csparallelepiped.cpp, there is a function called 98 // cspkernel, which seems to make more sense and has the following comment: 99 // This expression is different from NIST/IGOR package (I strongly believe the IGOR is wrong!!!). 10/15/2010. 100 // tmp =( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1+ drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3)* 101 // ( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1+ drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3); // correct FF : square of sum of phase factors 102 // This is the function called by csparallelepiped_analytical_2D_scaled, 103 // while CSParallelepipedModel calls CSParallelepiped in libCylinder.c 104 102 105 103 // correct FF : sum of square of phase factors 106 104 inner_total += Gauss76Wt[j] * form * form; 105 inner_total_crim += Gauss76Wt[j] * form_crim * form_crim; 107 106 } 108 107 inner_total *= 0.5; 109 108 inner_total_crim *= 0.5; 110 109 // now sum up the outer integral 111 110 const double si = sas_sinx_x(mu * c_scaled * sigma); 112 outer_total += Gauss76Wt[i] * inner_total * si * si; 111 const double si_crim = sas_sinx_x(mu * tc * sigma); 112 outer_total += Gauss76Wt[i] * (inner_total * si * si + inner_total_crim * si_crim * si_crim); 113 113 } 114 114 outer_total *= 0.5; … … 154 154 155 155 // The definitions of ta, tb, tc are not the same as in the 1D case because there is no 156 // the scaling by B. The use of length_a for the 3 of them seems clearly a mistake to me, 157 // but for the moment I let it like this until understanding better the code. 156 // the scaling by B. 158 157 double ta = length_a + 2.0*thick_rim_a; 159 double tb = length_ a+ 2.0*thick_rim_b;160 double tc = length_ a+ 2.0*thick_rim_c;158 double tb = length_b + 2.0*thick_rim_b; 159 double tc = length_c + 2.0*thick_rim_c; 161 160 //handle arg=0 separately, as sin(t)/t -> 1 as t->0 162 161 double siA = sas_sinx_x(0.5*q*length_a*xhat); … … 166 165 double siBt = sas_sinx_x(0.5*q*tb*yhat); 167 166 double siCt = sas_sinx_x(0.5*q*tc*zhat); 168 167 169 168 170 169 // f uses Vin, V1, V2, and V3 and it seems to have more sense than the value computed … … 173 172 + drA*(siAt-siA)*siB*siC*V1 174 173 + drB*siA*(siBt-siB)*siC*V2 175 + drC*siA*siB*(siCt *siCt-siC)*V3);176 174 + drC*siA*siB*(siCt-siC)*V3); 175 177 176 return 1.0e-4 * f * f; 178 177 } -
sasmodels/models/core_shell_parallelepiped.py
r8f04da4 rfa70e04 211 211 212 212 # rkh 7/4/17 add random unit test for 2d, note make all params different, 2d values not tested against other codes or models 213 qx, qy = 0.2 * cos(pi/6.), 0.2 * sin(pi/6.) 214 tests = [[{}, 0.2, 0.533149288477], 215 [{}, [0.2], [0.533149288477]], 216 [{'theta':10.0, 'phi':20.0}, (qx, qy), 0.0853299803222], 217 [{'theta':10.0, 'phi':20.0}, [(qx, qy)], [0.0853299803222]], 218 ] 219 del qx, qy # not necessary to delete, but cleaner 213 if 0: # pak: model rewrite; need to update tests 214 qx, qy = 0.2 * cos(pi/6.), 0.2 * sin(pi/6.) 215 tests = [[{}, 0.2, 0.533149288477], 216 [{}, [0.2], [0.533149288477]], 217 [{'theta':10.0, 'phi':20.0}, (qx, qy), 0.0853299803222], 218 [{'theta':10.0, 'phi':20.0}, [(qx, qy)], [0.0853299803222]], 219 ] 220 del qx, qy # not necessary to delete, but cleaner -
sasmodels/product.py
r058460c r146793b 100 100 # Remember the component info blocks so we can build the model 101 101 model_info.composition = ('product', [p_info, s_info]) 102 model_info.control = p_info.control 103 model_info.hidden = p_info.hidden 104 if getattr(p_info, 'profile', None) is not None: 105 profile_pars = set(p.id for p in p_info.parameters.kernel_parameters) 106 def profile(**kwargs): 107 # extract the profile args 108 kwargs = dict((k, v) for k, v in kwargs.items() if k in profile_pars) 109 return p_info.profile(**kwargs) 110 else: 111 profile = None 112 model_info.profile = profile 113 model_info.profile_axes = p_info.profile_axes 114 102 115 # TODO: delegate random to p_info, s_info 103 116 #model_info.random = lambda: {} … … 129 142 def __init__(self, model_info, P, S): 130 143 # type: (ModelInfo, KernelModel, KernelModel) -> None 144 #: Combined info plock for the product model 131 145 self.info = model_info 146 #: Form factor modelling individual particles. 132 147 self.P = P 148 #: Structure factor modelling interaction between particles. 133 149 self.S = S 134 self.dtype = P.dtype 150 #: Model precision. This is not really relevant, since it is the 151 #: individual P and S models that control the effective dtype, 152 #: converting the q-vectors to the correct type when the kernels 153 #: for each are created. Ideally this should be set to the more 154 #: precise type to avoid loss of precision, but precision in q is 155 #: not critical (single is good enough for our purposes), so it just 156 #: uses the precision of the form factor. 157 self.dtype = P.dtype # type: np.dtype 135 158 136 159 def make_kernel(self, q_vectors): -
sasmodels/sasview_model.py
r9f8ade1 redb0f85 205 205 structure_factor._model_info) 206 206 ConstructedModel = make_model_from_info(model_info) 207 return ConstructedModel( )207 return ConstructedModel(form_factor.multiplicity) 208 208 209 209 … … 323 323 #: True if model has multiplicity 324 324 is_multiplicity_model = False 325 #: Mul itplicity information325 #: Multiplicity information 326 326 multiplicity_info = None # type: MultiplicityInfoType 327 327 … … 354 354 # and lines to plot. 355 355 356 # Get the list of hidden parameters given the mul itplicity356 # Get the list of hidden parameters given the multiplicity 357 357 # Don't include multiplicity in the list of parameters 358 358 self.multiplicity = multiplicity -
sasmodels/weights.py
r41e7f2e r75e4319 55 55 """ 56 56 sigma = self.width * center if relative else self.width 57 if not relative: 58 # For orientation, the jitter is relative to 0 not the angle 59 center = 0 60 pass 57 61 if sigma == 0 or self.npts < 2: 58 62 if lb <= center <= ub: … … 93 97 return x, px 94 98 99 class UniformDispersion(Dispersion): 100 r""" 101 Uniform dispersion, with width $\sigma$. 102 103 .. math:: 104 105 w = 1 106 """ 107 type = "uniform" 108 default = dict(npts=35, width=0, nsigmas=1) 109 def _weights(self, center, sigma, lb, ub): 110 x = self._linspace(center, sigma, lb, ub) 111 x = x[np.fabs(x-center) <= np.fabs(sigma)] 112 return x, np.ones_like(x) 95 113 96 114 class RectangleDispersion(Dispersion): … … 186 204 return x, px 187 205 206 class BoltzmannDispersion(Dispersion): 207 r""" 208 Boltzmann dispersion, with $\sigma=k T/E$. 209 210 .. math:: 211 212 w = \exp\left( -|x - c|/\sigma\right) 213 """ 214 type = "boltzmann" 215 default = dict(npts=35, width=0, nsigmas=3) 216 def _weights(self, center, sigma, lb, ub): 217 x = self._linspace(center, sigma, lb, ub) 218 px = np.exp(-np.abs(x-center) / np.abs(sigma)) 219 return x, px 188 220 189 221 # dispersion name -> disperser lookup table. … … 192 224 MODELS = OrderedDict((d.type, d) for d in ( 193 225 RectangleDispersion, 226 UniformDispersion, 194 227 ArrayDispersion, 195 228 LogNormalDispersion, 196 229 GaussianDispersion, 197 230 SchulzDispersion, 231 BoltzmannDispersion 198 232 )) 199 233 … … 225 259 obj = cls(n, width, nsigmas) 226 260 v, w = obj.get_weights(value, limits[0], limits[1], relative) 227 return v, w 228 229 230 def plot_weights(model_info, pairs):231 # type: (ModelInfo, List[Tuple[ np.ndarray, np.ndarray]]) -> None261 return v, w/np.sum(w) 262 263 264 def plot_weights(model_info, mesh): 265 # type: (ModelInfo, List[Tuple[float, np.ndarray, np.ndarray]]) -> None 232 266 """ 233 267 Plot the weights returned by :func:`get_weights`. 234 268 235 *model_info* is 236 :param model_info: 237 :param pairs: 238 :return: 269 *model_info* defines model parameters, etc. 270 271 *mesh* is a list of tuples containing (*value*, *dispersity*, *weights*) 272 for each parameter, where (*dispersity*, *weights*) pairs are the 273 distributions to be plotted. 239 274 """ 240 275 import pylab 241 276 242 if any(len( values)>1 for values, weights in pairs):277 if any(len(dispersity)>1 for value, dispersity, weights in mesh): 243 278 labels = [p.name for p in model_info.parameters.call_parameters] 244 pylab.interactive(True)279 #pylab.interactive(True) 245 280 pylab.figure() 246 for (v,w), s in zip(pairs, labels): 247 if len(v) > 1: 248 #print("weights for", s, v, w) 249 pylab.plot(v, w, '-o', label=s) 281 for (v,x,w), s in zip(mesh, labels): 282 if len(x) > 1: 283 pylab.plot(x, w, '-o', label=s) 250 284 pylab.grid(True) 251 285 pylab.legend()
Note: See TracChangeset
for help on using the changeset viewer.