Changeset 32e3c9b in sasmodels
- Timestamp:
- Jul 21, 2016 4:08:04 PM (8 years ago)
- Branches:
- master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- b966a96
- Parents:
- 42356c8
- Files:
-
- 1 added
- 1 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/__init__.py
r59d94b3 r32e3c9b 41 41 # can build model docs on the fly, including images. 42 42 return_list = [ 43 expand_patterns([], ['*.c', '*.cl' , 'convert.json']),43 expand_patterns([], ['*.c', '*.cl']), 44 44 expand_patterns(['models'], ['*.py', '*.c']), 45 45 expand_patterns(['models', 'lib'], ['*.c']), -
sasmodels/convert.py
ra0494e9 r32e3c9b 7 7 import math 8 8 import warnings 9 import json 9 10 from .conversion_table import CONVERSION_TABLE 10 11 11 12 # List of models which SasView versions don't contain the explicit 'scale' argument. … … 47 48 ] 48 49 49 CONVERSION_TABLE = None50 51 def _read_conversion_table():52 global CONVERSION_TABLE53 if CONVERSION_TABLE is None:54 path = joinpath(dirname(abspath(__file__)), "convert.json")55 with open(path) as fid:56 CONVERSION_TABLE = json_load_byteified(fid)57 58 def json_load_byteified(file_handle):59 return _byteify(60 json.load(file_handle, object_hook=_byteify),61 ignore_dicts=True62 )63 64 def _byteify(data, ignore_dicts = False):65 # if this is a unicode string, return its string representation66 if isinstance(data, unicode):67 return data.encode('utf-8')68 # if this is a list of values, return list of byteified values69 if isinstance(data, list):70 return [ _byteify(item, ignore_dicts=True) for item in data ]71 # if this is a dictionary, return dictionary of byteified keys and values72 # but only if we haven't already byteified it73 if isinstance(data, dict) and not ignore_dicts:74 return dict((_byteify(key, ignore_dicts=True),75 _byteify(value, ignore_dicts=True))76 for key, value in data.items())77 # if it's anything else, return it in its original form78 return data79 80 81 50 def _convert_pars(pars, mapping): 82 51 """ … … 93 62 return newpars 94 63 95 def _rescale_sld(pars):96 """97 rescale all sld parameters in the new model definition by 1e6 so the98 numbers are nicer. Relies on the fact that all sld parameters in the99 new model definition end with sld.100 """101 return dict((p, (v*1e6 if p.endswith('sld')102 else v*1e-15 if 'ndensity' in p103 else v))104 for p, v in pars.items())105 106 64 def convert_model(name, pars): 107 65 """ … … 116 74 return [pk*scale for pk in par] if isinstance(par, list) else par*scale 117 75 118 def _unscale_sld(pars): 76 def _is_sld(modelinfo, id): 77 if id.startswith('M0:'): 78 return True 79 if (id.endswith('_pd') or id.endswith('_pd_n') or id.endswith('_pd_nsigma') 80 or id.endswith('_pd_width') or id.endswith('_pd_type')): 81 return False 82 for p in modelinfo.parameters.call_parameters: 83 if p.id == id: 84 return p.type == 'sld' 85 # check through kernel parameters in case it is a named as a vector 86 for p in modelinfo.parameters.kernel_parameters: 87 if p.id == id: 88 return p.type == 'sld' 89 raise ValueError("unknown parameter %r in conversion"%id) 90 91 def _unscale_sld(modelinfo, pars): 119 92 """ 120 93 rescale all sld parameters in the new model definition by 1e6 so the … … 122 95 new model definition end with sld. 123 96 """ 124 return dict((p, (_unscale(v,1e-6) if p.startswith('sld') or p.endswith('sld') 125 else _unscale(v,1e15) if 'ndensity' in p 126 else v)) 127 for p, v in pars.items()) 97 return dict((id, (_unscale(v,1e-6) if _is_sld(modelinfo, id) else v)) 98 for id, v in pars.items()) 128 99 129 100 def _remove_pd(pars, key, name): … … 164 135 165 136 def revert_name(model_info): 166 _read_conversion_table()167 137 oldname, oldpars = CONVERSION_TABLE.get(model_info.id, [None, {}]) 168 138 return oldname 169 139 170 140 def _get_translation_table(model_info): 171 _read_conversion_table()172 141 _, translation = CONVERSION_TABLE.get(model_info.id, [None, {}]) 173 142 translation = translation.copy() … … 186 155 187 156 def _trim_vectors(model_info, pars, oldpars): 188 _read_conversion_table()189 157 _, translation = CONVERSION_TABLE.get(model_info.id, [None, {}]) 190 158 for p in model_info.parameters.kernel_parameters: … … 212 180 else: 213 181 translation = _get_translation_table(model_info) 214 oldpars = _revert_pars(_unscale_sld( pars), translation)182 oldpars = _revert_pars(_unscale_sld(model_info, pars), translation) 215 183 oldpars = _trim_vectors(model_info, pars, oldpars) 216 184 … … 243 211 _remove_pd(oldpars, 'rimB', name) 244 212 _remove_pd(oldpars, 'rimC', name) 213 elif name == 'polymer_micelle': 214 if 'ndensity' in oldpars: 215 oldpars['ndensity'] *= 1e15 245 216 elif name == 'spherical_sld': 246 217 for k in range(1, int(pars['n_shells'])+1): -
sasmodels/details.py
ra738209 r32e3c9b 96 96 97 97 pd_offset = np.cumsum(np.hstack((0, pd_length))) 98 #print(", ".join(str(i)+"-"+p.id for i,p in enumerate(model_info.parameters.call_parameters))) 99 #print("len:",pd_length) 100 #print("off:",pd_offset) 98 101 # Note: the reversing view, x[::-1], does not require a copy 99 102 idx = np.argsort(pd_length)[::-1][:num_active] -
sasmodels/direct_model.py
ra738209 r32e3c9b 70 70 71 71 call_details, values = kernel.build_details(calculator, vw_pairs) 72 return calculator(call_details, values, cutoff) 72 magnetic = any(values[k]!=0 for k in parameters.magnetism_index) 73 #print("values:", values) 74 return calculator(call_details, values, cutoff, magnetic) 73 75 74 76 def get_weights(parameter, values): -
sasmodels/generate.py
ra738209 r32e3c9b 387 387 388 388 389 def kernel_name(model_info, is_2d):390 # type: (ModelInfo, bool) -> str389 def kernel_name(model_info, variant): 390 # type: (ModelInfo, str) -> str 391 391 """ 392 392 Name of the exported kernel symbol. 393 """ 394 return model_info.name + "_" + ("Iqxy" if is_2d else "Iq") 393 394 *variant* is "Iq", "Iqxy" or "Imagnetic". 395 """ 396 return model_info.name + "_" + variant 395 397 396 398 … … 555 557 refs = ["_q[_i]"] + _call_pars("_v.", partable.iq_parameters) 556 558 call_iq = "#define CALL_IQ(_q,_i,_v) Iq(%s)" % (",".join(refs)) 557 if _have_Iqxy(user_code) :559 if _have_Iqxy(user_code) or isinstance(model_info.Iqxy, str): 558 560 # Call 2D model 559 refs = [" q[2*_i]", "q[2*_i+1]"] + _call_pars("_v.", partable.iqxy_parameters)561 refs = ["_q[2*_i]", "_q[2*_i+1]"] + _call_pars("_v.", partable.iqxy_parameters) 560 562 call_iqxy = "#define CALL_IQ(_q,_i,_v) Iqxy(%s)" % (",".join(refs)) 561 563 else: … … 566 568 call_iqxy = "#define CALL_IQ(_q,_i,_v) Iq(%s)" % (",".join(pars_sqrt)) 567 569 570 magpars = [k-2 for k,p in enumerate(partable.call_parameters) 571 if p.type == 'sld'] 572 568 573 # Fill in definitions for numbers of parameters 569 574 source.append("#define MAX_PD %s"%partable.max_pd) 570 575 source.append("#define NPARS %d"%partable.npars) 576 source.append("#define NUM_MAGNETIC %d" % len(magpars)) 577 source.append("#define MAGNETIC_PARS %s"%",".join(str(k) for k in magpars)) 571 578 572 579 # TODO: allow mixed python/opencl kernels? … … 584 591 source = [ 585 592 # define the Iq kernel 586 "#define KERNEL_NAME %s_Iq" %name,593 "#define KERNEL_NAME %s_Iq" % name, 587 594 call_iq, 588 595 kernel_code, … … 591 598 592 599 # define the Iqxy kernel from the same source with different #defines 593 "#define KERNEL_NAME %s_Iqxy" %name,600 "#define KERNEL_NAME %s_Iqxy" % name, 594 601 call_iqxy, 595 602 kernel_code, 603 "#undef CALL_IQ", 604 "#undef KERNEL_NAME", 605 606 # define the Imagnetic kernel 607 "#define KERNEL_NAME %s_Imagnetic" % name, 608 "#define MAGNETIC 1", 609 call_iqxy, 610 kernel_code, 611 "#undef MAGNETIC", 596 612 "#undef CALL_IQ", 597 613 "#undef KERNEL_NAME", -
sasmodels/kernel.py
rdef2c1b r32e3c9b 41 41 results = None # type: List[np.ndarray] 42 42 43 def __call__(self, call_details, values, cutoff ):44 # type: (CallDetails, np.ndarray, np.ndarray, float ) -> np.ndarray43 def __call__(self, call_details, values, cutoff, magnetic): 44 # type: (CallDetails, np.ndarray, np.ndarray, float, bool) -> np.ndarray 45 45 raise NotImplementedError("need to implement __call__") 46 46 -
sasmodels/kernel_iq.c
ra738209 r32e3c9b 33 33 #endif 34 34 35 #ifdef MAGNETIC 36 const int32_t magnetic[] = { MAGNETIC_PARS }; 37 #endif 38 39 #ifdef MAGNETIC 40 // Return value restricted between low and high 41 static double clip(double value, double low, double high) 42 { 43 return (value < low ? low : (value > high ? high : value)); 44 } 45 46 // Compute spin cross sections given in_spin and out_spin 47 // To convert spin cross sections to sld b: 48 // uu * (sld - m_sigma_x); 49 // dd * (sld + m_sigma_x); 50 // ud * (m_sigma_y + 1j*m_sigma_z); 51 // du * (m_sigma_y - 1j*m_sigma_z); 52 static void spins(double in_spin, double out_spin, 53 double *uu, double *dd, double *ud, double *du) 54 { 55 in_spin = clip(in_spin, 0.0, 1.0); 56 out_spin = clip(out_spin, 0.0, 1.0); 57 *uu = sqrt(sqrt(in_spin * out_spin)); 58 *dd = sqrt(sqrt((1.0-in_spin) * (1.0-out_spin))); 59 *ud = sqrt(sqrt(in_spin * (1.0-out_spin))); 60 *du = sqrt(sqrt((1.0-in_spin) * out_spin)); 61 } 62 63 // Convert polar to rectangular coordinates. 64 static void polrec(double r, double theta, double phi, 65 double *x, double *y, double *z) 66 { 67 double cos_theta, sin_theta, cos_phi, sin_phi; 68 SINCOS(theta*M_PI_180, sin_theta, cos_theta); 69 SINCOS(phi*M_PI_180, sin_phi, cos_phi); 70 *x = r * cos_theta * cos_phi; 71 *y = r * sin_theta; 72 *z = -r * cos_theta * sin_phi; 73 } 74 #endif 35 75 36 76 kernel … … 40 80 const int32_t pd_stop, // where we are stopping in the polydispersity loop 41 81 global const ProblemDetails *details, 42 global const double *values, 82 // global const // TODO: make it const again! 83 double *values, 43 84 global const double *q, // nq q values, with padding to boundary 44 85 global double *result, // nq+3 return values, again with padding … … 52 93 53 94 // Fill in the initial variables 95 // values[0] is scale 96 // values[1] is background 54 97 #ifdef USE_OPENMP 55 98 #pragma omp parallel for … … 58 101 pvec[k] = values[k+2]; 59 102 } 103 #ifdef MAGNETIC 104 const double up_frac_i = values[NPARS+2]; 105 const double up_frac_f = values[NPARS+3]; 106 const double up_angle = values[NPARS+4]; 107 #define MX(_k) (values[NPARS+5+3*_k]) 108 #define MY(_k) (values[NPARS+6+3*_k]) 109 #define MZ(_k) (values[NPARS+7+3*_k]) 110 111 // TODO: precompute this on the python side 112 // Convert polar to rectangular coordinates in place. 113 if (pd_start == 0) { // Update in place; only do this for the first hunk! 114 //printf("spin: %g %g %g\n", up_frac_i, up_frac_f, up_angle); 115 for (int mag=0; mag < NUM_MAGNETIC; mag++) { 116 //printf("mag %d: %g %g %g\n", mag, MX(mag), MY(mag), MZ(mag)); 117 polrec(MX(mag), MY(mag), MZ(mag), &MX(mag), &MY(mag), &MZ(mag)); 118 //printf(" ==>: %g %g %g\n", MX(mag), MY(mag), MZ(mag)); 119 } 120 } 121 // Interpret polarization cross section. 122 double uu, dd, ud, du; 123 double cos_mspin, sin_mspin; 124 spins(up_frac_i, up_frac_f, &uu, &dd, &ud, &du); 125 SINCOS(-up_angle*M_PI_180, sin_mspin, cos_mspin); 126 #endif 60 127 61 128 // Monodisperse computation … … 74 141 #endif 75 142 for (int q_index=0; q_index < nq; q_index++) { 143 #ifdef MAGNETIC 144 const double qx = q[2*q_index]; 145 const double qy = q[2*q_index+1]; 146 const double qsq = qx*qx + qy*qy; 147 148 // Constant across orientation, polydispersity for given qx, qy 149 double px, py, pz; 150 if (qsq > 1e-16) { 151 px = (qy*cos_mspin + qx*sin_mspin)/qsq; 152 py = (qy*sin_mspin - qx*cos_mspin)/qsq; 153 pz = 1.0; 154 } else { 155 px = py = pz = 0.0; 156 } 157 158 double scattering = 0.0; 159 if (uu > 1e-8) { 160 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 161 const double perp = (qy*MX(mag) - qx*MY(mag)); 162 pvec[magnetic[mag]] = (values[magnetic[mag]+2] - perp*px)*uu; 163 } 164 scattering += CALL_IQ(q, q_index, local_values); 165 } 166 if (dd > 1e-8){ 167 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 168 const double perp = (qy*MX(mag) - qx*MY(mag)); 169 pvec[magnetic[mag]] = (values[magnetic[mag]+2] + perp*px)*dd; 170 } 171 scattering += CALL_IQ(q, q_index, local_values); 172 } 173 if (ud > 1e-8){ 174 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 175 const double perp = (qy*MX(mag) - qx*MY(mag)); 176 pvec[magnetic[mag]] = perp*py*ud; 177 } 178 scattering += CALL_IQ(q, q_index, local_values); 179 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 180 pvec[magnetic[mag]] = MZ(mag)*pz*ud; 181 } 182 scattering += CALL_IQ(q, q_index, local_values); 183 } 184 if (du > 1e-8) { 185 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 186 const double perp = (qy*MX(mag) - qx*MY(mag)); 187 pvec[magnetic[mag]] = perp*py*du; 188 } 189 scattering += CALL_IQ(q, q_index, local_values); 190 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 191 pvec[magnetic[mag]] = -MZ(mag)*pz*du; 192 } 193 scattering += CALL_IQ(q, q_index, local_values); 194 } 195 #else 76 196 double scattering = CALL_IQ(q, q_index, local_values); 197 #endif 77 198 result[q_index] = (norm>0. ? scale*scattering/norm + background : background); 78 199 } … … 82 203 #if MAX_PD > 0 83 204 205 #if MAGNETIC 206 const double *pd_value = values+2+NPARS+3+3*NUM_MAGNETIC; 207 #else 84 208 const double *pd_value = values+2+NPARS; 209 #endif 85 210 const double *pd_weight = pd_value+details->pd_sum; 86 211 … … 164 289 #endif 165 290 for (int q_index=0; q_index < nq; q_index++) { 166 const double scattering = CALL_IQ(q, q_index, local_values); 291 #ifdef MAGNETIC 292 const double qx = q[2*q_index]; 293 const double qy = q[2*q_index+1]; 294 const double qsq = qx*qx + qy*qy; 295 296 // Constant across orientation, polydispersity for given qx, qy 297 double px, py, pz; 298 if (qsq > 1e-16) { 299 px = (qy*cos_mspin + qx*sin_mspin)/qsq; 300 py = (qy*sin_mspin - qx*cos_mspin)/qsq; 301 pz = 1.0; 302 } else { 303 px = py = pz = 0.0; 304 } 305 306 double scattering = 0.0; 307 if (uu > 1e-8) { 308 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 309 const double perp = (qy*MX(mag) - qx*MY(mag)); 310 pvec[magnetic[mag]] = (values[magnetic[mag]+2] - perp*px)*uu; 311 } 312 scattering += CALL_IQ(q, q_index, local_values); 313 } 314 if (dd > 1e-8){ 315 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 316 const double perp = (qy*MX(mag) - qx*MY(mag)); 317 pvec[magnetic[mag]] = (values[magnetic[mag]+2] + perp*px)*dd; 318 } 319 scattering += CALL_IQ(q, q_index, local_values); 320 } 321 if (ud > 1e-8){ 322 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 323 const double perp = (qy*MX(mag) - qx*MY(mag)); 324 pvec[magnetic[mag]] = perp*py*ud; 325 } 326 scattering += CALL_IQ(q, q_index, local_values); 327 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 328 pvec[magnetic[mag]] = MZ(mag)*pz*ud; 329 } 330 scattering += CALL_IQ(q, q_index, local_values); 331 } 332 if (du > 1e-8) { 333 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 334 const double perp = (qy*MX(mag) - qx*MY(mag)); 335 pvec[magnetic[mag]] = perp*py*du; 336 } 337 scattering += CALL_IQ(q, q_index, local_values); 338 for (int mag=0; mag<NUM_MAGNETIC; mag++) { 339 pvec[magnetic[mag]] = -MZ(mag)*pz*du; 340 } 341 scattering += CALL_IQ(q, q_index, local_values); 342 } 343 #else 344 double scattering = CALL_IQ(q, q_index, local_values); 345 #endif 167 346 result[q_index] += weight*scattering; 168 347 } -
sasmodels/kernelcl.py
rdef2c1b r32e3c9b 385 385 self.program = None 386 386 387 def make_kernel(self, q_vectors ):387 def make_kernel(self, q_vectors, magnetic=False): 388 388 # type: (List[np.ndarray]) -> "GpuKernel" 389 389 if self.program is None: … … 392 392 self.dtype, self.fast) 393 393 is_2d = len(q_vectors) == 2 394 kernel_name = generate.kernel_name(self.info, is_2d) 394 variant = "Imagnetic" if magnetic else "Iqxy" if is_2d else "Iq" 395 kernel_name = generate.kernel_name(self.info, variant) 395 396 kernel = getattr(self.program, kernel_name) 396 397 return GpuKernel(kernel, self.dtype, self.info, q_vectors) … … 519 520 else np.float32) # will never get here, so use np.float32 520 521 521 def __call__(self, call_details, values, cutoff ):522 # type: (CallDetails, np.ndarray, np.ndarray, float ) -> np.ndarray522 def __call__(self, call_details, values, cutoff, magnetic): 523 # type: (CallDetails, np.ndarray, np.ndarray, float, bool) -> np.ndarray 523 524 context = self.queue.context 524 525 # Arrange data transfer to card -
sasmodels/kerneldll.py
rdef2c1b r32e3c9b 270 270 # int, int, int, int*, double*, double*, double*, double*, double 271 271 argtypes = [c_int32]*3 + [c_void_p]*4 + [fp] 272 self._Iq = self._dll[generate.kernel_name(self.info, is_2d=False)] 273 self._Iqxy = self._dll[generate.kernel_name(self.info, is_2d=True)] 272 self._Iq = self._dll[generate.kernel_name(self.info, "Iq")] 273 self._Iqxy = self._dll[generate.kernel_name(self.info, "Iqxy")] 274 self._Imagnetic = self._dll[generate.kernel_name(self.info, "Imagnetic")] 274 275 self._Iq.argtypes = argtypes 275 276 self._Iqxy.argtypes = argtypes 277 self._Imagnetic.argtypes = argtypes 276 278 277 279 def __getstate__(self): … … 284 286 self._dll = None 285 287 286 def make_kernel(self, q_vectors ):288 def make_kernel(self, q_vectors, magnetic=False): 287 289 # type: (List[np.ndarray]) -> DllKernel 288 290 q_input = PyInput(q_vectors, self.dtype) … … 290 292 if self._dll is None: 291 293 self._load_dll() 292 kernel = self._Iqxyif q_input.is_2d else self._Iq294 kernel = [self._Iqxy, self._Imagnetic] if q_input.is_2d else self._Iq 293 295 return DllKernel(kernel, self.info, q_input) 294 296 … … 341 343 else np.float128) 342 344 343 def __call__(self, call_details, values, cutoff ):344 # type: (CallDetails, np.ndarray, np.ndarray, float ) -> np.ndarray345 def __call__(self, call_details, values, cutoff, magnetic): 346 # type: (CallDetails, np.ndarray, np.ndarray, float, bool) -> np.ndarray 345 347 346 348 #print("in kerneldll") … … 358 360 ] 359 361 #print("calling DLL") 360 self.kernel (*args) # type: ignore362 self.kernel[1 if magnetic else 0](*args) # type: ignore 361 363 return self.result[:-1] 362 364 -
sasmodels/kernelpy.py
ra738209 r32e3c9b 155 155 else (lambda: 1.0)) 156 156 157 def __call__(self, call_details, values, cutoff ):157 def __call__(self, call_details, values, cutoff, magnetic): 158 158 assert isinstance(call_details, details.CallDetails) 159 159 res = _loops(self._parameter_vector, self._form, self._volume, -
sasmodels/modelinfo.py
rce176ca r32e3c9b 414 414 self.kernel_parameters = parameters 415 415 self._set_vector_lengths() 416 417 self.npars = sum(p.length for p in self.kernel_parameters) 418 self.num_magnetic = sum(p.length for p in self.kernel_parameters 419 if p.type=='sld') 420 416 421 self.call_parameters = self._get_call_parameters() 417 422 self.defaults = self._get_defaults() … … 441 446 num_pd = sum(p.length for p in self.kernel_parameters if p.polydisperse) 442 447 # Don't use more polydisperse parameters than are available in the model 443 # Note: we can do polydispersity on arbitrary parameters, so it is not444 # clear that this is a good idea; it does however make the poly_details445 # code easier to write, so we will leave it in for now.446 448 self.max_pd = min(num_pd, MAX_PD) 447 448 self.npars = sum(p.length for p in self.kernel_parameters)449 449 450 450 # true if has 2D parameters 451 451 self.has_2d = any(p.type in ('orientation', 'magnetic') 452 452 for p in self.kernel_parameters) 453 self.magnetism_index = [k for k,p in enumerate(self.call_parameters) 454 if p.id.startswith('M0:')] 453 455 454 456 self.pd_1d = set(p.name for p in self.call_parameters 455 457 if p.polydisperse and p.type not in ('orientation', 'magnetic')) 456 self.pd_2d = set(p.name for p in self.call_parameters 457 if p.polydisperse and p.type != 'magnetic') 458 self.pd_2d = set(p.name for p in self.call_parameters if p.polydisperse) 458 459 459 460 def _set_vector_lengths(self): … … 519 520 pk.relative_pd = p.relative_pd 520 521 full_list.append(pk) 522 523 # Add the magnetic parameters to the end of the call parameter list. 524 if self.num_magnetic > 0: 525 full_list.extend([ 526 Parameter('up:frac_i', '', 0., [0., 1.], 527 'magnetic', 'fraction of spin up incident'), 528 Parameter('up:frac_f', '', 0., [0., 1.], 529 'magnetic', 'fraction of spin up final'), 530 Parameter('up:angle', 'degress', 0., [0., 360.], 531 'magnetic', 'spin up angle'), 532 ]) 533 slds = [p for p in full_list if p.type == 'sld'] 534 for p in slds: 535 full_list.extend([ 536 Parameter('M0:'+p.id, '1e-6/Ang^2', 0., [-np.inf, np.inf], 537 'magnetic', 'magnetic amplitude for '+p.description), 538 Parameter('mtheta:'+p.id, 'degrees', 0., [-90., 90.], 539 'magnetic', 'magnetic latitude for '+p.description), 540 Parameter('mphi:'+p.id, 'degrees', 0., [-180., 180.], 541 'magnetic', 'magnetic longitude for '+p.description), 542 ]) 543 #print("call parameters", full_list) 521 544 return full_list 522 545 … … 553 576 parameter is always returned first since the GUI will want to set it 554 577 early, and rerender the table when it is changed. 578 579 Parameters marked as sld will automatically have a set of associated 580 magnetic parameters (m0:p, mtheta:p, mphi:p), as well as polarization 581 information (up:theta, up:frac_i, up:frac_f). 555 582 """ 556 583 # control parameters go first … … 565 592 566 593 # Gather entries such as name[4] into groups of the same length 567 fixed = {} # type: Dict[int, List[Parameter]]594 fixed_length = {} # type: Dict[int, List[Parameter]] 568 595 for p in self.kernel_parameters: 569 596 if p.length > 1 and p.length_control is None: 570 fixed .setdefault(p.length, []).append(p)597 fixed_length.setdefault(p.length, []).append(p) 571 598 572 599 # Using the call_parameters table, we already have expanded forms 573 600 # for each of the vector parameters; put them in a lookup table 574 601 expanded_pars = dict((p.name, p) for p in self.call_parameters) 602 603 def append_group(name): 604 """add the named parameter, and related magnetic parameters if any""" 605 result.append(expanded_pars[name]) 606 if is2d: 607 for tag in 'M0:', 'mtheta:', 'mphi:': 608 if tag+name in expanded_pars: 609 result.append(expanded_pars[tag+name]) 575 610 576 611 # Gather the user parameters in order … … 589 624 for k in range(1, table_length+1): 590 625 for entry in table: 591 result.append(expanded_pars[entry.id+str(k)])626 append_group(entry.id+str(k)) 592 627 else: 593 628 pass # already processed all entries 594 629 elif p.length > 1: 595 table = fixed .get(p.length, [])630 table = fixed_length.get(p.length, []) 596 631 if table: 597 632 table_length = p.length 598 del fixed [p.length]633 del fixed_length[p.length] 599 634 for k in range(1, table_length+1): 600 635 for entry in table: 601 result.append(expanded_pars[entry.id+str(k)])636 append_group(entry.id+str(k)) 602 637 else: 603 638 pass # already processed all entries 604 639 else: 605 result.append(p) 640 append_group(p.id) 641 642 if is2d and 'up:angle' in expanded_pars: 643 result.extend([ 644 expanded_pars['up:frac_i'], 645 expanded_pars['up:frac_f'], 646 expanded_pars['up:angle'], 647 ]) 606 648 607 649 return result … … 634 676 if (model_info.Iq is None 635 677 and model_info.Iqxy is None 678 and model_info.Imagnetic is None 636 679 and model_info.form_volume is None): 637 680 return … … 643 686 return 644 687 for k, v in enumerate(source.split('\n')): 645 if v.startswith('Iqxy'): 688 if v.startswith('Imagnetic'): 689 model_info._Imagnetic_line = k+1 690 elif v.startswith('Iqxy'): 646 691 model_info._Iqxy_line = k+1 647 692 elif v.startswith('Iq'): … … 692 737 info.Iq = getattr(kernel_module, 'Iq', None) # type: ignore 693 738 info.Iqxy = getattr(kernel_module, 'Iqxy', None) # type: ignore 739 info.Imagnetic = getattr(kernel_module, 'Imagnetic', None) # type: ignore 694 740 info.profile = getattr(kernel_module, 'profile', None) # type: ignore 695 741 info.sesans = getattr(kernel_module, 'sesans', None) # type: ignore … … 843 889 #: Returns *I(qx, qy, a, b, ...)*. The interface follows :attr:`Iq`. 844 890 Iqxy = None # type: Union[None, str, Callable[[np.ndarray], np.ndarray]] 891 #: Returns *I(qx, qy, a, b, ...)*. The interface follows :attr:`Iq`. 892 Imagnetic = None # type: Union[None, str, Callable[[np.ndarray], np.ndarray]] 845 893 #: Returns a model profile curve *x, y*. If *profile* is defined, this 846 894 #: curve will appear in response to the *Show* button in SasView. Use … … 857 905 # line numbers within the python file for bits of C source, if defined 858 906 # NB: some compilers fail with a "#line 0" directive, so default to 1. 907 _Imagnetic_line = 1 859 908 _Iqxy_line = 1 860 909 _Iq_line = 1 -
sasmodels/sasview_model.py
rce176ca r32e3c9b 152 152 orientation_params.append(p.name+".width") 153 153 fixed.append(p.name+".width") 154 if p.type == 'magnetic':154 elif p.type == 'magnetic': 155 155 orientation_params.append(p.name) 156 156 magnetic_params.append(p.name) 157 157 fixed.append(p.name+".width") 158 158 159 159 160 # Build class dictionary … … 512 513 for p in self._model_info.parameters.call_parameters] 513 514 call_details, value = kernel.build_details(calculator, pairs) 514 result = calculator(call_details, value, cutoff=self.cutoff )515 result = calculator(call_details, value, cutoff=self.cutoff, magnetic=False) 515 516 calculator.release() 516 517 return result -
setup.py
r3a161d0 r32e3c9b 46 46 package_data={ 47 47 'sasmodels.models': ['*.c', 'lib/*.c'], 48 'sasmodels': ['*.c', '*.cl' , 'convert.json'],48 'sasmodels': ['*.c', '*.cl'], 49 49 }, 50 50 install_requires = [
Note: See TracChangeset
for help on using the changeset viewer.