source: sasmodels/sasmodel.py @ a42fec0

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

Speed-up of 3X, compare.py working

  • Property mode set to 100644
File size: 6.8 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import numpy as np
5import pyopencl as cl
6from bumps.names import Parameter
7from sans.dataloader.loader import Loader
8from sans.dataloader.manipulations import Ringcut, Boxcut
9
10
11def load_data(filename):
12    loader = Loader()
13    data = loader.load(filename)
14    if data is None:
15        raise IOError("Data %r could not be loaded"%filename)
16    return data
17
18def set_precision(src, qx, qy, dtype):
19    qx = np.ascontiguousarray(qx, dtype=dtype)
20    qy = np.ascontiguousarray(qy, dtype=dtype)
21    if np.dtype(dtype) == np.dtype('float32'):
22        header = """\
23#define real float
24"""
25    else:
26        header = """\
27#pragma OPENCL EXTENSION cl_khr_fp64: enable
28#define real double
29"""
30    return header+src, qx, qy
31
32def set_precision_1d(src, q, dtype):
33    q = np.ascontiguousarray(q, dtype=dtype)
34    if np.dtype(dtype) == np.dtype('float32'):
35        header = """\
36#define real float
37"""
38    else:
39        header = """\
40#pragma OPENCL EXTENSION cl_khr_fp64: enable
41#define real double
42"""
43    return header+src, q
44
45def set_beam_stop(data, radius, outer=None):
46    if hasattr(data, 'qx_data'):
47        data.mask = Ringcut(0, radius)(data)
48        if outer is not None:
49            data.mask += Ringcut(outer,np.inf)(data)
50    else:
51        data.mask = (data.x>=radius)
52        if outer is not None:
53            data.mask &= (data.x<outer)
54
55def set_half(data, half):
56    if half == 'right':
57        data.mask += Boxcut(x_min=-np.inf, x_max=0.0, y_min=-np.inf, y_max=np.inf)(data)
58    if half == 'left':
59        data.mask += Boxcut(x_min=0.0, x_max=np.inf, y_min=-np.inf, y_max=np.inf)(data)
60
61def set_top(data, max):
62    data.mask += Boxcut(x_min=-np.inf, x_max=np.inf, y_min=-np.inf, y_max=max)(data)
63
64def plot_data(data, iq, vmin=None, vmax=None):
65    from numpy.ma import masked_array
66    import matplotlib.pyplot as plt
67    img = masked_array(iq, data.mask)
68    xmin, xmax = min(data.qx_data), max(data.qx_data)
69    ymin, ymax = min(data.qy_data), max(data.qy_data)
70    plt.imshow(img.reshape(128,128),
71               interpolation='nearest', aspect=1, origin='upper',
72               extent=[xmin, xmax, ymin, ymax], vmin=vmin, vmax=vmax)
73
74def plot_result2D(data, theory, view='linear'):
75    import matplotlib.pyplot as plt
76    from numpy.ma import masked_array, masked
77    #print "not a number",sum(np.isnan(data.data))
78    #data.data[data.data<0.05] = 0.5
79    mdata = masked_array(data.data, data.mask)
80    mdata[np.isnan(mdata)] = masked
81    if view is 'log':
82        mdata[mdata <= 0] = masked
83        mdata = np.log10(mdata)
84        mtheory = masked_array(np.log10(theory), mdata.mask)
85    else:
86        mtheory = masked_array(theory, mdata.mask)
87    mresid = masked_array((theory-data.data)/data.err_data, data.mask)
88    vmin = min(mdata.min(), mtheory.min())
89    vmax = max(mdata.max(), mtheory.max())
90
91    plt.subplot(1, 3, 1)
92    plot_data(data, mdata, vmin=vmin, vmax=vmax)
93    plt.colorbar()
94    plt.subplot(1, 3, 2)
95    plot_data(data, mtheory, vmin=vmin, vmax=vmax)
96    plt.colorbar()
97    plt.subplot(1, 3, 3)
98    print abs(mresid).max()
99    plot_data(data, mresid)
100    plt.colorbar()
101
102
103def plot_result1D(data, theory, view='linear'):
104    import matplotlib.pyplot as plt
105    from numpy.ma import masked_array, masked
106    #print "not a number",sum(np.isnan(data.y))
107    #data.y[data.y<0.05] = 0.5
108    mdata = masked_array(data.y, data.mask)
109    mdata[np.isnan(mdata)] = masked
110    if view is 'log':
111        mdata[mdata <= 0] = masked
112    mtheory = masked_array(theory, mdata.mask)
113    mresid = masked_array((theory-data.y)/data.dy, mdata.mask)
114
115    plt.subplot(1,2,1)
116    plt.errorbar(data.x, mdata, yerr=data.dy)
117    plt.plot(data.x, mtheory, '-', hold=True)
118    plt.yscale(view)
119    plt.subplot(1, 2, 2)
120    plt.plot(data.x, mresid, 'x')
121    #plt.axhline(1, color='black', ls='--',lw=1, hold=True)
122    #plt.axhline(0, color='black', lw=1, hold=True)
123    #plt.axhline(-1, color='black', ls='--',lw=1, hold=True)
124
125
126
127GPU_CONTEXT = None
128GPU_QUEUE = None
129def card():
130    global GPU_CONTEXT, GPU_QUEUE
131    if GPU_CONTEXT is None:
132        GPU_CONTEXT = cl.create_some_context()
133        GPU_QUEUE = cl.CommandQueue(GPU_CONTEXT)
134    return GPU_CONTEXT, GPU_QUEUE
135
136
137class SasModel(object):
138    def __init__(self, data, model, dtype='float32', **kw):
139        self.__dict__['_parameters'] = {}
140        #self.name = data.filename
141        self.is2D = hasattr(data,'qx_data')
142        self.data = data
143        if self.is2D:
144            self.index = (data.mask==0) & (~np.isnan(data.data))
145            self.iq = data.data[self.index]
146            self.diq = data.err_data[self.index]
147            self.qx = data.qx_data
148            self.qy = data.qy_data
149            self.gpu = model(self.qx, self.qy, dtype=dtype)
150        else:
151            self.index = (data.mask==0) & (~np.isnan(data.y))
152            self.iq = data.y[self.index]
153            self.diq = data.dy[self.index]
154            self.q = data.x
155            self.gpu = model(self.q, dtype=dtype)
156        pd_pars = set(base+attr for base in model.PD_PARS for attr in ('_pd','_pd_n','_pd_nsigma'))
157        total_pars = set(model.PARS.keys()) | pd_pars
158        extra_pars = set(kw.keys()) - total_pars
159        if extra_pars:
160            raise TypeError("unexpected parameters %s"%(str(extra_pars,)))
161        pars = model.PARS.copy()
162        pars.update((base+'_pd', 0) for base in model.PD_PARS)
163        pars.update((base+'_pd_n', 35) for base in model.PD_PARS)
164        pars.update((base+'_pd_nsigma', 3) for base in model.PD_PARS)
165        pars.update(kw)
166        for k,v in pars.items():
167            setattr(self, k, Parameter.default(v, name=k))
168        self._parameter_names = set(pars.keys())
169        self.update()
170
171    def update(self):
172        self._cache = {}
173
174    def numpoints(self):
175        return len(self.iq)
176
177    def parameters(self):
178        return dict((k,getattr(self,k)) for k in self._parameter_names)
179
180    def theory(self):
181        if 'theory' not in self._cache:
182            pars = dict((k,getattr(self,k).value) for k in self._parameter_names)
183            #print pars
184            self._cache['theory'] = self.gpu.eval(pars)
185        return self._cache['theory']
186
187    def residuals(self):
188        #if np.any(self.err ==0): print "zeros in err"
189        return (self.theory()[self.index]-self.iq)/self.diq
190
191    def nllf(self):
192        R = self.residuals()
193        #if np.any(np.isnan(R)): print "NaN in residuals"
194        return 0.5*np.sum(R**2)
195
196    def __call__(self):
197        return 2*self.nllf()/self.dof
198
199    def plot(self, view='log'):
200        if self.is2D:
201            plot_result2D(self.data, self.theory(), view=view)
202        else:
203            plot_result1D(self.data, self.theory(), view=view)
204
205    def save(self, basename):
206        pass
207
208def demo():
209    data = load_data('DEC07086.DAT')
210    set_beam_stop(data, 0.004)
211    plot_data(data)
212    import matplotlib.pyplot as plt; plt.show()
213
214if __name__ == "__main__":
215    demo()
Note: See TracBrowser for help on using the repository browser.