source: sasmodels/capcylcope.py @ 8a20be5

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 8a20be5 was 8a20be5, checked in by HMP1 <helen.park@…>, 10 years ago

Added a fit2 (fits two different models at different angles)
(preliminary) Added CoreshellCyl? and CapCyl? Kernels
(preliminary) Updated kernels to include functions

  • Property mode set to 100644
File size: 3.6 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import numpy as np
5from math import asin
6import pyopencl as cl
7from weights import GaussianDispersion
8
9class GpuCapCylinder(object):
10    PARS = {'scale':1, 'rad_cyl':1, 'rad_cap':1, 'length':1, 'sld_capcyl':1e-6, 'sld_solv':0, 'background':0,
11             'theta':0, 'phi':0}
12
13    PD_PARS = ['rad_cyl', 'length', 'rad_cap', 'theta', 'phi']
14
15    def __init__(self, qx, qy):
16
17        self.qx = np.asarray(qx, np.float32)
18        self.qy = np.asarray(qy, np.float32)
19        #create context, queue, and build program
20        self.ctx = cl.create_some_context()
21        self.queue = cl.CommandQueue(self.ctx)
22
23        self.prg = cl.Program(self.ctx, open('Kernel-CapCyl.cpp').read()).build()
24
25        #buffers
26        mf = cl.mem_flags
27        self.qx_b = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=self.qx)
28        self.qy_b = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=self.qy)
29        self.res_b = cl.Buffer(self.ctx, mf.WRITE_ONLY, qx.nbytes)
30        self.res = np.empty_like(self.qx)
31        self.vol_i = float(0.0)
32        self.vol_b = cl.Buffer(self.ctx, mf.WRITE_ONLY, self.vol_i.nbytes)
33
34    def eval(self, pars):
35
36        rad_cyl,length,rad_cap,theta,phi = \
37            [GaussianDispersion(int(pars[base+'_pd_n']), pars[base+'_pd'], pars[base+'_pd_nsigma'])
38             for base in GpuCapCylinder.PD_PARS]
39
40        rad_cyl.value, rad_cyl.weight = rad_cyl.get_weights(pars['rad_cyl'], 0, 1000, True)
41        rad_cap.value, rad_cap.weight = rad_cap.get_weights(pars['rad_cap'], 0, 1000, True)
42        length.value, length.weight = length.get_weights(pars['length'], 0, 1000, True)
43        theta.value, theta.weight = theta.get_weights(pars['theta'], -90, 180, False)
44        phi.value, phi.weight = phi.get_weights(pars['phi'], -90, 180, False)
45
46        sum, norm, norm_vol, vol = 0.0, 0.0, 0.0, 0.0
47        size = len(theta.weight)
48        sub = pars['sld_capcyl']-np.float32(['sld_solv'])
49
50        for i in xrange(len(rad_cyl.weight)):
51            for m in xrange(len(rad_cap.weight)):
52                for j in xrange(len(length.weight)):
53                    for k in xrange(len(theta.weight)):
54                        for l in xrange(len(phi.weight)):
55
56                            self.prg.CapCylinderKernel(self.queue, self.qx.shape, None, self.qx_b, self.qy_b, self.res_b,
57                                        self.vol_b, np.float32(rad_cyl.value[i]), np.float32(rad_cap.value[m]), np.float32(length.value[j]),
58                                        np.float32(theta.value[k]), np.float32(phi.value[l]), np.float32(sub), np.float32(pars['scale']),
59                                        np.float32(phi.weight[l]), np.float32(theta.weight[k]), np.float32(rad_cap.weight[m]),
60                                        np.float32(rad_cyl.weight[i]), np.float32(length.weight[j]), np.uint32(self.qx.size), np.uint32(size))
61
62                            cl.enqueue_copy(self.queue, self.res, self.res_b)
63                            cl.enqueue_copy(self.queue, self.vol_i, self.vol_b)
64
65                            sum += self.res
66                            vol += rad_cyl.weight[i]*length.weight[j]*rad_cap.weight[m]*self.vol_i
67                            norm_vol += rad_cyl.weight[i]*length.weight[j]*rad_cap.weight[m]
68                            norm += rad_cyl.weight[i]*length.weight[j]*rad_cap.weight[m]*theta.weight[k]*phi.weight[l]
69
70        if size > 1:
71            norm /= asin(1.0)
72
73        if vol != 0.0 and norm_vol != 0.0:
74            sum *= norm_vol/vol
75
76        return sum/norm + pars['background']
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
Note: See TracBrowser for help on using the repository browser.