1 | # -*- coding: utf-8 -*- |
---|
2 | #GSASII image calculations: ellipse fitting & image integration |
---|
3 | ########### SVN repository information ################### |
---|
4 | # $Date: 2013-04-26 20:45:31 +0000 (Fri, 26 Apr 2013) $ |
---|
5 | # $Author: vondreele $ |
---|
6 | # $Revision: 892 $ |
---|
7 | # $URL: trunk/GSASIIimage.py $ |
---|
8 | # $Id: GSASIIimage.py 892 2013-04-26 20:45:31Z vondreele $ |
---|
9 | ########### SVN repository information ################### |
---|
10 | import math |
---|
11 | import wx |
---|
12 | import time |
---|
13 | import numpy as np |
---|
14 | import numpy.linalg as nl |
---|
15 | from scipy.optimize import leastsq |
---|
16 | import copy |
---|
17 | import GSASIIpath |
---|
18 | GSASIIpath.SetVersionNumber("$Revision: 892 $") |
---|
19 | import GSASIIplot as G2plt |
---|
20 | import GSASIIlattice as G2lat |
---|
21 | import GSASIIpwd as G2pwd |
---|
22 | import fellipse as fel |
---|
23 | |
---|
24 | # trig functions in degrees |
---|
25 | sind = lambda x: math.sin(x*math.pi/180.) |
---|
26 | asind = lambda x: 180.*math.asin(x)/math.pi |
---|
27 | tand = lambda x: math.tan(x*math.pi/180.) |
---|
28 | atand = lambda x: 180.*math.atan(x)/math.pi |
---|
29 | atan2d = lambda y,x: 180.*math.atan2(y,x)/math.pi |
---|
30 | cosd = lambda x: math.cos(x*math.pi/180.) |
---|
31 | acosd = lambda x: 180.*math.acos(x)/math.pi |
---|
32 | rdsq2d = lambda x,p: round(1.0/math.sqrt(x),p) |
---|
33 | #numpy versions |
---|
34 | npsind = lambda x: np.sin(x*np.pi/180.) |
---|
35 | npasind = lambda x: 180.*np.arcsin(x)/np.pi |
---|
36 | npcosd = lambda x: np.cos(x*np.pi/180.) |
---|
37 | nptand = lambda x: np.tan(x*np.pi/180.) |
---|
38 | npatand = lambda x: 180.*np.arctan(x)/np.pi |
---|
39 | npatan2d = lambda y,x: 180.*np.arctan2(y,x)/np.pi |
---|
40 | |
---|
41 | def pointInPolygon(pXY,xy): |
---|
42 | #pXY - assumed closed 1st & last points are duplicates |
---|
43 | Inside = False |
---|
44 | N = len(pXY) |
---|
45 | p1x,p1y = pXY[0] |
---|
46 | for i in range(N+1): |
---|
47 | p2x,p2y = pXY[i%N] |
---|
48 | if (max(p1y,p2y) >= xy[1] > min(p1y,p2y)) and (xy[0] <= max(p1x,p2x)): |
---|
49 | if p1y != p2y: |
---|
50 | xinters = (xy[1]-p1y)*(p2x-p1x)/(p2y-p1y)+p1x |
---|
51 | if p1x == p2x or xy[0] <= xinters: |
---|
52 | Inside = not Inside |
---|
53 | p1x,p1y = p2x,p2y |
---|
54 | return Inside |
---|
55 | |
---|
56 | def makeMat(Angle,Axis): |
---|
57 | #Make rotation matrix from Angle in degrees,Axis =0 for rotation about x, =1 for about y, etc. |
---|
58 | cs = cosd(Angle) |
---|
59 | ss = sind(Angle) |
---|
60 | M = np.array(([1.,0.,0.],[0.,cs,-ss],[0.,ss,cs]),dtype=np.float32) |
---|
61 | return np.roll(np.roll(M,Axis,axis=0),Axis,axis=1) |
---|
62 | |
---|
63 | def FitRing(ring,delta): |
---|
64 | parms = [] |
---|
65 | if delta: |
---|
66 | err,parms = FitEllipse(ring) |
---|
67 | errc,parmsc = FitCircle(ring) |
---|
68 | errc = errc[0]/(len(ring)*parmsc[2][0]**2) |
---|
69 | if not parms or errc < .1: |
---|
70 | parms = parmsc |
---|
71 | else: |
---|
72 | err,parms = FitCircle(ring) |
---|
73 | return parms |
---|
74 | |
---|
75 | def FitCircle(ring): |
---|
76 | |
---|
77 | def makeParmsCircle(B): |
---|
78 | cent = [-B[0]/2,-B[1]/2] |
---|
79 | phi = 0. |
---|
80 | sr1 = sr2 = math.sqrt(cent[0]**2+cent[1]**2-B[2]) |
---|
81 | return cent,phi,[sr1,sr2] |
---|
82 | |
---|
83 | ring = np.array(ring) |
---|
84 | x = np.asarray(ring.T[0]) |
---|
85 | y = np.asarray(ring.T[1]) |
---|
86 | |
---|
87 | M = np.array((x,y,np.ones_like(x))) |
---|
88 | B = np.array(-(x**2+y**2)) |
---|
89 | result = nl.lstsq(M.T,B) |
---|
90 | return result[1],makeParmsCircle(result[0]) |
---|
91 | |
---|
92 | def FitEllipse(ring): |
---|
93 | |
---|
94 | def makeParmsEllipse(B): |
---|
95 | det = 4.*(1.-B[0]**2)-B[1]**2 |
---|
96 | if det < 0.: |
---|
97 | print 'hyperbola!' |
---|
98 | return 0 |
---|
99 | elif det == 0.: |
---|
100 | print 'parabola!' |
---|
101 | return 0 |
---|
102 | cent = [(B[1]*B[3]-2.*(1.-B[0])*B[2])/det, \ |
---|
103 | (B[1]*B[2]-2.*(1.+B[0])*B[3])/det] |
---|
104 | phi = 0.5*atand(0.5*B[1]/B[0]) |
---|
105 | |
---|
106 | a = (1.+B[0])/cosd(2*phi) |
---|
107 | b = 2.-a |
---|
108 | f = (1.+B[0])*cent[0]**2+(1.-B[0])*cent[1]**2+B[1]*cent[0]*cent[1]-B[4] |
---|
109 | if f/a < 0 or f/b < 0: |
---|
110 | return 0 |
---|
111 | sr1 = math.sqrt(f/a) |
---|
112 | sr2 = math.sqrt(f/b) |
---|
113 | if sr1 > sr2: |
---|
114 | sr1,sr2 = sr2,sr1 |
---|
115 | phi -= 90. |
---|
116 | if phi < -90.: |
---|
117 | phi += 180. |
---|
118 | return cent,phi,[sr1,sr2] |
---|
119 | |
---|
120 | ring = np.array(ring) |
---|
121 | x = np.asarray(ring.T[0]) |
---|
122 | y = np.asarray(ring.T[1]) |
---|
123 | M = np.array((x**2-y**2,x*y,x,y,np.ones_like(x))) |
---|
124 | B = np.array(-(x**2+y**2)) |
---|
125 | bb,err = fel.fellipse(len(x),x,y,1.E-7) |
---|
126 | # print nl.lstsq(M.T,B)[0] |
---|
127 | # print bb |
---|
128 | return err,makeParmsEllipse(bb) |
---|
129 | |
---|
130 | def FitDetector(rings,varyList,parmDict): |
---|
131 | |
---|
132 | def CalibPrint(ValSig): |
---|
133 | print 'Image Parameters:' |
---|
134 | ptlbls = 'names :' |
---|
135 | ptstr = 'values:' |
---|
136 | sigstr = 'esds :' |
---|
137 | for name,fmt,value,sig in ValSig: |
---|
138 | ptlbls += "%s" % (name.rjust(12)) |
---|
139 | if name == 'rotate': |
---|
140 | ptstr += fmt % (value-90.) #kluge to get rotation from vertical - see GSASIIimgGUI |
---|
141 | else: |
---|
142 | ptstr += fmt % (value) |
---|
143 | if sig: |
---|
144 | sigstr += fmt % (sig) |
---|
145 | else: |
---|
146 | sigstr += 12*' ' |
---|
147 | print ptlbls |
---|
148 | print ptstr |
---|
149 | print sigstr |
---|
150 | |
---|
151 | def ellipseCalcD(B,xyd,varyList,parmDict): |
---|
152 | x = xyd[0] |
---|
153 | y = xyd[1] |
---|
154 | dsp = xyd[2] |
---|
155 | wave = parmDict['wave'] |
---|
156 | if 'dep' in varyList: |
---|
157 | dist,x0,y0,tilt,phi,dep = B[:6] |
---|
158 | else: |
---|
159 | dist,x0,y0,tilt,phi = B[:5] |
---|
160 | dep = parmDict['dep'] |
---|
161 | if 'wave' in varyList: |
---|
162 | wave = B[-1] |
---|
163 | tth = 2.0*npasind(wave/(2.*dsp)) |
---|
164 | dxy = dep*(1.-npcosd(tth)) |
---|
165 | ttth = nptand(tth) |
---|
166 | radius = (dist+dxy)*ttth |
---|
167 | stth = npsind(tth) |
---|
168 | cosb = npcosd(tilt) |
---|
169 | R1 = (dist+dxy)*stth*npcosd(tth)*cosb/(cosb**2-stth**2) |
---|
170 | R0 = np.sqrt(R1*radius*cosb) |
---|
171 | zdis = R1*ttth*nptand(tilt) |
---|
172 | X = x-x0+zdis*npsind(phi) |
---|
173 | Y = y-y0-zdis*npcosd(phi) |
---|
174 | XR = X*npcosd(phi)-Y*npsind(phi) |
---|
175 | YR = X*npsind(phi)+Y*npcosd(phi) |
---|
176 | return (XR/R0)**2+(YR/R1)**2-1 |
---|
177 | |
---|
178 | names = ['dist','det-X','det-Y','tilt','phi','dep','wave'] |
---|
179 | fmt = ['%12.2f','%12.2f','%12.2f','%12.2f','%12.2f','%12.3f','%12.5f'] |
---|
180 | p0 = [parmDict[key] for key in varyList] |
---|
181 | result = leastsq(ellipseCalcD,p0,args=(rings.T,varyList,parmDict),full_output=True) |
---|
182 | parmDict.update(zip(varyList,result[0])) |
---|
183 | vals = list(result[0]) |
---|
184 | chi = np.sqrt(np.sum(ellipseCalcD(result[0],rings.T,varyList,parmDict)**2)) |
---|
185 | sig = list(chi*np.sqrt(np.diag(result[1]))) |
---|
186 | sigList = np.zeros(7) |
---|
187 | for i,name in enumerate(names): |
---|
188 | if name in varyList: |
---|
189 | sigList[i] = sig[varyList.index(name)] |
---|
190 | ValSig = zip(names,fmt,vals,sig) |
---|
191 | CalibPrint(ValSig) |
---|
192 | # try: |
---|
193 | # print 'Trial refinement of wavelength - not used for calibration' |
---|
194 | # p0 = result[0] |
---|
195 | # print p0 |
---|
196 | # print parms |
---|
197 | # p0 = np.append(p0,parms[0]) |
---|
198 | # resultW = leastsq(ellipseCalcW,p0,args=(rings.T,parms[1:]),full_output=True) |
---|
199 | # resultW[0][3] = np.mod(result[0][3],360.0) #remove random full circles |
---|
200 | # sig = np.sqrt(np.sum(ellipseCalcW(resultW[0],rings.T)**2)) |
---|
201 | # ValSig = zip(names,fmt,resultW[0],sig*np.sqrt(np.diag(resultW[1]))) |
---|
202 | # CalibPrint(ValSig) |
---|
203 | # return result[0],resultW[0][-1] |
---|
204 | # except ValueError: |
---|
205 | # print 'Bad refinement - no result' |
---|
206 | # return result[0],wave |
---|
207 | |
---|
208 | def ImageLocalMax(image,w,Xpix,Ypix): |
---|
209 | w2 = w*2 |
---|
210 | sizey,sizex = image.shape |
---|
211 | xpix = int(Xpix) #get reference corner of pixel chosen |
---|
212 | ypix = int(Ypix) |
---|
213 | if (w < xpix < sizex-w) and (w < ypix < sizey-w) and image[ypix,xpix]: |
---|
214 | Z = image[ypix-w:ypix+w,xpix-w:xpix+w] |
---|
215 | Zmax = np.argmax(Z) |
---|
216 | Zmin = np.argmin(Z) |
---|
217 | xpix += Zmax%w2-w |
---|
218 | ypix += Zmax/w2-w |
---|
219 | return xpix,ypix,np.ravel(Z)[Zmax],max(0.0001,np.ravel(Z)[Zmin]) #avoid neg/zero minimum |
---|
220 | else: |
---|
221 | return 0,0,0,0 |
---|
222 | |
---|
223 | def makeRing(dsp,ellipse,pix,reject,scalex,scaley,image): |
---|
224 | cent,phi,radii = ellipse |
---|
225 | cphi = cosd(phi) |
---|
226 | sphi = sind(phi) |
---|
227 | ring = [] |
---|
228 | amin = 0 |
---|
229 | amax = 360 |
---|
230 | for a in range(0,360,1): |
---|
231 | x = radii[0]*cosd(a) |
---|
232 | y = radii[1]*sind(a) |
---|
233 | X = (cphi*x-sphi*y+cent[0])*scalex #convert mm to pixels |
---|
234 | Y = (sphi*x+cphi*y+cent[1])*scaley |
---|
235 | X,Y,I,J = ImageLocalMax(image,pix,X,Y) |
---|
236 | if I and J and I/J > reject: |
---|
237 | X += .5 #set to center of pixel |
---|
238 | Y += .5 |
---|
239 | X /= scalex #convert to mm |
---|
240 | Y /= scaley |
---|
241 | amin = min(amin,a) |
---|
242 | amax = max(amax,a) |
---|
243 | if [X,Y,dsp] not in ring: |
---|
244 | ring.append([X,Y,dsp]) |
---|
245 | delt = amax-amin |
---|
246 | if len(ring) < 10: #want more than 20 deg |
---|
247 | return [],delt > 90 |
---|
248 | return ring,delt > 90 |
---|
249 | |
---|
250 | def makeIdealRing(ellipse,azm=None): |
---|
251 | cent,phi,radii = ellipse |
---|
252 | cphi = cosd(phi) |
---|
253 | sphi = sind(phi) |
---|
254 | if azm: |
---|
255 | aR = azm[0]-90,azm[1]-90,azm[1]-azm[0] |
---|
256 | if azm[1]-azm[0] > 180: |
---|
257 | aR[2] /= 2 |
---|
258 | else: |
---|
259 | aR = 0,362,181 |
---|
260 | |
---|
261 | a = np.linspace(aR[0],aR[1],aR[2]) |
---|
262 | x = radii[0]*npcosd(a-phi) |
---|
263 | y = radii[1]*npsind(a-phi) |
---|
264 | X = (cphi*x-sphi*y+cent[0]) |
---|
265 | Y = (sphi*x+cphi*y+cent[1]) |
---|
266 | return zip(X,Y) |
---|
267 | |
---|
268 | def calcDist(radii,tth): |
---|
269 | stth = sind(tth) |
---|
270 | ctth = cosd(tth) |
---|
271 | ttth = tand(tth) |
---|
272 | return math.sqrt(radii[0]**4/(ttth**2*((radii[0]*ctth)**2+(radii[1]*stth)**2))) |
---|
273 | |
---|
274 | def calcZdisCosB(radius,tth,radii): |
---|
275 | cosB = sinb = radii[0]**2/(radius*radii[1]) |
---|
276 | if cosB > 1.: |
---|
277 | return 0.,1. |
---|
278 | else: |
---|
279 | cosb = math.sqrt(1.-sinb**2) |
---|
280 | ttth = tand(tth) |
---|
281 | zdis = radii[1]*ttth*cosb/sinb |
---|
282 | return zdis,cosB |
---|
283 | |
---|
284 | def GetEllipse(dsp,data): |
---|
285 | dist = data['distance'] |
---|
286 | cent = data['center'] |
---|
287 | tilt = data['tilt'] |
---|
288 | phi = data['rotation'] |
---|
289 | dep = data['DetDepth'] |
---|
290 | radii = [0,0] |
---|
291 | tth = 2.0*asind(data['wavelength']/(2.*dsp)) |
---|
292 | ttth = tand(tth) |
---|
293 | stth = sind(tth) |
---|
294 | ctth = cosd(tth) |
---|
295 | cosb = cosd(tilt) |
---|
296 | dxy = dep*(1.-npcosd(tth)) |
---|
297 | radius = ttth*(dist+dxy) |
---|
298 | radii[1] = (dist+dxy)*stth*ctth*cosb/(cosb**2-stth**2) |
---|
299 | if radii[1] > 0: |
---|
300 | radii[0] = math.sqrt(radii[1]*radius*cosb) |
---|
301 | zdis = radii[1]*ttth*tand(tilt) |
---|
302 | elcent = [cent[0]-zdis*sind(phi),cent[1]+zdis*cosd(phi)] |
---|
303 | return elcent,phi,radii |
---|
304 | else: |
---|
305 | print 'bad ellipse - radii:',radii |
---|
306 | return False |
---|
307 | |
---|
308 | def GetDetectorXY(dsp,azm,data): |
---|
309 | from scipy.optimize import fsolve |
---|
310 | def func(xy,*args): |
---|
311 | azm,phi,R0,R1,A,B = args |
---|
312 | cp = cosd(phi) |
---|
313 | sp = sind(phi) |
---|
314 | x,y = xy |
---|
315 | out = [] |
---|
316 | out.append(y-x*tand(azm)) |
---|
317 | out.append(R0**2*((x+A)*sp-(y+B)*cp)**2+R1**2*((x+A)*cp+(y+B)*sp)**2-(R0*R1)**2) |
---|
318 | return out |
---|
319 | elcent,phi,radii = GetEllipse(dsp,data) |
---|
320 | cent = data['center'] |
---|
321 | tilt = data['tilt'] |
---|
322 | phi = data['rotation'] |
---|
323 | wave = data['wavelength'] |
---|
324 | dist = data['distance'] |
---|
325 | dep = data['DetDepth'] |
---|
326 | tth = 2.0*asind(wave/(2.*dsp)) |
---|
327 | dxy = dep*(1.-npcosd(tth)) |
---|
328 | ttth = tand(tth) |
---|
329 | radius = (dist+dxy)*ttth |
---|
330 | stth = sind(tth) |
---|
331 | cosb = cosd(tilt) |
---|
332 | R1 = (dist+dxy)*stth*cosd(tth)*cosb/(cosb**2-stth**2) |
---|
333 | R0 = math.sqrt(R1*radius*cosb) |
---|
334 | zdis = R1*ttth*tand(tilt) |
---|
335 | A = zdis*sind(phi) |
---|
336 | B = -zdis*cosd(phi) |
---|
337 | xy0 = [radius*cosd(azm),radius*sind(azm)] |
---|
338 | xy = fsolve(func,xy0,args=(azm,phi,R0,R1,A,B))+cent |
---|
339 | return xy |
---|
340 | |
---|
341 | def GetDetXYfromThAzm(Th,Azm,data): |
---|
342 | dsp = data['wavelength']/(2.0*npsind(Th)) |
---|
343 | |
---|
344 | return GetDetectorXY(dsp,azm,data) |
---|
345 | |
---|
346 | def GetTthAzmDsp(x,y,data): |
---|
347 | wave = data['wavelength'] |
---|
348 | dist = data['distance'] |
---|
349 | cent = data['center'] |
---|
350 | tilt = data['tilt'] |
---|
351 | phi = data['rotation'] |
---|
352 | dep = data['DetDepth'] |
---|
353 | LRazim = data['LRazimuth'] |
---|
354 | azmthoff = data['azmthOff'] |
---|
355 | dx = np.array(x-cent[0],dtype=np.float32) |
---|
356 | dy = np.array(y-cent[1],dtype=np.float32) |
---|
357 | X = np.array(([dx,dy,np.zeros_like(dx)]),dtype=np.float32).T |
---|
358 | X = np.dot(X,makeMat(phi,2)) |
---|
359 | Z = np.dot(X,makeMat(tilt,0)).T[2] |
---|
360 | tth = npatand(np.sqrt(dx**2+dy**2-Z**2)/(dist-Z)) |
---|
361 | dxy = dep*(1.-npcosd(tth)) |
---|
362 | tth = npatand(np.sqrt(dx**2+dy**2-Z**2)/(dist-Z+dxy)) |
---|
363 | dsp = wave/(2.*npsind(tth/2.)) |
---|
364 | azm = (npatan2d(dx,-dy)+azmthoff+720.)%360. |
---|
365 | return tth,azm,dsp |
---|
366 | |
---|
367 | def GetTth(x,y,data): |
---|
368 | return GetTthAzmDsp(x,y,data)[0] |
---|
369 | |
---|
370 | def GetTthAzm(x,y,data): |
---|
371 | return GetTthAzmDsp(x,y,data)[0:2] |
---|
372 | |
---|
373 | def GetDsp(x,y,data): |
---|
374 | return GetTthAzmDsp(x,y,data)[2] |
---|
375 | |
---|
376 | def GetAzm(x,y,data): |
---|
377 | return GetTthAzmDsp(x,y,data)[1] |
---|
378 | |
---|
379 | def ImageCompress(image,scale): |
---|
380 | if scale == 1: |
---|
381 | return image |
---|
382 | else: |
---|
383 | return image[::scale,::scale] |
---|
384 | |
---|
385 | def checkEllipse(Zsum,distSum,xSum,ySum,dist,x,y): |
---|
386 | avg = np.array([distSum/Zsum,xSum/Zsum,ySum/Zsum]) |
---|
387 | curr = np.array([dist,x,y]) |
---|
388 | return abs(avg-curr)/avg < .02 |
---|
389 | |
---|
390 | def EdgeFinder(image,data): #this makes list of all x,y where I>edgeMin suitable for an ellipse search? |
---|
391 | import numpy.ma as ma |
---|
392 | Nx,Ny = data['size'] |
---|
393 | pixelSize = data['pixelSize'] |
---|
394 | edgemin = data['edgemin'] |
---|
395 | scalex = pixelSize[0]/1000. |
---|
396 | scaley = pixelSize[1]/1000. |
---|
397 | tay,tax = np.mgrid[0:Nx,0:Ny] |
---|
398 | tax = np.asfarray(tax*scalex,dtype=np.float32) |
---|
399 | tay = np.asfarray(tay*scaley,dtype=np.float32) |
---|
400 | tam = ma.getmask(ma.masked_less(image.flatten(),edgemin)) |
---|
401 | tax = ma.compressed(ma.array(tax.flatten(),mask=tam)) |
---|
402 | tay = ma.compressed(ma.array(tay.flatten(),mask=tam)) |
---|
403 | return zip(tax,tay) |
---|
404 | |
---|
405 | def ImageRecalibrate(self,data): |
---|
406 | import ImageCalibrants as calFile |
---|
407 | print 'Image recalibration:' |
---|
408 | time0 = time.time() |
---|
409 | pixelSize = data['pixelSize'] |
---|
410 | scalex = 1000./pixelSize[0] |
---|
411 | scaley = 1000./pixelSize[1] |
---|
412 | pixLimit = data['pixLimit'] |
---|
413 | cutoff = data['cutoff'] |
---|
414 | data['rings'] = [] |
---|
415 | data['ellipses'] = [] |
---|
416 | if not data['calibrant']: |
---|
417 | print 'no calibration material selected' |
---|
418 | return True |
---|
419 | |
---|
420 | skip = data['calibskip'] |
---|
421 | dmin = data['calibdmin'] |
---|
422 | Bravais,Cells = calFile.Calibrants[data['calibrant']][:2] |
---|
423 | HKL = [] |
---|
424 | for bravais,cell in zip(Bravais,Cells): |
---|
425 | A = G2lat.cell2A(cell) |
---|
426 | hkl = G2lat.GenHBravais(dmin,bravais,A)[skip:] |
---|
427 | HKL += hkl |
---|
428 | HKL = G2lat.sortHKLd(HKL,True,False) |
---|
429 | varyList = ['dist','det-X','det-Y','tilt','phi'] |
---|
430 | parmDict = {'dist':data['distance'],'det-X':data['center'][0],'det-Y':data['center'][1], |
---|
431 | 'tilt':data['tilt'],'phi':data['rotation'],'wave':data['wavelength'],'dep':data['DetDepth']} |
---|
432 | for H in HKL: |
---|
433 | dsp = H[3] |
---|
434 | ellipse = GetEllipse(dsp,data) |
---|
435 | Ring,delt = makeRing(dsp,ellipse,pixLimit,cutoff,scalex,scaley,self.ImageZ) |
---|
436 | if Ring: |
---|
437 | # numZ = len(Ring) |
---|
438 | data['rings'].append(np.array(Ring)) |
---|
439 | data['ellipses'].append(copy.deepcopy(ellipse+('r',))) |
---|
440 | else: |
---|
441 | continue |
---|
442 | rings = np.concatenate((data['rings']),axis=0) |
---|
443 | if data['DetDepthRef']: |
---|
444 | varyList.append('dep') |
---|
445 | FitDetector(rings,varyList,parmDict) |
---|
446 | data['distance'] = parmDict['dist'] |
---|
447 | data['center'] = [parmDict['det-X'],parmDict['det-Y']] |
---|
448 | data['rotation'] = np.mod(parmDict['phi'],360.0) |
---|
449 | data['tilt'] = parmDict['tilt'] |
---|
450 | data['DetDepth'] = parmDict['dep'] |
---|
451 | N = len(data['ellipses']) |
---|
452 | data['ellipses'] = [] #clear away individual ellipse fits |
---|
453 | for H in HKL[:N]: |
---|
454 | ellipse = GetEllipse(H[3],data) |
---|
455 | data['ellipses'].append(copy.deepcopy(ellipse+('b',))) |
---|
456 | |
---|
457 | print 'calibration time = ',time.time()-time0 |
---|
458 | G2plt.PlotImage(self,newImage=True) |
---|
459 | return True |
---|
460 | |
---|
461 | def ImageCalibrate(self,data): |
---|
462 | import copy |
---|
463 | import ImageCalibrants as calFile |
---|
464 | print 'Image calibration:' |
---|
465 | time0 = time.time() |
---|
466 | ring = data['ring'] |
---|
467 | pixelSize = data['pixelSize'] |
---|
468 | scalex = 1000./pixelSize[0] |
---|
469 | scaley = 1000./pixelSize[1] |
---|
470 | pixLimit = data['pixLimit'] |
---|
471 | cutoff = data['cutoff'] |
---|
472 | if len(ring) < 5: |
---|
473 | print 'not enough inner ring points for ellipse' |
---|
474 | return False |
---|
475 | |
---|
476 | #fit start points on inner ring |
---|
477 | data['ellipses'] = [] |
---|
478 | outE = FitRing(ring,True) |
---|
479 | if outE: |
---|
480 | print 'start ellipse:',outE |
---|
481 | ellipse = outE |
---|
482 | else: |
---|
483 | return False |
---|
484 | |
---|
485 | #setup 360 points on that ring for "good" fit |
---|
486 | Ring,delt = makeRing(1.0,ellipse,pixLimit,cutoff,scalex,scaley,self.ImageZ) |
---|
487 | if Ring: |
---|
488 | ellipse = FitRing(Ring,delt) |
---|
489 | Ring,delt = makeRing(1.0,ellipse,pixLimit,cutoff,scalex,scaley,self.ImageZ) #do again |
---|
490 | ellipse = FitRing(Ring,delt) |
---|
491 | else: |
---|
492 | print '1st ring not sufficiently complete to proceed' |
---|
493 | return False |
---|
494 | print 'inner ring:',ellipse #cent,phi,radii |
---|
495 | data['center'] = copy.copy(ellipse[0]) #not right!! (but useful for now) |
---|
496 | data['ellipses'].append(ellipse[:]+('r',)) |
---|
497 | G2plt.PlotImage(self,newImage=True) |
---|
498 | |
---|
499 | #setup for calibration |
---|
500 | data['rings'] = [] |
---|
501 | data['ellipses'] = [] |
---|
502 | if not data['calibrant']: |
---|
503 | print 'no calibration material selected' |
---|
504 | return True |
---|
505 | |
---|
506 | skip = data['calibskip'] |
---|
507 | dmin = data['calibdmin'] |
---|
508 | Bravais,Cells = calFile.Calibrants[data['calibrant']][:2] |
---|
509 | HKL = [] |
---|
510 | for bravais,cell in zip(Bravais,Cells): |
---|
511 | A = G2lat.cell2A(cell) |
---|
512 | hkl = G2lat.GenHBravais(dmin,bravais,A)[skip:] |
---|
513 | HKL += hkl |
---|
514 | HKL = G2lat.sortHKLd(HKL,True,False) |
---|
515 | wave = data['wavelength'] |
---|
516 | cent = data['center'] |
---|
517 | elcent,phi,radii = ellipse |
---|
518 | dsp = HKL[0][3] |
---|
519 | tth = 2.0*asind(wave/(2.*dsp)) |
---|
520 | ttth = tand(tth) |
---|
521 | data['distance'] = dist = calcDist(radii,tth) |
---|
522 | radius = dist*tand(tth) |
---|
523 | zdis,cosB = calcZdisCosB(radius,tth,radii) |
---|
524 | cent1 = [] |
---|
525 | cent2 = [] |
---|
526 | xSum = 0 |
---|
527 | ySum = 0 |
---|
528 | zxSum = 0 |
---|
529 | zySum = 0 |
---|
530 | phiSum = 0 |
---|
531 | tiltSum = 0 |
---|
532 | distSum = 0 |
---|
533 | Zsum = 0 |
---|
534 | for i,H in enumerate(HKL): |
---|
535 | dsp = H[3] |
---|
536 | tth = 2.0*asind(0.5*wave/dsp) |
---|
537 | stth = sind(tth) |
---|
538 | ctth = cosd(tth) |
---|
539 | ttth = tand(tth) |
---|
540 | radius = dist*ttth |
---|
541 | elcent,phi,radii = ellipse |
---|
542 | if i: |
---|
543 | radii[1] = dist*stth*ctth*cosB/(cosB**2-stth**2) |
---|
544 | radii[0] = math.sqrt(radii[1]*radius*cosB) |
---|
545 | zdis,cosB = calcZdisCosB(radius,tth,radii) |
---|
546 | zsinp = zdis*sind(phi) |
---|
547 | zcosp = zdis*cosd(phi) |
---|
548 | cent = data['center'] |
---|
549 | elcent = [cent[0]-zsinp,cent[1]+zcosp] |
---|
550 | ellipse = (elcent,phi,radii) |
---|
551 | ratio = radii[1]/radii[0] |
---|
552 | Ring,delt = makeRing(dsp,ellipse,pixLimit,cutoff,scalex,scaley,self.ImageZ) |
---|
553 | if Ring: |
---|
554 | numZ = len(Ring) |
---|
555 | data['rings'].append(np.array(Ring)) |
---|
556 | newellipse = FitRing(Ring,delt) |
---|
557 | elcent,phi,radii = newellipse |
---|
558 | if abs(phi) > 45. and phi < 0.: |
---|
559 | phi += 180. |
---|
560 | dist = calcDist(radii,tth) |
---|
561 | distR = 1.-dist/data['distance'] |
---|
562 | if abs(distR) > 0.1: |
---|
563 | # print dsp,dist,data['distance'],distR,len(Ring),delt |
---|
564 | break |
---|
565 | if distR > 0.001: |
---|
566 | print 'Wavelength too large?' |
---|
567 | elif distR < -0.001: |
---|
568 | print 'Wavelength too small?' |
---|
569 | else: |
---|
570 | ellipse = newellipse |
---|
571 | zdis,cosB = calcZdisCosB(radius,tth,radii) |
---|
572 | Tilt = acosd(cosB) # 0 <= tilt <= 90 |
---|
573 | zsinp = zdis*sind(ellipse[1]) |
---|
574 | zcosp = zdis*cosd(ellipse[1]) |
---|
575 | cent1.append(np.array([elcent[0]+zsinp,elcent[1]-zcosp])) |
---|
576 | cent2.append(np.array([elcent[0]-zsinp,elcent[1]+zcosp])) |
---|
577 | if i: |
---|
578 | d1 = cent1[-1]-cent1[-2] #get shift of 2 possible center solutions |
---|
579 | d2 = cent2[-1]-cent2[-2] |
---|
580 | if np.dot(d2,d2) > np.dot(d1,d1): #right solution is the larger shift |
---|
581 | data['center'] = cent1[-1] |
---|
582 | else: |
---|
583 | data['center'] = cent2[-1] |
---|
584 | Zsum += numZ |
---|
585 | phiSum += numZ*phi |
---|
586 | distSum += numZ*dist |
---|
587 | xSum += numZ*data['center'][0] |
---|
588 | ySum += numZ*data['center'][1] |
---|
589 | tiltSum += numZ*abs(Tilt) |
---|
590 | if not np.all(checkEllipse(Zsum,distSum,xSum,ySum,dist,data['center'][0],data['center'][1])): |
---|
591 | print 'Bad fit for ring # %i. Try reducing Pixel search range'%(i) |
---|
592 | cent = data['center'] |
---|
593 | # print ('for ring # %2i @ d-space %.4f: dist %.3f rotate %6.2f tilt %6.2f Xcent %.3f Ycent %.3f Npts %d' |
---|
594 | # %(i,dsp,dist,phi-90.,Tilt,cent[0],cent[1],numZ)) |
---|
595 | data['ellipses'].append(copy.deepcopy(ellipse+('r',))) |
---|
596 | else: |
---|
597 | break |
---|
598 | G2plt.PlotImage(self,newImage=True) |
---|
599 | fullSize = len(self.ImageZ)/scalex |
---|
600 | if 2*radii[1] < .9*fullSize: |
---|
601 | print 'Are all usable rings (>25% visible) used? Try reducing Min ring I/Ib' |
---|
602 | if not Zsum: |
---|
603 | print 'Only one ring fitted. Check your wavelength.' |
---|
604 | return False |
---|
605 | data['center'] = [xSum/Zsum,ySum/Zsum] |
---|
606 | data['distance'] = distSum/Zsum |
---|
607 | |
---|
608 | #possible error if no. of rings < 3! Might need trap here |
---|
609 | d1 = cent1[-1]-cent1[1] #compare last ring to 2nd ring |
---|
610 | d2 = cent2[-1]-cent2[1] |
---|
611 | Zsign = 1 |
---|
612 | len1 = math.sqrt(np.dot(d1,d1)) |
---|
613 | len2 = math.sqrt(np.dot(d2,d2)) |
---|
614 | t1 = d1/len1 |
---|
615 | t2 = d2/len2 |
---|
616 | if len2 > len1: |
---|
617 | if -135. < atan2d(t2[1],t2[0]) < 45.: |
---|
618 | Zsign = -1 |
---|
619 | else: |
---|
620 | if -135. < atan2d(t1[1],t1[0]) < 45.: |
---|
621 | Zsign = -1 |
---|
622 | |
---|
623 | data['tilt'] = Zsign*tiltSum/Zsum |
---|
624 | data['rotation'] = phiSum/Zsum |
---|
625 | varyList = ['dist','det-X','det-Y','tilt','phi'] |
---|
626 | parmDict = {'dist':data['distance'],'det-X':data['center'][0],'det-Y':data['center'][1], |
---|
627 | 'tilt':data['tilt'],'phi':data['rotation'],'wave':data['wavelength'],'dep':data['DetDepth']} |
---|
628 | rings = np.concatenate((data['rings']),axis=0) |
---|
629 | if data['DetDepthRef']: |
---|
630 | varyList.append('dep') |
---|
631 | FitDetector(rings,varyList,parmDict) |
---|
632 | data['distance'] = parmDict['dist'] |
---|
633 | data['center'] = [parmDict['det-X'],parmDict['det-Y']] |
---|
634 | data['rotation'] = np.mod(parmDict['phi'],360.0) |
---|
635 | data['tilt'] = parmDict['tilt'] |
---|
636 | data['DetDepth'] = parmDict['dep'] |
---|
637 | N = len(data['ellipses']) |
---|
638 | data['ellipses'] = [] #clear away individual ellipse fits |
---|
639 | for H in HKL[:N]: |
---|
640 | ellipse = GetEllipse(H[3],data) |
---|
641 | data['ellipses'].append(copy.deepcopy(ellipse+('b',))) |
---|
642 | print 'calibration time = ',time.time()-time0 |
---|
643 | G2plt.PlotImage(self,newImage=True) |
---|
644 | return True |
---|
645 | |
---|
646 | def Make2ThetaAzimuthMap(data,masks,iLim,jLim): |
---|
647 | import numpy.ma as ma |
---|
648 | import polymask as pm |
---|
649 | #transforms 2D image from x,y space to 2-theta,azimuth space based on detector orientation |
---|
650 | pixelSize = data['pixelSize'] |
---|
651 | scalex = pixelSize[0]/1000. |
---|
652 | scaley = pixelSize[1]/1000. |
---|
653 | |
---|
654 | tay,tax = np.mgrid[iLim[0]+0.5:iLim[1]+.5,jLim[0]+.5:jLim[1]+.5] #bin centers not corners |
---|
655 | tax = np.asfarray(tax*scalex,dtype=np.float32) |
---|
656 | tay = np.asfarray(tay*scaley,dtype=np.float32) |
---|
657 | nI = iLim[1]-iLim[0] |
---|
658 | nJ = jLim[1]-jLim[0] |
---|
659 | #make position masks here |
---|
660 | spots = masks['Points'] |
---|
661 | polygons = masks['Polygons'] |
---|
662 | tam = ma.make_mask_none((nI,nJ)) |
---|
663 | for polygon in polygons: |
---|
664 | if polygon: |
---|
665 | tamp = ma.make_mask_none((nI*nJ)) |
---|
666 | tamp = ma.make_mask(pm.polymask(nI*nJ,tax.flatten(), |
---|
667 | tay.flatten(),len(polygon),polygon,tamp)) |
---|
668 | tam = ma.mask_or(tam.flatten(),tamp) |
---|
669 | if tam.shape: tam = np.reshape(tam,(nI,nJ)) |
---|
670 | for X,Y,diam in spots: |
---|
671 | tamp = ma.getmask(ma.masked_less((tax-X)**2+(tay-Y)**2,(diam/2.)**2)) |
---|
672 | tam = ma.mask_or(tam,tamp) |
---|
673 | TA = np.array(GetTthAzm(tax,tay,data)) |
---|
674 | TA[1] = np.where(TA[1]<0,TA[1]+360,TA[1]) |
---|
675 | return np.array(TA),tam #2-theta & azimuth arrays & position mask |
---|
676 | |
---|
677 | def Fill2ThetaAzimuthMap(masks,TA,tam,image): |
---|
678 | import numpy.ma as ma |
---|
679 | Zlim = masks['Thresholds'][1] |
---|
680 | rings = masks['Rings'] |
---|
681 | arcs = masks['Arcs'] |
---|
682 | TA = np.dstack((ma.getdata(TA[1]),ma.getdata(TA[0]))) #azimuth, 2-theta |
---|
683 | tax,tay = np.dsplit(TA,2) #azimuth, 2-theta |
---|
684 | for tth,thick in rings: |
---|
685 | tam = ma.mask_or(tam.flatten(),ma.getmask(ma.masked_inside(tay.flatten(),max(0.01,tth-thick/2.),tth+thick/2.))) |
---|
686 | for tth,azm,thick in arcs: |
---|
687 | tamt = ma.getmask(ma.masked_inside(tay.flatten(),max(0.01,tth-thick/2.),tth+thick/2.)) |
---|
688 | tama = ma.getmask(ma.masked_inside(tax.flatten(),azm[0],azm[1])) |
---|
689 | tam = ma.mask_or(tam.flatten(),tamt*tama) |
---|
690 | taz = ma.masked_outside(image.flatten(),int(Zlim[0]),Zlim[1]) |
---|
691 | tam = ma.mask_or(tam.flatten(),ma.getmask(taz)) |
---|
692 | tax = ma.compressed(ma.array(tax.flatten(),mask=tam)) |
---|
693 | tay = ma.compressed(ma.array(tay.flatten(),mask=tam)) |
---|
694 | taz = ma.compressed(ma.array(taz.flatten(),mask=tam)) |
---|
695 | del(tam) |
---|
696 | return tax,tay,taz |
---|
697 | |
---|
698 | def ImageIntegrate(image,data,masks): |
---|
699 | import histogram2d as h2d |
---|
700 | print 'Begin image integration' |
---|
701 | LUtth = data['IOtth'] |
---|
702 | LRazm = np.array(data['LRazimuth'],dtype=np.float64) |
---|
703 | numAzms = data['outAzimuths'] |
---|
704 | numChans = data['outChannels'] |
---|
705 | Dtth = (LUtth[1]-LUtth[0])/numChans |
---|
706 | Dazm = (LRazm[1]-LRazm[0])/numAzms |
---|
707 | if data['centerAzm']: |
---|
708 | LRazm += Dazm/2. |
---|
709 | NST = np.zeros(shape=(numAzms,numChans),order='F',dtype=np.float32) |
---|
710 | H0 = np.zeros(shape=(numAzms,numChans),order='F',dtype=np.float32) |
---|
711 | imageN = len(image) |
---|
712 | Nx,Ny = data['size'] |
---|
713 | nXBlks = (Nx-1)/1024+1 |
---|
714 | nYBlks = (Ny-1)/1024+1 |
---|
715 | Nup = nXBlks*nYBlks*3+3 |
---|
716 | dlg = wx.ProgressDialog("Elapsed time","2D image integration",Nup, |
---|
717 | style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE) |
---|
718 | try: |
---|
719 | t0 = time.time() |
---|
720 | Nup = 0 |
---|
721 | dlg.Update(Nup) |
---|
722 | for iBlk in range(nYBlks): |
---|
723 | iBeg = iBlk*1024 |
---|
724 | iFin = min(iBeg+1024,Ny) |
---|
725 | for jBlk in range(nXBlks): |
---|
726 | jBeg = jBlk*1024 |
---|
727 | jFin = min(jBeg+1024,Nx) |
---|
728 | print 'Process map block:',iBlk,jBlk,' limits:',iBeg,iFin,jBeg,jFin |
---|
729 | TA,tam = Make2ThetaAzimuthMap(data,masks,(iBeg,iFin),(jBeg,jFin)) #2-theta & azimuth arrays & create position mask |
---|
730 | |
---|
731 | Nup += 1 |
---|
732 | dlg.Update(Nup) |
---|
733 | Block = image[iBeg:iFin,jBeg:jFin] |
---|
734 | tax,tay,taz = Fill2ThetaAzimuthMap(masks,TA,tam,Block) #and apply masks |
---|
735 | del TA,tam |
---|
736 | Nup += 1 |
---|
737 | dlg.Update(Nup) |
---|
738 | tax = np.where(tax > LRazm[1],tax-360.,tax) #put azm inside limits if possible |
---|
739 | tax = np.where(tax < LRazm[0],tax+360.,tax) |
---|
740 | NST,H0 = h2d.histogram2d(len(tax),tax,tay,taz,numAzms,numChans,LRazm,LUtth,Dazm,Dtth,NST,H0) |
---|
741 | print 'block done' |
---|
742 | del tax,tay,taz |
---|
743 | Nup += 1 |
---|
744 | dlg.Update(Nup) |
---|
745 | NST = np.array(NST) |
---|
746 | H0 = np.divide(H0,NST) |
---|
747 | H0 = np.nan_to_num(H0) |
---|
748 | del NST |
---|
749 | if Dtth: |
---|
750 | H2 = np.array([tth for tth in np.linspace(LUtth[0],LUtth[1],numChans+1)]) |
---|
751 | else: |
---|
752 | H2 = np.array(LUtth) |
---|
753 | if Dazm: |
---|
754 | H1 = np.array([azm for azm in np.linspace(LRazm[0],LRazm[1],numAzms+1)]) |
---|
755 | else: |
---|
756 | H1 = LRazm |
---|
757 | H0[0] /= npcosd(H2[:-1])**2 |
---|
758 | if data['Oblique'][1]: |
---|
759 | H0[0] /= G2pwd.Oblique(data['Oblique'][0],H2[:-1]) |
---|
760 | Nup += 1 |
---|
761 | dlg.Update(Nup) |
---|
762 | t1 = time.time() |
---|
763 | finally: |
---|
764 | dlg.Destroy() |
---|
765 | print 'Integration complete' |
---|
766 | print "Elapsed time:","%8.3f"%(t1-t0), "s" |
---|
767 | return H0,H1,H2 |
---|
768 | |
---|
769 | def FitStrSta(Image,StrSta,Controls,Masks): |
---|
770 | |
---|
771 | # print 'Masks:',Masks |
---|
772 | StaControls = copy.deepcopy(Controls) |
---|
773 | phi = StrSta['Sample phi'] |
---|
774 | wave = Controls['wavelength'] |
---|
775 | StaControls['distance'] += StrSta['Sample z']*cosd(phi) |
---|
776 | pixSize = StaControls['pixelSize'] |
---|
777 | scalex = 1000./pixSize[0] |
---|
778 | scaley = 1000./pixSize[1] |
---|
779 | rings = [] |
---|
780 | |
---|
781 | for ring in StrSta['d-zero']: #get observed x,y,d points for the d-zeros |
---|
782 | ellipse = GetEllipse(ring['Dset'],StaControls) |
---|
783 | Ring,delt = makeRing(ring['Dset'],ellipse,ring['pixLimit'],ring['cutoff'],scalex,scaley,Image) |
---|
784 | Ring = np.array(Ring).T |
---|
785 | ring['ImxyObs'] = np.array(Ring[:2]) #need to apply masks to this to eliminate bad points |
---|
786 | Ring[:2] = GetTthAzm(Ring[0],Ring[1],StaControls) #convert x,y to tth,azm |
---|
787 | Ring[0] /= 2. #convert to theta |
---|
788 | if len(rings): |
---|
789 | rings = np.concatenate((rings,Ring),axis=1) |
---|
790 | else: |
---|
791 | rings = np.array(Ring) |
---|
792 | E = StrSta['strain'] |
---|
793 | p0 = [E[0][0],E[1][1],E[2][2],E[0][1],E[0][2],E[1][2]] |
---|
794 | E = FitStrain(rings,p0,wave,phi) |
---|
795 | StrSta['strain'] = E |
---|
796 | |
---|
797 | def calcFij(omg,phi,azm,th): |
---|
798 | ''' Uses parameters as defined by Bob He & Kingsley Smith, Adv. in X-Ray Anal. 41, 501 (1997) |
---|
799 | omg: his omega = sample omega rotation; 0 when incident beam || sample surface, 90 |
---|
800 | when perp. to sample surface |
---|
801 | phi: his phi = sample phi rotation; usually = 0, axis rotates with omg. |
---|
802 | azm: his chi = azimuth around incident beam |
---|
803 | th: his theta = theta |
---|
804 | ''' |
---|
805 | a = npsind(th)*npcosd(omg)+npsind(azm)*npcosd(th)*npsind(omg) |
---|
806 | b = -npcosd(azm)*npcosd(th) |
---|
807 | c = npsind(th)*npsind(omg)-npsind(azm)*npcosd(th)*npcosd(omg) |
---|
808 | d = a*npcosd(phi)-b*npsind(phi) |
---|
809 | e = a*npsind(phi)+b*npcosd(phi) |
---|
810 | Fij = np.array([ |
---|
811 | [d**2,d*e,c*d], |
---|
812 | [d*e,e**2,c*e], |
---|
813 | [c*d,c*e,c**2]]) |
---|
814 | return -Fij*nptand(th) |
---|
815 | |
---|
816 | def FitStrain(rings,p0,wave,phi): |
---|
817 | |
---|
818 | def StrainPrint(ValSig): |
---|
819 | print 'Strain tensor:' |
---|
820 | ptlbls = 'names :' |
---|
821 | ptstr = 'values:' |
---|
822 | sigstr = 'esds :' |
---|
823 | for name,fmt,value,sig in ValSig: |
---|
824 | ptlbls += "%s" % (name.rjust(12)) |
---|
825 | ptstr += fmt % (value) |
---|
826 | if sig: |
---|
827 | sigstr += fmt % (sig) |
---|
828 | else: |
---|
829 | sigstr += 12*' ' |
---|
830 | print ptlbls |
---|
831 | print ptstr |
---|
832 | print sigstr |
---|
833 | |
---|
834 | def strainCalc(p,xyd,wave,phi): |
---|
835 | # E = np.array([[p[0],p[3],p[4]],[p[3],p[1],p[5]],[p[4],p[5],p[2]]]) |
---|
836 | E = np.array([[p[0],0,0],[0,p[1],0],[0,0,0]]) |
---|
837 | th,azm,dsp = xyd |
---|
838 | th0 = npasind(wave/(2.*dsp)) |
---|
839 | dth = 180.*np.sum(E*calcFij(phi,0.,azm,th).T)/(np.pi*1.e6) #in degrees & microstrain units |
---|
840 | th0 += dth |
---|
841 | return (th-th0)**2 |
---|
842 | |
---|
843 | names = ['e11','e22','e33','e12','e13','e23'] |
---|
844 | fmt = ['%12.2f','%12.2f','%12.2f','%12.2f','%12.2f','%12.5f'] |
---|
845 | p1 = [p0[0],p0[1]] |
---|
846 | result = leastsq(strainCalc,p1,args=(rings,wave,phi),full_output=True) |
---|
847 | vals = list(result[0]) |
---|
848 | chi = np.sqrt(np.sum(strainCalc(result[0],rings,wave,phi)**2)) |
---|
849 | sig = list(chi*np.sqrt(np.diag(result[1]))) |
---|
850 | ValSig = zip(names,fmt,vals,sig) |
---|
851 | StrainPrint(ValSig) |
---|
852 | # return np.array([[vals[0],vals[3],vals[4]],[vals[3],vals[1],vals[5]],[vals[4],vals[5],vals[2]]]) |
---|
853 | return np.array([[vals[0],0,0],[0,vals[1],0],[0,0,0]]) |
---|
854 | |
---|
855 | |
---|