Changeset 6ddd6e0 in sasmodels
- Timestamp:
- Mar 18, 2016 2:16:21 AM (9 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:
- 30c2ac3
- Parents:
- 02e70ff (diff), c094758 (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. - Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/genmodel.py
raa2edb2 rc094758 10 10 # Convert ../sasmodels/models/name.py to name 11 11 model_name = os.path.basename(sys.argv[1])[:-3] 12 model_info = core.load_model_info(model_name) 13 model = core.build_model(model_info) 12 14 13 15 # Load the doc string from the module definition file and store it in rst 14 docstr = generate.make_doc(core.load_model_info(model_name)) 15 16 # Generate automatically plot of the model and add it to rst documentation 16 docstr = generate.make_doc(model_info) 17 17 18 info = core.load_model_info(model_name)19 18 20 19 # Calculate 1D curve for default parameters 21 pars = dict((p [0], p[2]) for p ininfo['parameters'])20 pars = dict((p.name, p.default) for p in model_info['parameters']) 22 21 23 22 # Plotting ranges and options 24 23 opts = { 25 'xscale' : 'log', 26 'yscale' : 'log' if not info['structure_factor'] else 'linear', 27 'qmin' : 0.001, 28 'qmax' : 1.0, 29 'nq' : 1000, 30 'nq2d' : 100, 24 'xscale' : 'log', 25 'yscale' : 'log' if not model_info['structure_factor'] else 'linear', 26 'zscale' : 'log' if not model_info['structure_factor'] else 'linear', 27 'q_min' : 0.001, 28 'q_max' : 1.0, 29 'nq' : 1000, 30 'nq2d' : 400, 31 'vmin' : 1e-3, # floor for the 2D data results 32 'qx_max' : 0.5, 31 33 } 32 34 33 qmin, qmax, nq = opts['qmin'], opts['qmax'], opts['nq']34 qmin = math.log10(qmin)35 qmax = math.log10(qmax)36 q = np.logspace(qmin, qmax, nq)37 data = empty_data1D(q)38 model = core.load_model(model_name)39 calculator = DirectModel(data, model)40 Iq1D = calculator()41 35 42 # TO DO: Generation of 2D plots 43 # Problem in sasmodels.direct_model._calc_theory 44 # There self._kernel.q_input.nq gets a value of 0 in the 2D case 45 # and returns a 0 numpy array (it does not call the C code) 36 def plot_1d(model, opts, ax): 37 q_min, q_max, nq = opts['q_min'], opts['q_max'], opts['nq'] 38 q_min = math.log10(q_min) 39 q_max = math.log10(q_max) 40 q = np.logspace(q_min, q_max, nq) 41 data = empty_data1D(q) 42 calculator = DirectModel(data, model) 43 Iq1D = calculator() 46 44 47 # If 2D model, compute 2D image 48 #if info['has_2d'] != []: 49 # qmax, nq2d = opts['qmax'], opts['nq2d'] 50 # data2d = empty_data2D(np.linspace(-qmax, qmax, nq2d), resolution=0.0) 51 # #model = core.load_model(model_name) 52 # calculator = DirectModel(data2d, model) 53 # Iq2D = calculator() 45 ax.plot(q, Iq1D, color='blue', lw=2, label=model_info['name']) 46 ax.set_xlabel(r'$Q \/(\AA^{-1})$') 47 ax.set_ylabel(r'$I(Q) \/(\mathrm{cm}^{-1})$') 48 ax.set_xscale(opts['xscale']) 49 ax.set_yscale(opts['yscale']) 50 #ax.legend(loc='best') 51 52 def plot_2d(model, opts, ax): 53 qx_max, nq2d = opts['qx_max'], opts['nq2d'] 54 q = np.linspace(-qx_max, qx_max, nq2d) 55 data2d = empty_data2D(q, resolution=0.0) 56 calculator = DirectModel(data2d, model) 57 Iq2D = calculator() #background=0) 58 Iq2D = Iq2D.reshape(nq2d, nq2d) 59 if opts['zscale'] == 'log': 60 Iq2D = np.log(np.clip(Iq2D, opts['vmin'], np.inf)) 61 h = ax.imshow(Iq2D, interpolation='nearest', aspect=1, origin='upper', 62 extent=[-qx_max, qx_max, -qx_max, qx_max], cmap=ice_cm()) 63 # , vmin=vmin, vmax=vmax) 64 ax.set_xlabel(r'$Q_x \/(\AA^{-1})$') 65 ax.set_ylabel(r'$Q_y \/(\AA^{-1})$') 66 67 def ice_cm(): 68 from matplotlib._cm import _Blues_data 69 from matplotlib import colors 70 from matplotlib import rcParams 71 def from_white(segments): 72 scale = 1.0/segments[0][1] 73 return [(k, v*scale, w*scale) for k, v, w in segments] 74 ice_data = dict((k,from_white(v)) for k,v in _Blues_data.items()) 75 ice = colors.LinearSegmentedColormap("ice", ice_data, rcParams['image.lut']) 76 return ice 77 54 78 55 79 # Generate image (comment IF for 1D/2D for the moment) and generate only 1D 56 #if info['has_2d'] == []: 57 # fig = plt.figure() 58 # ax = fig.add_subplot(1,1,1) 59 # ax.plot(q, Iq1D, color='blue', lw=2, label=model_name) 60 # ax.set_xlabel(r'$Q \/(\AA^{-1})$') 61 # ax.set_xscale(opts['xscale']) 62 # ax.set_ylabel(r'$I(Q) \/(\mathrm{cm}^{-1})$') 63 # ax.set_yscale(opts['yscale']) 64 # ax.legend() 65 #else: 66 # # need figure with 1D + 2D 67 # pass 68 fig = plt.figure() 69 ax = fig.add_subplot(1,1,1) 70 ax.plot(q, Iq1D, color='blue', lw=2, label=info['name']) 71 ax.set_xlabel(r'$Q \/(\AA^{-1})$') 72 ax.set_xscale(opts['xscale']) 73 ax.set_ylabel(r'$I(Q) \/(\mathrm{cm}^{-1})$') 74 ax.set_yscale(opts['yscale']) 75 ax.legend() 76 80 fig_height = 3.0 # in 81 fig_left = 0.6 # in 82 fig_right = 0.5 # in 83 fig_top = 0.6*0.25 # in 84 fig_bottom = 0.6*0.75 85 if model_info['has_2d']: 86 plot_height = fig_height - (fig_top+fig_bottom) 87 plot_width = plot_height 88 fig_width = 2*(plot_width + fig_left + fig_right) 89 aspect = (fig_width, fig_height) 90 ratio = aspect[0]/aspect[1] 91 ax_left = fig_left/fig_width 92 ax_bottom = fig_bottom/fig_height 93 ax_height = plot_height/fig_height 94 ax_width = ax_height/ratio # square axes 95 fig = plt.figure(figsize=aspect) 96 ax2d = fig.add_axes([0.5+ax_left, ax_bottom, ax_width, ax_height]) 97 plot_2d(model, opts, ax2d) 98 ax1d = fig.add_axes([ax_left, ax_bottom, ax_width, ax_height]) 99 #ax.set_aspect('square') 100 else: 101 plot_height = fig_height - (fig_top+fig_bottom) 102 plot_width = (1+np.sqrt(5))/2*fig_height 103 fig_width = plot_width + fig_left + fig_right 104 ax_left = fig_left/fig_width 105 ax_bottom = fig_bottom/fig_height 106 ax_width = plot_width/fig_width 107 ax_height = plot_height/fig_height 108 aspect = (fig_width, fig_height) 109 fig = plt.figure(figsize=aspect) 110 ax1d = fig.add_axes([ax_left, ax_bottom, ax_width, ax_height]) 111 plot_1d(model, opts, ax1d) 77 112 78 113 # Save image in model/img 79 114 figname = model_name + '_autogenfig.png' 80 115 filename = os.path.join('model', 'img', figname) 81 plt.savefig(filename) 116 plt.savefig(filename, bbox_inches='tight') 117 #print "figure saved in",filename 82 118 83 119 # Auto caption for figure 84 120 captionstr = '\n' 85 captionstr += '.. figure:: img/' + model_ name+ '_autogenfig.png\n'121 captionstr += '.. figure:: img/' + model_info['id'] + '_autogenfig.png\n' 86 122 captionstr += '\n' 87 #if info['has_2d'] == []:88 # captionstr += ' 1D plot corresponding to the default parameters of the model.\n'89 #else:90 # captionstr += ' 1D and 2D plots corresponding to the default parameters of the model.\n'91 123 captionstr += ' 1D plot corresponding to the default parameters of the model.\n' 92 124 captionstr += '\n' … … 102 134 else: 103 135 print '------------------------------------------------------------------' 104 print 'References NOT FOUND for model: ', model_ name136 print 'References NOT FOUND for model: ', model_info['id'] 105 137 print '------------------------------------------------------------------' 106 138 docstr = docstr + captionstr -
explore/J1c.py
r0a6da3c rcbd37a7 9 9 10 10 11 SHOW_DIFF = True # True if show diff rather than function value 11 SHOW_DIFF = True # True if show diff rather than function value 12 #SHOW_DIFF = False # True if show diff rather than function value 12 13 LINEAR_X = False # True if q is linearly spaced instead of log spaced 14 #LINEAR_X = True # True if q is linearly spaced instead of log spaced 15 FUNCTION = "2*J1(x)/x" 13 16 14 def mp_ J1c(vec, bits=500):17 def mp_fn(vec, bits=500): 15 18 """ 16 19 Direct calculation using sympy multiprecision library. 17 20 """ 18 21 with mp.workprec(bits): 19 return [_mp_ J1c(mp.mpf(x)) for x in vec]22 return [_mp_fn(mp.mpf(x)) for x in vec] 20 23 21 def _mp_ J1c(x):24 def _mp_fn(x): 22 25 """ 23 Helper funciton for mp_j1c26 Actual function that gets evaluated. The caller just vectorizes. 24 27 """ 25 28 return mp.mpf(2)*mp.j1(x)/x 26 29 27 def np_ J1c(x, dtype):30 def np_fn(x, dtype): 28 31 """ 29 32 Direct calculation using scipy. … … 33 36 return np.asarray(2, dtype)*J1(x)/x 34 37 35 def cephes_J1c(x, dtype, n):38 def sasmodels_fn(x, dtype, platform='ocl'): 36 39 """ 37 40 Calculation using pade approximant. 38 41 """ 39 f = np.float64 if np.dtype(dtype) == np.float64 else np.float32 40 x = np.asarray(x, dtype) 41 ans = np.empty_like(x) 42 ax = abs(x) 43 44 # Branch a 45 a_idx = ax < f(8.0) 46 a_xsq = x[a_idx]**2 47 a_coeff1 = list(reversed((72362614232.0, -7895059235.0, 242396853.1, -2972611.439, 15704.48260, -30.16036606))) 48 a_coeff2 = list(reversed((144725228442.0, 2300535178.0, 18583304.74, 99447.43394, 376.9991397, 1.0))) 49 a_ans1 = np.polyval(np.asarray(a_coeff1[n:], dtype), a_xsq) 50 a_ans2 = np.polyval(np.asarray(a_coeff2[n:], dtype), a_xsq) 51 ans[a_idx] = f(2.0)*a_ans1/a_ans2 52 53 # Branch b 54 b_idx = ~a_idx 55 b_ax = ax[b_idx] 56 b_x = x[b_idx] 57 58 b_y = f(64.0)/(b_ax**2) 59 b_xx = b_ax - f(2.356194491) 60 b_coeff1 = list(reversed((1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6))) 61 b_coeff2 = list(reversed((0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6))) 62 b_ans1 = np.polyval(np.asarray(b_coeff1[n:], dtype),b_y) 63 b_ans2 = np.polyval(np.asarray(b_coeff2[n:], dtype), b_y) 64 b_sn, b_cn = np.sin(b_xx), np.cos(b_xx) 65 ans[b_idx] = np.sign(b_x)*np.sqrt(f(0.636619772)/b_ax) * (b_cn*b_ans1 - (f(8.0)/b_ax)*b_sn*b_ans2)*f(2.0)/b_x 66 67 return ans 68 69 def div_J1c(x, dtype): 70 f = np.float64 if np.dtype(dtype) == np.float64 else np.float32 71 x = np.asarray(x, dtype) 72 return f(2.0)*np.asarray([_J1(xi, f)/xi for xi in x], dtype) 73 74 def _J1(x, f): 75 ax = abs(x) 76 if ax < f(8.0): 77 y = x*x 78 ans1 = x*(f(72362614232.0) 79 + y*(f(-7895059235.0) 80 + y*(f(242396853.1) 81 + y*(f(-2972611.439) 82 + y*(f(15704.48260) 83 + y*(f(-30.16036606))))))) 84 ans2 = (f(144725228442.0) 85 + y*(f(2300535178.0) 86 + y*(f(18583304.74) 87 + y*(f(99447.43394) 88 + y*(f(376.9991397) 89 + y))))) 90 return ans1/ans2 91 else: 92 y = f(64.0)/(ax*ax) 93 xx = ax - f(2.356194491) 94 ans1 = (f(1.0) 95 + y*(f(0.183105e-2) 96 + y*(f(-0.3516396496e-4) 97 + y*(f(0.2457520174e-5) 98 + y*f(-0.240337019e-6))))) 99 ans2 = (f(0.04687499995) 100 + y*(f(-0.2002690873e-3) 101 + y*(f(0.8449199096e-5) 102 + y*(f(-0.88228987e-6) 103 + y*f(0.105787412e-6))))) 104 sn, cn = np.sin(xx), np.cos(xx) 105 ans = np.sqrt(f(0.636619772)/ax) * (cn*ans1 - (f(8.0)/ax)*sn*ans2) 106 return -ans if (x < f(0.0)) else ans 42 from sasmodels import core, data, direct_model 43 model = core.load_model('bessel', dtype=dtype) 44 calculator = direct_model.DirectModel(data.empty_data1D(x), model) 45 return calculator(background=0) 107 46 108 47 def plotdiff(x, target, actual, label): … … 113 52 """ 114 53 if SHOW_DIFF: 115 err = np.clip(abs((target-actual)/target), 0, 1) 54 err = abs((target-actual)/target) 55 #err = np.clip(err, 0, 1) 116 56 pylab.loglog(x, err, '-', label=label) 117 57 else: … … 119 59 pylab.semilogx(x, np.clip(actual,*limits), '-', label=label) 120 60 121 def compare(x, precision ):61 def compare(x, precision, target): 122 62 r""" 123 63 Compare the different computation methods using the given precision. 124 64 """ 125 target = np.asarray(mp_J1c(x), 'double') 126 #plotdiff(x, target, mp_J1c(x, 11), 'mp 11 bits') 127 plotdiff(x, target, np_J1c(x, precision), 'direct '+precision) 128 plotdiff(x, target, cephes_J1c(x, precision, 0), 'cephes '+precision) 129 #plotdiff(x, target, cephes_J1c(x, precision, 1), 'cephes '+precision) 130 #plotdiff(x, target, div_J1c(x, precision), 'cephes 2 J1(x)/x '+precision) 65 #plotdiff(x, target, mp_fn(x, 11), 'mp 11 bits') 66 plotdiff(x, target, np_fn(x, precision), 'numpy '+precision) 67 plotdiff(x, target, sasmodels_fn(x, precision, 0), 'sasmodels '+precision) 131 68 pylab.xlabel("qr (1/Ang)") 132 69 if SHOW_DIFF: 133 70 pylab.ylabel("relative error") 134 71 else: 135 pylab.ylabel( "2 J1(x)/x")72 pylab.ylabel(FUNCTION) 136 73 pylab.semilogx(x, target, '-', label="true value") 137 74 if LINEAR_X: … … 147 84 else: 148 85 qr = np.logspace(-3,5,400) 86 target = np.asarray(mp_fn(qr), 'double') 149 87 pylab.subplot(121) 150 compare(qr, 'single' )88 compare(qr, 'single', target) 151 89 pylab.legend(loc='best') 152 90 pylab.subplot(122) 153 compare(qr, 'double' )91 compare(qr, 'double', target) 154 92 pylab.legend(loc='best') 155 pylab.suptitle( '2 J1(x)/x')93 pylab.suptitle(FUNCTION) 156 94 157 95 if __name__ == "__main__": -
sasmodels/data.py
r84db7a5 rc094758 178 178 self.qy_data, self.dqy_data = y, dy 179 179 self.data, self.err_data = z, dz 180 self.mask = ( ~np.isnan(z) if z is not None181 else np. ones_like(x) if x is not None180 self.mask = (np.isnan(z) if z is not None 181 else np.zeros_like(x, dtype='bool') if x is not None 182 182 else None) 183 183 self.q_data = np.sqrt(x**2 + y**2) -
sasmodels/kernelcl.py
r17bbadd rc094758 367 367 self.q_vectors = [_stretch_input(q, self.dtype, 32) for q in q_vectors] 368 368 context = env.get_context(self.dtype) 369 self.global_size = [self.q_vectors[0].size] 370 #print("creating inputs of size", self.global_size) 369 371 self.q_buffers = [ 370 372 cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=q) 371 373 for q in self.q_vectors 372 374 ] 373 self.global_size = [self.q_vectors[0].size]374 375 375 376 def release(self): -
sasmodels/models/bessel.py
r07142f3 rcbd37a7 67 67 #Bessel 68 68 parameters = [ 69 ["ignored", "", 0.0, [-inf, inf], "", "no parameterless functions"], 69 70 ] 70 71 71 source = ["lib/polevl.c", "lib/j1 d.c"]72 source = ["lib/polevl.c", "lib/j1_cephes.c"] 72 73 73 74 # No volume normalization despite having a volume parameter … … 77 78 78 79 Iq = """ 79 return j1(q);80 return 2.0*j1(q)/q; 80 81 """ 81 82 -
sasmodels/models/lib/j0_cephes.c
rbfef528 r094e320 44 44 */ 45 45 46 /* y0.c47 *48 * Bessel function of the second kind, order zero49 *50 *51 *52 * SYNOPSIS:53 *54 * double x, y, y0();55 *56 * y = y0( x );57 *58 *59 *60 * DESCRIPTION:61 *62 * Returns Bessel function of the second kind, of order63 * zero, of the argument.64 *65 * The domain is divided into the intervals [0, 5] and66 * (5, infinity). In the first interval a rational approximation67 * R(x) is employed to compute68 * y0(x) = R(x) + 2 * log(x) * j0(x) / PI.69 * Thus a call to j0() is required.70 *71 * In the second interval, the Hankel asymptotic expansion72 * is employed with two rational functions of degree 6/673 * and 7/7.74 *75 *76 *77 * ACCURACY:78 *79 * Absolute error, when y0(x) < 1; else relative error:80 *81 * arithmetic domain # trials peak rms82 * DEC 0, 30 9400 7.0e-17 7.9e-1883 * IEEE 0, 30 30000 1.3e-15 1.6e-1684 *85 */86 87 46 88 47 /* … … 95 54 96 55 double j0( double ); 97 98 56 double j0(double x) { 99 57 … … 291 249 292 250 q = 1.0/x; 293 w = sqrt f(q);251 w = sqrt(q); 294 252 295 253 p = w * polevl( q, MO, 7); 296 254 w = q*q; 297 255 xn = q * polevl( w, PH, 7) - PIO4F; 298 p = p * cos f(xn + xx);256 p = p * cos(xn + xx); 299 257 return(p); 300 258 #endif -
sasmodels/models/lib/j1_cephes.c
rbfef528 re2af2a9 32 32 * IEEE 0, 30 30000 2.6e-16 1.1e-16 33 33 * 34 *35 */36 /* y1.c37 *38 * Bessel function of second kind of order one39 *40 *41 *42 * SYNOPSIS:43 *44 * double x, y, y1();45 *46 * y = y1( x );47 *48 *49 *50 * DESCRIPTION:51 *52 * Returns Bessel function of the second kind of order one53 * of the argument.54 *55 * The domain is divided into the intervals [0, 8] and56 * (8, infinity). In the first interval a 25 term Chebyshev57 * expansion is used, and a call to j1() is required.58 * In the second, the asymptotic trigonometric representation59 * is employed using two rational functions of degree 5/5.60 *61 *62 *63 * ACCURACY:64 *65 * Absolute error:66 * arithmetic domain # trials peak rms67 * DEC 0, 30 10000 8.6e-17 1.3e-1768 * IEEE 0, 30 30000 1.0e-15 1.3e-1669 *70 * (error criterion relative when |y1| > 1).71 34 * 72 35 */ -
sasmodels/models/lib/polevl.c
r3936ad3 re2af2a9 50 50 Direct inquiries to 30 Frost Street, Cambridge, MA 02140 51 51 */ 52 52 53 double polevl( double x, double coef[8], int N ); 53 54 double p1evl( double x, double coef[8], int N ); -
example/sesansfit.py
r84db7a5 r02e70ff 8 8 HAS_CONVERTER = False 9 9 10 10 11 def get_bumps_model(model_name): 11 12 kernel = core.load_model(model_name) 12 13 model = bumps_model.Model(kernel) 13 14 return model 15 16 def sesans_fit(file, model_name, initial_vals={}, custom_params={}, param_range=[], acceptance_angle=None): 17 """ 14 18 15 19 def sesans_fit(file, model, initial_vals={}, custom_params={}, param_range=[]): … … 55 59 dy = err_data 56 60 sample = Sample() 61 acceptance_angle = acceptance_angle 62 needs_all_q = acceptance_angle is not None 57 63 data = SESANSData1D() 58 64 -
sasmodels/core.py
r7b3e62c r02e70ff 176 176 return value, weight 177 177 178 def call_kernel(kernel, pars, cutoff=0 ):178 def call_kernel(kernel, pars, cutoff=0, mono=False): 179 179 """ 180 180 Call *kernel* returned from :func:`make_kernel` with parameters *pars*. … … 189 189 fixed_pars = [pars.get(name, kernel.info['defaults'][name]) 190 190 for name in kernel.fixed_pars] 191 pd_pars = [get_weights(kernel.info, pars, name) for name in kernel.pd_pars] 191 if mono: 192 pd_pars = [( np.array([pars[name]]), np.array([1.0]) ) 193 for name in kernel.pd_pars] 194 else: 195 pd_pars = [get_weights(kernel.info, pars, name) for name in kernel.pd_pars] 192 196 return kernel(fixed_pars, pd_pars, cutoff=cutoff) 193 197 -
sasmodels/direct_model.py
r17bbadd r02e70ff 69 69 70 70 if self.data_type == 'sesans': 71 71 72 q = sesans.make_q(data.sample.zacceptance, data.Rmax) 72 73 index = slice(None, None) … … 77 78 Iq, dIq = None, None 78 79 #self._theory = np.zeros_like(q) 79 q_vectors = [q] 80 q_vectors = [q] 81 q_mono = sesans.make_all_q(data) 80 82 elif self.data_type == 'Iqxy': 81 83 if not partype['orientation'] and not partype['magnetic']: … … 96 98 #self._theory = np.zeros_like(self.Iq) 97 99 q_vectors = res.q_calc 100 q_mono = [] 98 101 elif self.data_type == 'Iq': 99 102 index = (data.x >= data.qmin) & (data.x <= data.qmax) … … 120 123 #self._theory = np.zeros_like(self.Iq) 121 124 q_vectors = [res.q_calc] 125 q_mono = [] 122 126 else: 123 127 raise ValueError("Unknown data type") # never gets here … … 125 129 # Remember function inputs so we can delay loading the function and 126 130 # so we can save/restore state 127 self._kernel_inputs = [v for v in q_vectors] 131 self._kernel_inputs = q_vectors 132 self._kernel_mono_inputs = q_mono 128 133 self._kernel = None 129 134 self.Iq, self.dIq, self.index = Iq, dIq, index … … 149 154 def _calc_theory(self, pars, cutoff=0.0): 150 155 if self._kernel is None: 151 self._kernel = make_kernel(self._model, self._kernel_inputs) # pylint: disable=attribute-defined-outside-init 156 self._kernel = make_kernel(self._model, self._kernel_inputs) # pylint: disable=attribute-dedata_type 157 self._kernel_mono = make_kernel(self._model, self._kernel_mono_inputs) if self._kernel_mono_inputs else None 152 158 153 159 Iq_calc = call_kernel(self._kernel, pars, cutoff=cutoff) 160 Iq_mono = call_kernel(self._kernel_mono, pars, mono=True) if self._kernel_mono_inputs else None 154 161 if self.data_type == 'sesans': 155 result = sesans. hankel(self._data.x, self._data.lam * 1e-9,156 self._ data.sample.thickness / 10,157 self._kernel_ inputs[0], Iq_calc)162 result = sesans.transform(self._data, 163 self._kernel_inputs[0], Iq_calc, 164 self._kernel_mono_inputs, Iq_mono) 158 165 else: 159 166 result = self.resolution.apply(Iq_calc) 160 return result 167 return result 161 168 162 169 -
sasmodels/sesans.py
r190fc2b r02e70ff 13 13 from numpy import pi, exp 14 14 from scipy.special import jv as besselj 15 15 #import direct_model.DataMixin as model 16 16 17 def make_q(q_max, Rmax): 17 18 r""" … … 21 22 q_min = dq = 0.1 * 2*pi / Rmax 22 23 return np.arange(q_min, q_max, dq) 24 25 def make_allq(data): 26 if not data.needs_all_q: 27 return [] 28 elif needs_Iqxy(data): 29 # compute qx, qy 30 Qx, Qy = np.meshgrid(qx, qy) 31 return [Qx, Qy] 32 else: 33 # else only need q 34 return [q] 23 35 36 def transform(data, q_calc, Iq_calc, qmono, Iq_mono): 37 nqmono = len(qmono) 38 if nqmono == 0: 39 result = call_hankel(data, q_calc, Iq_calc) 40 elif nqmono == 1: 41 q = qmono[0] 42 result = call_HankelAccept(data, q_calc, Iq_calc, q, Iq_mono) 43 else: 44 Qx, Qy = [qmono[0], qmono[1]] 45 Qx = np.reshape(Qx, nqx, nqy) 46 Qy = np.reshape(Qy, nqx, nqy) 47 Iq_mono = np.reshape(Iq_mono, nqx, nqy) 48 qx = Qx[0, :] 49 qy = Qy[:, 0] 50 result = call_Cosine2D(data, q_calc, Iq_calc, qx, qy, Iq_mono) 51 52 return result 53 54 def call_hankel(data, q_calc, Iq_calc): 55 return hankel(data.x, data.lam * 1e-9, 56 data.sample.thickness / 10, 57 q_calc, Iq_calc) 58 59 def call_HankelAccept(data, q_calc, Iq_calc, q_mono, Iq_mono): 60 return hankel(data.x, data.lam * 1e-9, 61 data.sample.thickness / 10, 62 q_calc, Iq_calc) 63 64 def Cosine2D(data, q_calc, Iq_calc, qx, qy, Iq_mono): 65 return hankel(data.x, data.y data.lam * 1e-9, 66 data.sample.thickness / 10, 67 q_calc, Iq_calc) 68 69 def TotalScatter(model, parameters): #Work in progress!! 70 # Calls a model with existing model parameters already in place, then integrate the product of q and I(q) from 0 to (4*pi/lambda) 71 allq = np.linspace(0,4*pi/wavelength,1000) 72 allIq = 73 integral = allq*allIq 74 75 76 77 def Cosine2D(wavelength, magfield, thickness, qy, qz, Iqy, Iqz, modelname): #Work in progress!! Needs to call model still 78 #============================================================================== 79 # 2D Cosine Transform if "wavelength" is a vector 80 #============================================================================== 81 #allq is the q-space needed to create the total scattering cross-section 82 83 Gprime = np.zeros_like(wavelength, 'd') 84 s = np.zeros_like(wavelength, 'd') 85 sd = np.zeros_like(wavelength, 'd') 86 Gprime = np.zeros_like(wavelength, 'd') 87 f = np.zeros_like(wavelength, 'd') 88 for i, wavelength_i in enumerate(wavelength): 89 z = magfield*wavelength_i 90 allq=np.linspace() #for calculating the Q-range of the scattering power integral 91 allIq=np.linspace() # This is the model applied to the allq q-space. Needs to refference the model somehow 92 alldq = (allq[1]-allq[0])*1e10 93 sigma[i]=wavelength[i]^2*thickness/2/pi*np.sum(allIq*allq*alldq) 94 s[i]=1-exp(-sigma) 95 for j, Iqy_j, qy_j in enumerate(qy): 96 for k, Iqz_k, qz_k in enumerate(qz): 97 Iq = np.sqrt(Iqy_j^2+Iqz_k^2) 98 q = np.sqrt(qy_j^2 + qz_k^2) 99 Gintegral = Iq*cos(z*Qz_k) 100 Gprime[i] += Gintegral 101 # sigma = wavelength^2*thickness/2/pi* allq[i]*allIq[i] 102 # s[i] += 1-exp(Totalscatter(modelname)*thickness) 103 # For now, work with standard 2-phase scatter 104 105 106 sd[i] += Iq 107 f[i] = 1-s[i]+sd[i] 108 P[i] = (1-sd[i]/f[i])+1/f[i]*Gprime[i] 109 110 111 112 113 def HankelAccept(wavelength, magfield, thickness, q, Iq, theta, modelname): 114 #============================================================================== 115 # HankelTransform with fixed circular acceptance angle (circular aperture) for Time of Flight SESANS 116 #============================================================================== 117 #acceptq is the q-space needed to create limited acceptance effect 118 SElength= wavelength*magfield 119 G = np.zeros_like(SElength, 'd') 120 threshold=2*pi*theta/wavelength 121 for i, SElength_i in enumerate(SElength): 122 allq=np.linspace() #for calculating the Q-range of the scattering power integral 123 allIq=np.linspace() # This is the model applied to the allq q-space. Needs to refference the model somehow 124 alldq = (allq[1]-allq[0])*1e10 125 sigma[i]=wavelength[i]^2*thickness/2/pi*np.sum(allIq*allq*alldq) 126 s[i]=1-exp(-sigma) 127 128 dq = (q[1]-q[0])*1e10 129 a = (x<threshold) 130 acceptq = a*q 131 acceptIq = a*Iq 132 133 G[i] = np.sum(besselj(0, acceptq*SElength_i)*acceptIq*acceptq*dq) 134 135 # G[i]=np.sum(integral) 136 137 G *= dq*1e10*2*pi 138 139 P = exp(thickness*wavelength**2/(4*pi**2)*(G-G[0])) 140 24 141 def hankel(SElength, wavelength, thickness, q, Iq): 25 142 r""" … … 44 161 """ 45 162 G = np.zeros_like(SElength, 'd') 163 #============================================================================== 164 # Hankel Transform method if "wavelength" is a scalar; mono-chromatic SESANS 165 #============================================================================== 46 166 for i, SElength_i in enumerate(SElength): 47 167 integral = besselj(0, q*SElength_i)*Iq*q
Note: See TracChangeset
for help on using the changeset viewer.