source: sasview/pr_inversion/pr_test.py @ 34ae302

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 34ae302 was 9e8dc22, checked in by Mathieu Doucet <doucetm@…>, 16 years ago

Initial import.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1import math
2import pylab, numpy
3
4class PrInverse:
5   
6    D = 70.0
7    #alpha = 0.0001
8    alpha = 0.0
9   
10    data_x   = []
11    data_y   = []
12    data_err = []
13   
14    r = []
15    pr = []
16    pr_err = []
17   
18    xmult = []
19   
20    c = None
21   
22    def __init__(self, D=60.0):
23        ## Max distance
24        self.D = D
25        self.xmult = pylab.arange(0.001, self.D, self.D/21.0)
26
27    def l_multiplier(self, c):
28        return self.alpha * self._lmult2(c)
29       
30    def _lmult1(self, c):
31        sum = 0
32        for i in range(len(c)-1):
33            sum += (c[i+1]-c[i])**2
34        return sum
35   
36    def _lmult2(self, c):
37        sum = 0
38        for i in range(len(self.xmult)):
39            dp = 0
40            for j in range(len(c)):
41                dp += c[j] * self._ortho_derived(j+1, self.xmult[i])
42            sum += (dp**2)
43        return sum * self.D/len(self.xmult)
44   
45    def _ortho_transformed(self, n, q):
46        """
47            Fourier transform of the nth orthogonal function
48        """
49        return 8.0*math.pi**2/q * self.D * n * (-1)**(n+1) * \
50            math.sin(q*self.D) / ( (math.pi*n)**2 - (q*self.D)**2)
51           
52    def _ortho_derived(self, n, r):
53       
54        return 2.0*math.sin(math.pi*n*r/self.D) + 2.0*r*math.cos(math.pi*n*r/self.D) 
55   
56    def iq(self, c, q):
57        sum = 0.0
58        N = len(c)
59        #str =  ''
60        for i in range(N):
61            # n goes from 1 to N in the formulas
62            sum += c[i] * self._ortho_transformed(i+1, q)
63            #str += "c%i=%g  " % (i, c[i]);
64        #print str
65        #import time
66        #time.sleep(10)
67        return sum
68   
69    def residuals(self, params):
70        """
71            Calculates the vector of residuals for each point
72            in y for a given set of input parameters.
73            @param params: list of parameter values
74            @return: vector of residuals
75        """
76        residuals = []
77        M = len(self.data_x)
78        #lmult = self.l_multiplier(params)
79        lmult = 0
80        for j in range(M):
81            if self.data_x[j]>0.0:
82                #print j
83                value = (self.data_y[j] - self.iq(params, self.data_x[j]))**2 / self.data_err[j]**2
84                #print self.data_x[j], value, lmult/float(M)
85                value += lmult/float(M)
86                residuals.append( value )
87           
88        return residuals
89   
90    def convert_res(self, res):
91        v = numpy.asarray(res)
92        if not v.flags.contiguous:
93            print "not contiguous" 
94            v = numpy.array(res)
95       
96        print v
97        res = self.c.residuals(v)
98        print res
99        #return self.c.residuals(v)
100        return res
101   
102    def new_fit(self):
103        from sans.pr.invertor import Invertor
104        from scipy import optimize
105       
106        c = Invertor()
107        c.set_dmax(self.D)
108        c.set_x(self.data_x)
109        c.set_y(self.data_y)
110        c.set_err(self.data_err)
111       
112        out, cov_x = c.invert()
113       
114        return out, cov_x
115
116    def new_fit_0(self):
117        from sans.pr.core.pr_inversion import Cinvertor
118        from scipy import optimize
119       
120        self.c = Cinvertor()
121        self.c.set_dmax(self.D)
122        self.c.set_x(self.data_x)
123        self.c.set_y(self.data_y)
124        self.c.set_err(self.data_err)
125        print "Valid", self.c.is_valid()
126        M=10
127        p = numpy.ones(M)
128       
129        p[0] = 10.0
130       
131        out, cov_x, info, mesg, success = optimize.leastsq(self.c.residuals, p, full_output=1, warning=True)
132        #out, cov_x, info, mesg, success = optimize.leastsq(self.convert_res, p, full_output=1, warning=True)
133       
134       
135        return out, cov_x
136   
137    def fit(self):
138        return self.new_fit()
139       
140        import numpy
141        from scipy import optimize
142
143
144        M = len(self.data_x)-3
145        M=3
146        print "Number of functions: ", M
147        p = numpy.zeros(M)
148        p[0] = 1000.0
149       
150        out, cov_x, info, mesg, success = optimize.leastsq(self.residuals, p, full_output=1, warning=True)
151       
152       
153        return out, cov_x
154
155    def pr_theory(self, r, R):
156        """
157           
158        """
159        if r<=2*R:
160            return 12.0* ((0.5*r/R)**2) * ((1.0-0.5*r/R)**2) * ( 2.0 + 0.5*r/R )
161        else:
162            return 0.0
163
164
165    def residuals_pr(self, params):
166        import pylab
167       
168        residuals = []
169        M = len(self.r)
170       
171       
172        for j in range(M):
173           
174            if self.r[j]>0:
175                err2 = (self.pr_err[j])**2
176                if j>0:
177                    err2 += 0.25*(self.pr[j-1]-self.pr[j-1])**2
178                value = (self.pr[j]-self.pr_calc(params, self.r[j]))**2/err2
179                residuals.append( value )
180           
181        return residuals       
182
183    def pr_calc(self, c, r):
184        sum = 0
185        N = len(c)
186        for i in range(N):
187            sum += c[i]*2.0*r*math.sin(math.pi*(i+1)*r/self.D)
188           
189        return sum
190
191    def fill_sphere(self, radius=60):
192        import pylab
193        import numpy
194        self.r = pylab.arange(0.0, radius, radius/50.0)
195        M = len(self.r)
196        self.pr = numpy.zeros(M)
197        self.pr_err = numpy.zeros(M)
198       
199        for j in range(M):
200            self.pr[j] = self.pr_theory(self.r[j], radius)
201            self.pr_err[j] = math.sqrt(self.pr[j])
202       
203
204    def fit_pr(self):
205        import numpy
206        from scipy import optimize
207       
208       
209        M = len(self.r)-3
210        M=2
211        print "Number of functions: ", M
212        p = numpy.ones(M)
213        #p = numpy.ones(15)
214       
215        out, cov_x, info, mesg, success = optimize.leastsq(self.residuals_pr, p, full_output=1, warning=True)
216     
217        return out, cov_x
218       
219       
220
221    def load(self, path = "sphere_test_data.txt"):
222        # Read the data from the data file
223        self.data_x = numpy.zeros(0)
224        self.data_y = numpy.zeros(0)
225        self.data_err = numpy.zeros(0)
226        if not path == None:
227            input_f = open(path,'r')
228            buff = input_f.read()
229            lines = buff.split('\n')
230            for line in lines:
231                try:
232                    toks = line.split()
233                    x = float(toks[0])
234                    y = float(toks[1])
235                    self.data_x = numpy.append(self.data_x, x)
236                    self.data_y = numpy.append(self.data_y, y)
237                    self.data_err = numpy.append(self.data_err, math.sqrt(y)+1000.0)
238                except:
239                    print "Error reading line: ", line
240                   
241        print "Lines read:", len(self.data_x)
242       
243
244if __name__ == "__main__": 
245    from sans.pr.core.pr_inversion import Cinvertor
246    pr = PrInverse()
247    pr.load("sphere_80.txt")
248    out, cov = pr.fit()
249   
250    print "output:"
251    print out
252   
Note: See TracBrowser for help on using the repository browser.