1 | # -*- coding: utf-8 -*- |
---|
2 | ''' |
---|
3 | *GSASIIplot: plotting routines* |
---|
4 | =============================== |
---|
5 | |
---|
6 | ''' |
---|
7 | ########### SVN repository information ################### |
---|
8 | # $Date: 2013-08-14 20:52:37 +0000 (Wed, 14 Aug 2013) $ |
---|
9 | # $Author: toby $ |
---|
10 | # $Revision: 1032 $ |
---|
11 | # $URL: trunk/GSASIIplot.py $ |
---|
12 | # $Id: GSASIIplot.py 1032 2013-08-14 20:52:37Z toby $ |
---|
13 | ########### SVN repository information ################### |
---|
14 | import math |
---|
15 | import time |
---|
16 | import copy |
---|
17 | import sys |
---|
18 | import os.path |
---|
19 | import numpy as np |
---|
20 | import numpy.ma as ma |
---|
21 | import numpy.linalg as nl |
---|
22 | import wx |
---|
23 | import wx.aui |
---|
24 | import wx.glcanvas |
---|
25 | import matplotlib as mpl |
---|
26 | import mpl_toolkits.mplot3d.axes3d as mp3d |
---|
27 | import GSASIIpath |
---|
28 | GSASIIpath.SetVersionNumber("$Revision: 1032 $") |
---|
29 | import GSASIIgrid as G2gd |
---|
30 | import GSASIIimage as G2img |
---|
31 | import GSASIIpwd as G2pwd |
---|
32 | import GSASIIIO as G2IO |
---|
33 | import GSASIIpwdGUI as G2pdG |
---|
34 | import GSASIIimgGUI as G2imG |
---|
35 | import GSASIIphsGUI as G2phG |
---|
36 | import GSASIIlattice as G2lat |
---|
37 | import GSASIIspc as G2spc |
---|
38 | import GSASIImath as G2mth |
---|
39 | import pytexture as ptx |
---|
40 | from OpenGL.GL import * |
---|
41 | from OpenGL.GLU import * |
---|
42 | from OpenGL.GLE import * |
---|
43 | import gltext |
---|
44 | from matplotlib.backends.backend_wx import _load_bitmap |
---|
45 | from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas |
---|
46 | from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as Toolbar |
---|
47 | |
---|
48 | # useful degree trig functions |
---|
49 | sind = lambda x: math.sin(x*math.pi/180.) |
---|
50 | cosd = lambda x: math.cos(x*math.pi/180.) |
---|
51 | tand = lambda x: math.tan(x*math.pi/180.) |
---|
52 | asind = lambda x: 180.*math.asin(x)/math.pi |
---|
53 | acosd = lambda x: 180.*math.acos(x)/math.pi |
---|
54 | atan2d = lambda x,y: 180.*math.atan2(y,x)/math.pi |
---|
55 | atand = lambda x: 180.*math.atan(x)/math.pi |
---|
56 | # numpy versions |
---|
57 | npsind = lambda x: np.sin(x*np.pi/180.) |
---|
58 | npcosd = lambda x: np.cos(x*np.pi/180.) |
---|
59 | nptand = lambda x: np.tan(x*np.pi/180.) |
---|
60 | npacosd = lambda x: 180.*np.arccos(x)/np.pi |
---|
61 | npasind = lambda x: 180.*np.arcsin(x)/np.pi |
---|
62 | npatand = lambda x: 180.*np.arctan(x)/np.pi |
---|
63 | npatan2d = lambda x,y: 180.*np.arctan2(x,y)/np.pi |
---|
64 | |
---|
65 | class G2PlotMpl(wx.Panel): |
---|
66 | 'needs a doc string' |
---|
67 | def __init__(self,parent,id=-1,dpi=None,**kwargs): |
---|
68 | wx.Panel.__init__(self,parent,id=id,**kwargs) |
---|
69 | mpl.rcParams['legend.fontsize'] = 10 |
---|
70 | self.figure = mpl.figure.Figure(dpi=dpi,figsize=(5,6)) |
---|
71 | self.canvas = Canvas(self,-1,self.figure) |
---|
72 | self.toolbar = GSASIItoolbar(self.canvas) |
---|
73 | |
---|
74 | self.toolbar.Realize() |
---|
75 | |
---|
76 | sizer=wx.BoxSizer(wx.VERTICAL) |
---|
77 | sizer.Add(self.canvas,1,wx.EXPAND) |
---|
78 | sizer.Add(self.toolbar,0,wx.LEFT|wx.EXPAND) |
---|
79 | self.SetSizer(sizer) |
---|
80 | |
---|
81 | class G2PlotOgl(wx.Panel): |
---|
82 | 'needs a doc string' |
---|
83 | def __init__(self,parent,id=-1,dpi=None,**kwargs): |
---|
84 | self.figure = wx.Panel.__init__(self,parent,id=id,**kwargs) |
---|
85 | if 'win' in sys.platform: #Windows already double buffered |
---|
86 | self.canvas = wx.glcanvas.GLCanvas(self,-1,**kwargs) |
---|
87 | else: #fix from Jim Hester for X systems |
---|
88 | attribs = (wx.glcanvas.WX_GL_DOUBLEBUFFER,) |
---|
89 | self.canvas = wx.glcanvas.GLCanvas(self,-1,attribList=attribs,**kwargs) |
---|
90 | self.camera = {} |
---|
91 | sizer=wx.BoxSizer(wx.VERTICAL) |
---|
92 | sizer.Add(self.canvas,1,wx.EXPAND) |
---|
93 | self.SetSizer(sizer) |
---|
94 | |
---|
95 | class G2Plot3D(wx.Panel): |
---|
96 | 'needs a doc string' |
---|
97 | def __init__(self,parent,id=-1,dpi=None,**kwargs): |
---|
98 | wx.Panel.__init__(self,parent,id=id,**kwargs) |
---|
99 | self.figure = mpl.figure.Figure(dpi=dpi,figsize=(6,6)) |
---|
100 | self.canvas = Canvas(self,-1,self.figure) |
---|
101 | self.toolbar = GSASIItoolbar(self.canvas) |
---|
102 | |
---|
103 | self.toolbar.Realize() |
---|
104 | |
---|
105 | sizer=wx.BoxSizer(wx.VERTICAL) |
---|
106 | sizer.Add(self.canvas,1,wx.EXPAND) |
---|
107 | sizer.Add(self.toolbar,0,wx.LEFT|wx.EXPAND) |
---|
108 | self.SetSizer(sizer) |
---|
109 | |
---|
110 | class G2PlotNoteBook(wx.Panel): |
---|
111 | 'create a tabbed window for plotting' |
---|
112 | def __init__(self,parent,id=-1): |
---|
113 | wx.Panel.__init__(self,parent,id=id) |
---|
114 | #so one can't delete a plot page!! |
---|
115 | self.nb = wx.aui.AuiNotebook(self, \ |
---|
116 | style=wx.aui.AUI_NB_DEFAULT_STYLE ^ wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB) |
---|
117 | sizer = wx.BoxSizer() |
---|
118 | sizer.Add(self.nb,1,wx.EXPAND) |
---|
119 | self.SetSizer(sizer) |
---|
120 | self.status = parent.CreateStatusBar() |
---|
121 | self.status.SetFieldsCount(2) |
---|
122 | self.status.SetStatusWidths([150,-1]) |
---|
123 | self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged) |
---|
124 | self.nb.Bind(wx.EVT_KEY_UP,self.OnNotebookKey) |
---|
125 | |
---|
126 | self.plotList = [] |
---|
127 | |
---|
128 | def OnNotebookKey(self,event): |
---|
129 | '''Called when a keystroke event gets picked up by the notebook window |
---|
130 | rather the child. This is not expected, but somehow it does sometimes |
---|
131 | on the Mac and perhaps Linux. |
---|
132 | |
---|
133 | Assume that the page associated with the currently displayed tab |
---|
134 | has a child, .canvas; give that child the focus and pass it the event. |
---|
135 | ''' |
---|
136 | Page = self.nb.GetPage(self.nb.GetSelection()) |
---|
137 | try: |
---|
138 | Page.canvas.SetFocus() |
---|
139 | wx.PostEvent(Page.canvas,event) |
---|
140 | except AttributeError: |
---|
141 | pass |
---|
142 | |
---|
143 | def addMpl(self,name=""): |
---|
144 | 'Add a tabbed page with a matplotlib plot' |
---|
145 | page = G2PlotMpl(self.nb) |
---|
146 | self.nb.AddPage(page,name) |
---|
147 | |
---|
148 | self.plotList.append(name) |
---|
149 | |
---|
150 | return page.figure |
---|
151 | |
---|
152 | def add3D(self,name=""): |
---|
153 | 'Add a tabbed page with a 3D plot' |
---|
154 | page = G2Plot3D(self.nb) |
---|
155 | self.nb.AddPage(page,name) |
---|
156 | |
---|
157 | self.plotList.append(name) |
---|
158 | |
---|
159 | return page.figure |
---|
160 | |
---|
161 | def addOgl(self,name=""): |
---|
162 | 'Add a tabbed page with an openGL plot' |
---|
163 | page = G2PlotOgl(self.nb) |
---|
164 | self.nb.AddPage(page,name) |
---|
165 | |
---|
166 | self.plotList.append(name) |
---|
167 | |
---|
168 | return page.figure |
---|
169 | |
---|
170 | def Delete(self,name): |
---|
171 | 'delete a tabbed page' |
---|
172 | try: |
---|
173 | item = self.plotList.index(name) |
---|
174 | del self.plotList[item] |
---|
175 | self.nb.DeletePage(item) |
---|
176 | except ValueError: #no plot of this name - do nothing |
---|
177 | return |
---|
178 | |
---|
179 | def clear(self): |
---|
180 | 'clear all pages from plot window' |
---|
181 | while self.nb.GetPageCount(): |
---|
182 | self.nb.DeletePage(0) |
---|
183 | self.plotList = [] |
---|
184 | self.status.DestroyChildren() |
---|
185 | |
---|
186 | def Rename(self,oldName,newName): |
---|
187 | 'rename a tab' |
---|
188 | try: |
---|
189 | item = self.plotList.index(oldName) |
---|
190 | self.plotList[item] = newName |
---|
191 | self.nb.SetPageText(item,newName) |
---|
192 | except ValueError: #no plot of this name - do nothing |
---|
193 | return |
---|
194 | |
---|
195 | def OnPageChanged(self,event): |
---|
196 | 'respond to someone pressing a tab on the plot window' |
---|
197 | if self.plotList: |
---|
198 | self.status.SetStatusText('Better to select this from GSAS-II data tree',1) |
---|
199 | self.status.DestroyChildren() #get rid of special stuff on status bar |
---|
200 | |
---|
201 | class GSASIItoolbar(Toolbar): |
---|
202 | 'needs a doc string' |
---|
203 | ON_MPL_HELP = wx.NewId() |
---|
204 | ON_MPL_KEY = wx.NewId() |
---|
205 | def __init__(self,plotCanvas): |
---|
206 | Toolbar.__init__(self,plotCanvas) |
---|
207 | POSITION_OF_CONFIGURE_SUBPLOTS_BTN = 6 |
---|
208 | self.DeleteToolByPos(POSITION_OF_CONFIGURE_SUBPLOTS_BTN) |
---|
209 | parent = self.GetParent() |
---|
210 | key = os.path.join(os.path.split(__file__)[0],'key.ico') |
---|
211 | self.AddSimpleTool(self.ON_MPL_KEY,_load_bitmap(key),'Key press','Select key press') |
---|
212 | wx.EVT_TOOL(self,self.ON_MPL_KEY,self.OnKey) |
---|
213 | help = os.path.join(os.path.split(__file__)[0],'help.ico') |
---|
214 | self.AddSimpleTool(self.ON_MPL_HELP,_load_bitmap(help),'Help on','Show help on') |
---|
215 | wx.EVT_TOOL(self,self.ON_MPL_HELP,self.OnHelp) |
---|
216 | def OnHelp(self,event): |
---|
217 | 'needs a doc string' |
---|
218 | Page = self.GetParent().GetParent() |
---|
219 | pageNo = Page.GetSelection() |
---|
220 | bookmark = Page.GetPageText(pageNo) |
---|
221 | bookmark = bookmark.strip(')').replace('(','_') |
---|
222 | G2gd.ShowHelp(bookmark,self.TopLevelParent) |
---|
223 | def OnKey(self,event): |
---|
224 | 'needs a doc string' |
---|
225 | parent = self.GetParent() |
---|
226 | if parent.Choice: |
---|
227 | dlg = wx.SingleChoiceDialog(parent,'Select','Key press',list(parent.Choice)) |
---|
228 | if dlg.ShowModal() == wx.ID_OK: |
---|
229 | sel = dlg.GetSelection() |
---|
230 | event.key = parent.Choice[sel][0] |
---|
231 | parent.keyPress(event) |
---|
232 | dlg.Destroy() |
---|
233 | |
---|
234 | ################################################################################ |
---|
235 | ##### PlotSngl |
---|
236 | ################################################################################ |
---|
237 | |
---|
238 | def PlotSngl(self,newPlot=False): |
---|
239 | '''Single crystal structure factor plotting package - displays zone of reflections as rings proportional |
---|
240 | to F, F**2, etc. as requested |
---|
241 | ''' |
---|
242 | from matplotlib.patches import Circle |
---|
243 | global HKL,HKLF |
---|
244 | |
---|
245 | def OnSCMotion(event): |
---|
246 | xpos = event.xdata |
---|
247 | if xpos: |
---|
248 | xpos = round(xpos) #avoid out of frame mouse position |
---|
249 | ypos = round(event.ydata) |
---|
250 | zpos = Data['Layer'] |
---|
251 | if '100' in Data['Zone']: |
---|
252 | HKLtxt = '(%3d,%3d,%3d)'%(zpos,xpos,ypos) |
---|
253 | elif '010' in Data['Zone']: |
---|
254 | HKLtxt = '(%3d,%3d,%3d)'%(xpos,zpos,ypos) |
---|
255 | elif '001' in Data['Zone']: |
---|
256 | HKLtxt = '(%3d,%3d,%3d)'%(xpos,ypos,zpos) |
---|
257 | Page.canvas.SetToolTipString(HKLtxt) |
---|
258 | self.G2plotNB.status.SetFields(['HKL = '+HKLtxt,'']) |
---|
259 | |
---|
260 | def OnSCPick(event): |
---|
261 | zpos = Data['Layer'] |
---|
262 | pos = event.artist.center |
---|
263 | if '100' in Data['Zone']: |
---|
264 | Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(zpos,pos[0],pos[1])) |
---|
265 | hkl = np.array([zpos,pos[0],pos[1]]) |
---|
266 | elif '010' in Data['Zone']: |
---|
267 | Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],zpos,pos[1])) |
---|
268 | hkl = np.array([pos[0],zpos,pos[1]]) |
---|
269 | elif '001' in Data['Zone']: |
---|
270 | Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],pos[1],zpos)) |
---|
271 | hkl = np.array([pos[0],pos[1],zpos]) |
---|
272 | h,k,l = hkl |
---|
273 | hklf = HKLF[np.where(np.all(HKL-hkl == [0,0,0],axis=1))] |
---|
274 | if len(hklf): |
---|
275 | Fosq,sig,Fcsq = hklf[0] |
---|
276 | HKLtxt = '(%3d,%3d,%3d %.2f %.3f %.2f %.2f)'%(h,k,l,Fosq,sig,Fcsq,(Fosq-Fcsq)/(scale*sig)) |
---|
277 | self.G2plotNB.status.SetFields(['','HKL, Fosq, sig, Fcsq, delFsq/sig = '+HKLtxt]) |
---|
278 | |
---|
279 | try: |
---|
280 | plotNum = self.G2plotNB.plotList.index('Structure Factors') |
---|
281 | Page = self.G2plotNB.nb.GetPage(plotNum) |
---|
282 | if not newPlot: |
---|
283 | Plot = Page.figure.gca() #get previous powder plot & get limits |
---|
284 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
285 | Page.figure.clf() |
---|
286 | Page.Choice = None |
---|
287 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
288 | except ValueError: |
---|
289 | Plot = self.G2plotNB.addMpl('Structure Factors').gca() |
---|
290 | plotNum = self.G2plotNB.plotList.index('Structure Factors') |
---|
291 | Page = self.G2plotNB.nb.GetPage(plotNum) |
---|
292 | Page.canvas.mpl_connect('pick_event', OnSCPick) |
---|
293 | Page.canvas.mpl_connect('motion_notify_event', OnSCMotion) |
---|
294 | Page.Choice = None |
---|
295 | Page.SetFocus() |
---|
296 | |
---|
297 | Plot.set_aspect(aspect='equal') |
---|
298 | HKLref = self.PatternTree.GetItemPyData(self.Sngl)[1] |
---|
299 | Data = self.PatternTree.GetItemPyData( |
---|
300 | G2gd.GetPatternTreeItemId(self,self.Sngl, 'HKL Plot Controls')) |
---|
301 | Type = Data['Type'] |
---|
302 | scale = Data['Scale'] |
---|
303 | HKLmax = Data['HKLmax'] |
---|
304 | HKLmin = Data['HKLmin'] |
---|
305 | FosqMax = Data['FoMax'] |
---|
306 | FoMax = math.sqrt(FosqMax) |
---|
307 | xlabel = ['k, h=','h, k=','h, l='] |
---|
308 | ylabel = ['l','l','k'] |
---|
309 | zones = ['100','010','001'] |
---|
310 | pzone = [[1,2],[0,2],[0,1]] |
---|
311 | izone = zones.index(Data['Zone']) |
---|
312 | Plot.set_title(self.PatternTree.GetItemText(self.Sngl)[5:]) |
---|
313 | HKL = [] |
---|
314 | HKLF = [] |
---|
315 | for refl in HKLref: |
---|
316 | H = np.array(refl[:3]) |
---|
317 | Fosq,sig,Fcsq = refl[5:8] |
---|
318 | HKL.append(H) |
---|
319 | HKLF.append([Fosq,sig,Fcsq]) |
---|
320 | if H[izone] == Data['Layer']: |
---|
321 | A = 0 |
---|
322 | B = 0 |
---|
323 | if Type == 'Fosq': |
---|
324 | A = scale*Fosq/FosqMax |
---|
325 | B = scale*Fcsq/FosqMax |
---|
326 | C = abs(A-B) |
---|
327 | elif Type == 'Fo': |
---|
328 | A = scale*math.sqrt(max(0,Fosq))/FoMax |
---|
329 | B = scale*math.sqrt(max(0,Fcsq))/FoMax |
---|
330 | C = abs(A-B) |
---|
331 | elif Type == '|DFsq|/sig': |
---|
332 | if sig > 0.: |
---|
333 | A = scale*(Fosq-Fcsq)/(sig) |
---|
334 | B = 0 |
---|
335 | elif Type == '|DFsq|>sig': |
---|
336 | if sig > 0.: |
---|
337 | A = (Fosq-Fcsq)/sig |
---|
338 | if abs(A) < 1.0: A = 0 |
---|
339 | A *= scale |
---|
340 | B = 0 |
---|
341 | elif Type == '|DFsq|>3sig': |
---|
342 | if sig > 0.: |
---|
343 | A = (Fosq-Fcsq)/sig |
---|
344 | if abs(A) < 3.0: A = 0 |
---|
345 | A *= scale |
---|
346 | B = 0 |
---|
347 | xy = (H[pzone[izone][0]],H[pzone[izone][1]]) |
---|
348 | if Type in ['|DFsq|/sig','|DFsq|>sig','|DFsq|>3sig']: |
---|
349 | if A > 0.0: |
---|
350 | Plot.add_artist(Circle(xy,radius=A,ec='g',fc='w',picker=3)) |
---|
351 | else: |
---|
352 | Plot.add_artist(Circle(xy,radius=-A,ec='r',fc='w',picker=3)) |
---|
353 | else: |
---|
354 | if A > 0.0 and A > B: |
---|
355 | Plot.add_artist(Circle(xy,radius=A,ec='g',fc='w',picker=3)) |
---|
356 | if B: |
---|
357 | Plot.add_artist(Circle(xy,radius=B,ec='b',fc='w')) |
---|
358 | if A < B: |
---|
359 | Plot.add_artist(Circle(xy,radius=A,ec='g',fc='w',picker=3)) |
---|
360 | radius = C |
---|
361 | if radius > 0: |
---|
362 | if A > B: |
---|
363 | Plot.add_artist(Circle(xy,radius=radius,ec='g',fc='g')) |
---|
364 | else: |
---|
365 | Plot.add_artist(Circle(xy,radius=radius,ec='r',fc='r')) |
---|
366 | HKL = np.array(HKL,dtype=np.int) |
---|
367 | HKLF = np.array(HKLF) |
---|
368 | Plot.set_xlabel(xlabel[izone]+str(Data['Layer']),fontsize=12) |
---|
369 | Plot.set_ylabel(ylabel[izone],fontsize=12) |
---|
370 | Plot.set_xlim((HKLmin[pzone[izone][0]],HKLmax[pzone[izone][0]])) |
---|
371 | Plot.set_ylim((HKLmin[pzone[izone][1]],HKLmax[pzone[izone][1]])) |
---|
372 | Page.canvas.draw() |
---|
373 | # if not newPlot: |
---|
374 | # Page.toolbar.push_current() |
---|
375 | # Plot.set_xlim(xylim[0]) |
---|
376 | # Plot.set_ylim(xylim[1]) |
---|
377 | # xylim = [] |
---|
378 | # Page.toolbar.push_current() |
---|
379 | # Page.toolbar.draw() |
---|
380 | # else: |
---|
381 | # Page.canvas.draw() |
---|
382 | |
---|
383 | ################################################################################ |
---|
384 | ##### PlotPatterns |
---|
385 | ################################################################################ |
---|
386 | |
---|
387 | def PlotPatterns(G2frame,newPlot=False): |
---|
388 | '''Powder pattern plotting package - displays single or multiple powder patterns as intensity vs |
---|
389 | 2-theta, q or TOF. Can display multiple patterns as "waterfall plots" or contour plots. Log I |
---|
390 | plotting available. |
---|
391 | ''' |
---|
392 | global HKL |
---|
393 | global exclLines |
---|
394 | def OnPlotKeyPress(event): |
---|
395 | newPlot = False |
---|
396 | if event.key == 'w': |
---|
397 | if G2frame.Weight: |
---|
398 | G2frame.Weight = False |
---|
399 | else: |
---|
400 | G2frame.Weight = True |
---|
401 | G2frame.SinglePlot = True |
---|
402 | newPlot = True |
---|
403 | elif event.key == 'b': |
---|
404 | if G2frame.SubBack: |
---|
405 | G2frame.SubBack = False |
---|
406 | else: |
---|
407 | G2frame.SubBack = True |
---|
408 | G2frame.SinglePlot = True |
---|
409 | elif event.key == 'n': |
---|
410 | if G2frame.Contour: |
---|
411 | pass |
---|
412 | else: |
---|
413 | if G2frame.logPlot: |
---|
414 | G2frame.logPlot = False |
---|
415 | else: |
---|
416 | G2frame.Offset[0] = 0 |
---|
417 | G2frame.logPlot = True |
---|
418 | newPlot = True |
---|
419 | elif event.key == 'u': |
---|
420 | if G2frame.Contour: |
---|
421 | G2frame.Cmax = min(1.0,G2frame.Cmax*1.2) |
---|
422 | elif G2frame.logPlot: |
---|
423 | pass |
---|
424 | elif G2frame.Offset[0] < 100.: |
---|
425 | G2frame.Offset[0] += 1. |
---|
426 | elif event.key == 'd': |
---|
427 | if G2frame.Contour: |
---|
428 | G2frame.Cmax = max(0.0,G2frame.Cmax*0.8) |
---|
429 | elif G2frame.logPlot: |
---|
430 | pass |
---|
431 | elif G2frame.Offset[0] > 0.: |
---|
432 | G2frame.Offset[0] -= 1. |
---|
433 | elif event.key == 'l': |
---|
434 | G2frame.Offset[1] -= 1. |
---|
435 | elif event.key == 'r': |
---|
436 | G2frame.Offset[1] += 1. |
---|
437 | elif event.key == 'o': |
---|
438 | G2frame.Offset = [0,0] |
---|
439 | elif event.key == 'c': |
---|
440 | newPlot = True |
---|
441 | if G2frame.Contour: |
---|
442 | G2frame.Contour = False |
---|
443 | else: |
---|
444 | G2frame.Contour = True |
---|
445 | G2frame.SinglePlot = False |
---|
446 | G2frame.Offset = [0.,0.] |
---|
447 | elif event.key == 'q': |
---|
448 | newPlot = True |
---|
449 | if G2frame.qPlot: |
---|
450 | G2frame.qPlot = False |
---|
451 | else: |
---|
452 | G2frame.qPlot = True |
---|
453 | elif event.key == 's': |
---|
454 | if G2frame.Contour: |
---|
455 | choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] |
---|
456 | choice.sort() |
---|
457 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice) |
---|
458 | if dlg.ShowModal() == wx.ID_OK: |
---|
459 | sel = dlg.GetSelection() |
---|
460 | G2frame.ContourColor = choice[sel] |
---|
461 | else: |
---|
462 | G2frame.ContourColor = 'Paired' |
---|
463 | dlg.Destroy() |
---|
464 | else: |
---|
465 | if G2frame.SinglePlot: |
---|
466 | G2frame.SinglePlot = False |
---|
467 | else: |
---|
468 | G2frame.SinglePlot = True |
---|
469 | newPlot = True |
---|
470 | elif event.key == '+': |
---|
471 | if G2frame.PickId: |
---|
472 | G2frame.PickId = False |
---|
473 | elif event.key == 'i': #for smoothing contour plot |
---|
474 | choice = ['nearest','bilinear','bicubic','spline16','spline36','hanning', |
---|
475 | 'hamming','hermite','kaiser','quadric','catrom','gaussian','bessel', |
---|
476 | 'mitchell','sinc','lanczos'] |
---|
477 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Interpolation',choice) |
---|
478 | if dlg.ShowModal() == wx.ID_OK: |
---|
479 | sel = dlg.GetSelection() |
---|
480 | G2frame.Interpolate = choice[sel] |
---|
481 | else: |
---|
482 | G2frame.Interpolate = 'nearest' |
---|
483 | dlg.Destroy() |
---|
484 | |
---|
485 | PlotPatterns(G2frame,newPlot=newPlot) |
---|
486 | |
---|
487 | def OnMotion(event): |
---|
488 | xpos = event.xdata |
---|
489 | if xpos: #avoid out of frame mouse position |
---|
490 | ypos = event.ydata |
---|
491 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
492 | try: |
---|
493 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
494 | if 'C' in Parms['Type'][0]: |
---|
495 | wave = G2mth.getWave(Parms) |
---|
496 | if G2frame.qPlot: |
---|
497 | try: |
---|
498 | xpos = 2.0*asind(xpos*wave/(4*math.pi)) |
---|
499 | except ValueError: #avoid bad value in asin beyond upper limit |
---|
500 | pass |
---|
501 | dsp = 0.0 |
---|
502 | if abs(xpos) > 0.: #avoid possible singularity at beam center |
---|
503 | dsp = wave/(2.*sind(abs(xpos)/2.0)) |
---|
504 | if G2frame.Contour: |
---|
505 | G2frame.G2plotNB.status.SetStatusText('2-theta =%9.3f d =%9.5f pattern ID =%5d'%(xpos,dsp,int(ypos)),1) |
---|
506 | else: |
---|
507 | G2frame.G2plotNB.status.SetStatusText('2-theta =%9.3f d =%9.5f Intensity =%9.1f'%(xpos,dsp,ypos),1) |
---|
508 | else: #TOF neutrons |
---|
509 | dsp = 0.0 |
---|
510 | difC = Parms['difC'][1] |
---|
511 | dsp = xpos/difC #rough approx.! |
---|
512 | if G2frame.Contour: |
---|
513 | G2frame.G2plotNB.status.SetStatusText('TOF =%9.3f d =%9.5f pattern ID =%5d'%(xpos,dsp,int(ypos)),1) |
---|
514 | else: |
---|
515 | G2frame.G2plotNB.status.SetStatusText('TOF =%9.3f d =%9.5f Intensity =%9.1f'%(xpos,dsp,ypos),1) |
---|
516 | if G2frame.itemPicked: |
---|
517 | Page.canvas.SetToolTipString('%9.3f'%(xpos)) |
---|
518 | if G2frame.PickId: |
---|
519 | found = [] |
---|
520 | if G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Index Peak List','Unit Cells List','Reflection Lists'] or \ |
---|
521 | 'PWDR' in G2frame.PatternTree.GetItemText(PickId): |
---|
522 | if len(HKL): |
---|
523 | view = Page.toolbar._views.forward()[0][:2] |
---|
524 | wid = view[1]-view[0] |
---|
525 | found = HKL[np.where(np.fabs(HKL.T[5]-xpos) < 0.002*wid)] |
---|
526 | if len(found): |
---|
527 | h,k,l = found[0][:3] |
---|
528 | Page.canvas.SetToolTipString('%d,%d,%d'%(int(h),int(k),int(l))) |
---|
529 | else: |
---|
530 | Page.canvas.SetToolTipString('') |
---|
531 | |
---|
532 | except TypeError: |
---|
533 | G2frame.G2plotNB.status.SetStatusText('Select PWDR powder pattern first',1) |
---|
534 | |
---|
535 | def OnPick(event): |
---|
536 | if G2frame.itemPicked is not None: return |
---|
537 | PatternId = G2frame.PatternId |
---|
538 | try: |
---|
539 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
540 | except TypeError: |
---|
541 | return |
---|
542 | if 'C' in Parms['Type'][0]: |
---|
543 | wave = G2mth.getWave(Parms) |
---|
544 | else: |
---|
545 | difC = Parms['difC'][1] |
---|
546 | PickId = G2frame.PickId |
---|
547 | pick = event.artist |
---|
548 | mouse = event.mouseevent |
---|
549 | xpos = pick.get_xdata() |
---|
550 | ypos = pick.get_ydata() |
---|
551 | ind = event.ind |
---|
552 | xy = list(zip(np.take(xpos,ind),np.take(ypos,ind))[0]) |
---|
553 | if G2frame.PatternTree.GetItemText(PickId) == 'Peak List': |
---|
554 | if ind.all() != [0]: #picked a data point |
---|
555 | data = G2frame.PatternTree.GetItemPyData(G2frame.PickId) |
---|
556 | XY = G2mth.setPeakparms(Parms,Parms2,xy[0],xy[1]) #what happens for a q-plot??? |
---|
557 | data.append(XY) |
---|
558 | G2pdG.UpdatePeakGrid(G2frame,data) |
---|
559 | PlotPatterns(G2frame) |
---|
560 | else: #picked a peak list line |
---|
561 | G2frame.itemPicked = pick |
---|
562 | elif G2frame.PatternTree.GetItemText(PickId) == 'Limits': |
---|
563 | if ind.all() != [0]: #picked a data point |
---|
564 | LimitId = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits') |
---|
565 | data = G2frame.PatternTree.GetItemPyData(LimitId) |
---|
566 | if 'C' in Parms['Type'][0]: #CW data - TOF later in an elif |
---|
567 | if G2frame.qPlot: #qplot - convert back to 2-theta |
---|
568 | xy[0] = 2.0*asind(xy[0]*wave/(4*math.pi)) |
---|
569 | if G2frame.ifGetExclude: |
---|
570 | excl = [0,0] |
---|
571 | excl[0] = max(data[1][0],min(xy[0],data[1][1])) |
---|
572 | excl[1] = excl[0]+0.1 |
---|
573 | data.append(excl) |
---|
574 | G2frame.ifGetExclude = False |
---|
575 | else: |
---|
576 | if mouse.button==1: |
---|
577 | data[1][0] = min(xy[0],data[1][1]) |
---|
578 | if mouse.button==3: |
---|
579 | data[1][1] = max(xy[0],data[1][0]) |
---|
580 | G2frame.PatternTree.SetItemPyData(LimitId,data) |
---|
581 | G2pdG.UpdateLimitsGrid(G2frame,data) |
---|
582 | wx.CallAfter(PlotPatterns,G2frame) |
---|
583 | else: #picked a limit line |
---|
584 | G2frame.itemPicked = pick |
---|
585 | elif G2frame.PatternTree.GetItemText(PickId) == 'Reflection Lists' or \ |
---|
586 | 'PWDR' in G2frame.PatternTree.GetItemText(PickId): |
---|
587 | G2frame.itemPicked = pick |
---|
588 | pick = str(pick) |
---|
589 | |
---|
590 | def OnRelease(event): |
---|
591 | if G2frame.itemPicked is None: return |
---|
592 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
593 | if 'C' in Parms['Type'][0]: |
---|
594 | wave = G2mth.getWave(Parms) |
---|
595 | else: |
---|
596 | difC = Parms['difC'][1] |
---|
597 | xpos = event.xdata |
---|
598 | PickId = G2frame.PickId |
---|
599 | if G2frame.PatternTree.GetItemText(PickId) in ['Peak List','Limits'] and xpos: |
---|
600 | lines = [] |
---|
601 | for line in G2frame.Lines: |
---|
602 | lines.append(line.get_xdata()[0]) |
---|
603 | # print G2frame.itemPicked.get_xdata() |
---|
604 | lineNo = lines.index(G2frame.itemPicked.get_xdata()[0]) |
---|
605 | if lineNo in [0,1] or lineNo in exclLines: |
---|
606 | LimitId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Limits') |
---|
607 | data = G2frame.PatternTree.GetItemPyData(LimitId) |
---|
608 | id = lineNo/2+1 |
---|
609 | id2 = lineNo%2 |
---|
610 | if G2frame.qPlot: |
---|
611 | if 'C' in Parms['Type'][0]: |
---|
612 | data[id][id2] = 2.0*asind(wave*xpos/(4*math.pi)) |
---|
613 | else: |
---|
614 | data[id][id2] = 2*math.pi*Parms['difC'][1]/xpos |
---|
615 | else: |
---|
616 | data[id][id2] = xpos |
---|
617 | if id > 1 and data[id][0] > data[id][1]: |
---|
618 | data[id].reverse() |
---|
619 | G2frame.PatternTree.SetItemPyData(LimitId,data) |
---|
620 | if G2frame.PatternTree.GetItemText(G2frame.PickId) == 'Limits': |
---|
621 | G2pdG.UpdateLimitsGrid(G2frame,data) |
---|
622 | else: |
---|
623 | PeakId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List') |
---|
624 | data = G2frame.PatternTree.GetItemPyData(PeakId) |
---|
625 | if event.button == 3: |
---|
626 | del data[lineNo-2] |
---|
627 | else: |
---|
628 | if G2frame.qPlot: |
---|
629 | data[lineNo-2][0] = 2.0*asind(wave*xpos/(4*math.pi)) |
---|
630 | else: |
---|
631 | data[lineNo-2][0] = xpos |
---|
632 | G2frame.PatternTree.SetItemPyData(PeakId,data) |
---|
633 | G2pdG.UpdatePeakGrid(G2frame,data) |
---|
634 | elif (G2frame.PatternTree.GetItemText(PickId) == 'Reflection Lists' or \ |
---|
635 | 'PWDR' in G2frame.PatternTree.GetItemText(PickId)) and xpos: |
---|
636 | Phases = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists')) |
---|
637 | pick = str(G2frame.itemPicked).split('(')[1].strip(')') |
---|
638 | if 'line' not in pick: #avoid data points, etc. |
---|
639 | num = Phases.keys().index(pick) |
---|
640 | if num: |
---|
641 | G2frame.refDelt = -(event.ydata-G2frame.refOffset)/(num*Ymax) |
---|
642 | else: #1st row of refl ticks |
---|
643 | G2frame.refOffset = event.ydata |
---|
644 | PlotPatterns(G2frame) |
---|
645 | G2frame.itemPicked = None |
---|
646 | |
---|
647 | xylim = [] |
---|
648 | try: |
---|
649 | plotNum = G2frame.G2plotNB.plotList.index('Powder Patterns') |
---|
650 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
651 | if not newPlot: |
---|
652 | Plot = Page.figure.gca() #get previous powder plot & get limits |
---|
653 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
654 | Page.figure.clf() |
---|
655 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
656 | except ValueError: |
---|
657 | newPlot = True |
---|
658 | G2frame.Cmax = 1.0 |
---|
659 | Plot = G2frame.G2plotNB.addMpl('Powder Patterns').gca() |
---|
660 | plotNum = G2frame.G2plotNB.plotList.index('Powder Patterns') |
---|
661 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
662 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
663 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
664 | Page.canvas.mpl_connect('pick_event', OnPick) |
---|
665 | Page.canvas.mpl_connect('button_release_event', OnRelease) |
---|
666 | Page.SetFocus() |
---|
667 | G2frame.G2plotNB.status.DestroyChildren() |
---|
668 | if G2frame.Contour: |
---|
669 | Page.Choice = (' key press','d: lower contour max','u: raise contour max', |
---|
670 | 'i: interpolation method','s: color scheme','c: contour off') |
---|
671 | else: |
---|
672 | if G2frame.logPlot: |
---|
673 | Page.Choice = (' key press','n: log(I) off','l: offset left','r: offset right', |
---|
674 | 'c: contour on','q: toggle q plot','s: toggle single plot','+: no selection') |
---|
675 | else: |
---|
676 | Page.Choice = (' key press','l: offset left','r: offset right','d: offset down', |
---|
677 | 'u: offset up','o: reset offset','b: toggle subtract background','n: log(I) on','c: contour on', |
---|
678 | 'q: toggle q plot','s: toggle single plot','w: toggle divide by sig','+: no selection') |
---|
679 | Page.keyPress = OnPlotKeyPress |
---|
680 | |
---|
681 | PickId = G2frame.PickId |
---|
682 | PatternId = G2frame.PatternId |
---|
683 | colors=['b','g','r','c','m','k'] |
---|
684 | Lines = [] |
---|
685 | exclLines = [] |
---|
686 | if G2frame.SinglePlot: |
---|
687 | Pattern = G2frame.PatternTree.GetItemPyData(PatternId) |
---|
688 | Pattern.append(G2frame.PatternTree.GetItemText(PatternId)) |
---|
689 | PlotList = [Pattern,] |
---|
690 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, |
---|
691 | G2frame.PatternId, 'Instrument Parameters')) |
---|
692 | ParmList = [Parms,] |
---|
693 | Title = Pattern[-1] |
---|
694 | else: |
---|
695 | Title = os.path.split(G2frame.GSASprojectfile)[1] |
---|
696 | PlotList = [] |
---|
697 | ParmList = [] |
---|
698 | item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root) |
---|
699 | while item: |
---|
700 | if 'PWDR' in G2frame.PatternTree.GetItemText(item): |
---|
701 | Pattern = G2frame.PatternTree.GetItemPyData(item) |
---|
702 | if len(Pattern) < 3: # put name on end if needed |
---|
703 | Pattern.append(G2frame.PatternTree.GetItemText(item)) |
---|
704 | PlotList.append(Pattern) |
---|
705 | ParmList.append(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, |
---|
706 | item,'Instrument Parameters'))[0]) |
---|
707 | item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie) |
---|
708 | Ymax = 1.0 |
---|
709 | lenX = 0 |
---|
710 | if PickId: |
---|
711 | if G2frame.PatternTree.GetItemText(PickId) in ['Reflection Lists']: |
---|
712 | Phases = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists')) |
---|
713 | HKL = [] |
---|
714 | if Phases: |
---|
715 | for peak in Phases[G2frame.RefList]: |
---|
716 | HKL.append(peak[:6]) |
---|
717 | HKL = np.array(HKL) |
---|
718 | else: |
---|
719 | HKL = np.array(G2frame.HKL) |
---|
720 | for Pattern in PlotList: |
---|
721 | xye = Pattern[1] |
---|
722 | Ymax = max(Ymax,max(xye[1])) |
---|
723 | offset = G2frame.Offset[0]*Ymax/100.0 |
---|
724 | if G2frame.logPlot: |
---|
725 | Title = 'log('+Title+')' |
---|
726 | Plot.set_title(Title) |
---|
727 | if G2frame.qPlot: |
---|
728 | Plot.set_xlabel(r'$Q, \AA^{-1}$',fontsize=14) |
---|
729 | else: |
---|
730 | if 'C' in ParmList[0]['Type'][0]: |
---|
731 | Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14) |
---|
732 | else: |
---|
733 | Plot.set_xlabel(r'TOF, $\mathsf{\mu}$s',fontsize=14) |
---|
734 | if G2frame.Weight: |
---|
735 | Plot.set_ylabel(r'$\mathsf{I/\sigma(I)}$',fontsize=14) |
---|
736 | else: |
---|
737 | if 'C' in ParmList[0]['Type'][0]: |
---|
738 | Plot.set_ylabel('Intensity',fontsize=14) |
---|
739 | else: |
---|
740 | Plot.set_ylabel('Normalized intensity',fontsize=14) |
---|
741 | if G2frame.Contour: |
---|
742 | ContourZ = [] |
---|
743 | ContourY = [] |
---|
744 | Nseq = 0 |
---|
745 | if len(PlotList) < 2: |
---|
746 | G2frame.Contour = False |
---|
747 | for N,Pattern in enumerate(PlotList): |
---|
748 | Parms = ParmList[N] |
---|
749 | if 'C' in Parms['Type'][0]: |
---|
750 | wave = G2mth.getWave(Parms) |
---|
751 | else: |
---|
752 | difC = Parms['difC'][1] |
---|
753 | ifpicked = False |
---|
754 | LimitId = 0 |
---|
755 | xye = ma.array(ma.getdata(Pattern[1])) |
---|
756 | if PickId: |
---|
757 | ifpicked = Pattern[2] == G2frame.PatternTree.GetItemText(PatternId) |
---|
758 | LimitId = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits') |
---|
759 | limits = np.array(G2frame.PatternTree.GetItemPyData(LimitId)) |
---|
760 | excls = limits[2:] |
---|
761 | for excl in excls: |
---|
762 | xye[0] = ma.masked_inside(xye[0],excl[0],excl[1]) |
---|
763 | if G2frame.qPlot: |
---|
764 | Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, Pattern[2]) |
---|
765 | if 'C' in Parms['Type'][0]: |
---|
766 | X = 4*np.pi*npsind((xye[0]-Parms['Zero'][1])/2.0)/wave |
---|
767 | else: |
---|
768 | X = 2*np.pi*Parms['difC'][1]/(xye[0]-Parms['Zero'][1]) |
---|
769 | else: |
---|
770 | X = xye[0]-Parms['Zero'][1] |
---|
771 | if not lenX: |
---|
772 | lenX = len(X) |
---|
773 | Y = xye[1]+offset*N |
---|
774 | if LimitId: |
---|
775 | limits = np.array(G2frame.PatternTree.GetItemPyData(LimitId)) |
---|
776 | if G2frame.qPlot: |
---|
777 | if 'C' in Parms['Type'][0]: |
---|
778 | limits = 4*np.pi*npsind(limits/2.0)/wave |
---|
779 | else: |
---|
780 | limits = 2*np.pi*difC/limits |
---|
781 | Lines.append(Plot.axvline(limits[1][0],color='g',dashes=(5,5),picker=3.)) |
---|
782 | Lines.append(Plot.axvline(limits[1][1],color='r',dashes=(5,5),picker=3.)) |
---|
783 | for i,item in enumerate(limits[2:]): |
---|
784 | Lines.append(Plot.axvline(item[0],color='m',dashes=(5,5),picker=3.)) |
---|
785 | Lines.append(Plot.axvline(item[1],color='m',dashes=(5,5),picker=3.)) |
---|
786 | exclLines += [2*i+2,2*i+3] |
---|
787 | if G2frame.Contour: |
---|
788 | |
---|
789 | if lenX == len(X): |
---|
790 | ContourY.append(N) |
---|
791 | ContourZ.append(Y) |
---|
792 | ContourX = X |
---|
793 | Nseq += 1 |
---|
794 | Plot.set_ylabel('Data sequence',fontsize=12) |
---|
795 | else: |
---|
796 | X += G2frame.Offset[1]*.005*N |
---|
797 | Xum = ma.getdata(X) |
---|
798 | if ifpicked: |
---|
799 | Z = xye[3]+offset*N |
---|
800 | W = xye[4]+offset*N |
---|
801 | D = xye[5]-Ymax*G2frame.delOffset |
---|
802 | if G2frame.logPlot: |
---|
803 | Plot.semilogy(X,Y,colors[N%6]+'+',picker=3.,clip_on=False,nonposy='mask') |
---|
804 | Plot.semilogy(X,Z,colors[(N+1)%6],picker=False,nonposy='mask') |
---|
805 | Plot.semilogy(X,W,colors[(N+2)%6],picker=False,nonposy='mask') |
---|
806 | elif G2frame.Weight: |
---|
807 | DY = xye[1]*np.sqrt(xye[2]) |
---|
808 | DYmax = max(DY) |
---|
809 | DZ = xye[3]*np.sqrt(xye[2]) |
---|
810 | DS = xye[5]*np.sqrt(xye[2])-DYmax*G2frame.delOffset |
---|
811 | Plot.plot(X,DY,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
812 | Plot.plot(X,DZ,colors[(N+1)%6],picker=False) |
---|
813 | Plot.plot(X,DS,colors[(N+3)%6],picker=False) |
---|
814 | Plot.axhline(0.,color=wx.BLACK) |
---|
815 | else: |
---|
816 | if G2frame.SubBack: |
---|
817 | Plot.plot(Xum,Y-W,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
818 | Plot.plot(X,Z-W,colors[(N+1)%6],picker=False) |
---|
819 | else: |
---|
820 | Plot.plot(Xum,Y,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
821 | Plot.plot(X,Z,colors[(N+1)%6],picker=False) |
---|
822 | Plot.plot(X,W,colors[(N+2)%6],picker=False) |
---|
823 | Plot.plot(X,D,colors[(N+3)%6],picker=False) |
---|
824 | Plot.axhline(0.,color=wx.BLACK) |
---|
825 | Page.canvas.SetToolTipString('') |
---|
826 | if G2frame.PatternTree.GetItemText(PickId) == 'Peak List': |
---|
827 | tip = 'On data point: Pick peak - L or R MB. On line: L-move, R-delete' |
---|
828 | Page.canvas.SetToolTipString(tip) |
---|
829 | data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List')) |
---|
830 | for item in data: |
---|
831 | if G2frame.qPlot: |
---|
832 | if 'C' in Parms['Type'][0]: |
---|
833 | Lines.append(Plot.axvline(4*math.pi*sind(item[0]/2.)/wave,color=colors[N%6],picker=2.)) |
---|
834 | else: |
---|
835 | Lines.append(Plot.axvline(2*math.pi*difC/item[0],color=colors[N%6],picker=2.)) |
---|
836 | else: |
---|
837 | Lines.append(Plot.axvline(item[0],color=colors[N%6],picker=2.)) |
---|
838 | if G2frame.PatternTree.GetItemText(PickId) == 'Limits': |
---|
839 | tip = 'On data point: Lower limit - L MB; Upper limit - R MB. On limit: MB down to move' |
---|
840 | Page.canvas.SetToolTipString(tip) |
---|
841 | data = G2frame.LimitsTable.GetData() |
---|
842 | else: |
---|
843 | if G2frame.logPlot: |
---|
844 | Plot.semilogy(X,Y,colors[N%6],picker=False,nonposy='clip') |
---|
845 | else: |
---|
846 | Plot.plot(X,Y,colors[N%6],picker=False) |
---|
847 | if PickId and not G2frame.Contour: |
---|
848 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters')) |
---|
849 | if 'C' in Parms['Type'][0]: |
---|
850 | wave = G2mth.getWave(Parms) |
---|
851 | else: |
---|
852 | difC = Parms['difC'][1] |
---|
853 | if G2frame.PatternTree.GetItemText(PickId) in ['Index Peak List','Unit Cells List']: |
---|
854 | peaks = np.array((G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List')))) |
---|
855 | for peak in peaks: |
---|
856 | if G2frame.qPlot: |
---|
857 | Plot.axvline(4*np.pi*sind(peak[0]/2.0)/wave,color='b') |
---|
858 | else: |
---|
859 | Plot.axvline(peak[0],color='b') |
---|
860 | for hkl in G2frame.HKL: |
---|
861 | if G2frame.qPlot: |
---|
862 | Plot.axvline(4*np.pi*sind(hkl[5]/2.0)/wave,color='r',dashes=(5,5)) |
---|
863 | else: |
---|
864 | Plot.axvline(hkl[5],color='r',dashes=(5,5)) |
---|
865 | elif G2frame.PatternTree.GetItemText(PickId) in ['Reflection Lists'] or \ |
---|
866 | 'PWDR' in G2frame.PatternTree.GetItemText(PickId): |
---|
867 | refColors=['b','r','c','g','m','k'] |
---|
868 | Phases = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists')) |
---|
869 | for pId,phase in enumerate(Phases): |
---|
870 | peaks = Phases[phase] |
---|
871 | if not peaks: |
---|
872 | continue |
---|
873 | peak = np.array([[peak[4],peak[5]] for peak in peaks]) |
---|
874 | pos = G2frame.refOffset-pId*Ymax*G2frame.refDelt*np.ones_like(peak) |
---|
875 | if G2frame.qPlot: |
---|
876 | Plot.plot(2*np.pi/peak.T[0],pos,refColors[pId%6]+'|',mew=1,ms=8,picker=3.,label=phase) |
---|
877 | else: |
---|
878 | Plot.plot(peak.T[1],pos,refColors[pId%6]+'|',mew=1,ms=8,picker=3.,label=phase) |
---|
879 | if len(Phases): |
---|
880 | handles,legends = Plot.get_legend_handles_labels() #got double entries in the legends for some reason |
---|
881 | if handles: |
---|
882 | Plot.legend(handles[::2],legends[::2],title='Phases',loc='best') #skip every other one |
---|
883 | |
---|
884 | if G2frame.Contour: |
---|
885 | acolor = mpl.cm.get_cmap(G2frame.ContourColor) |
---|
886 | Img = Plot.imshow(ContourZ,cmap=acolor,vmin=0,vmax=Ymax*G2frame.Cmax,interpolation=G2frame.Interpolate, |
---|
887 | extent=[ContourX[0],ContourX[-1],ContourY[0],ContourY[-1]],aspect='auto',origin='lower') |
---|
888 | Page.figure.colorbar(Img) |
---|
889 | else: |
---|
890 | G2frame.Lines = Lines |
---|
891 | if not newPlot: |
---|
892 | Page.toolbar.push_current() |
---|
893 | Plot.set_xlim(xylim[0]) |
---|
894 | Plot.set_ylim(xylim[1]) |
---|
895 | xylim = [] |
---|
896 | Page.toolbar.push_current() |
---|
897 | Page.toolbar.draw() |
---|
898 | else: |
---|
899 | Page.canvas.draw() |
---|
900 | # G2frame.Pwdr = True |
---|
901 | |
---|
902 | ################################################################################ |
---|
903 | ##### PlotDeltSig |
---|
904 | ################################################################################ |
---|
905 | |
---|
906 | def PlotDeltSig(G2frame,kind): |
---|
907 | 'needs a doc string' |
---|
908 | try: |
---|
909 | plotNum = G2frame.G2plotNB.plotList.index('Error analysis') |
---|
910 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
911 | Page.figure.clf() |
---|
912 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
913 | except ValueError: |
---|
914 | newPlot = True |
---|
915 | G2frame.Cmax = 1.0 |
---|
916 | Plot = G2frame.G2plotNB.addMpl('Error analysis').gca() |
---|
917 | plotNum = G2frame.G2plotNB.plotList.index('Error analysis') |
---|
918 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
919 | Page.Choice = None |
---|
920 | PatternId = G2frame.PatternId |
---|
921 | Pattern = G2frame.PatternTree.GetItemPyData(PatternId) |
---|
922 | Pattern.append(G2frame.PatternTree.GetItemText(PatternId)) |
---|
923 | wtFactor = Pattern[0]['wtFactor'] |
---|
924 | if kind == 'PWDR': |
---|
925 | limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1] |
---|
926 | xye = np.array(Pattern[1]) |
---|
927 | xmin = np.searchsorted(xye[0],limits[0]) |
---|
928 | xmax = np.searchsorted(xye[0],limits[1]) |
---|
929 | DS = xye[5][xmin:xmax]*np.sqrt(wtFactor*xye[2][xmin:xmax]) |
---|
930 | elif kind == 'HKLF': |
---|
931 | refl = Pattern[1] |
---|
932 | DS = [] |
---|
933 | for ref in refl: |
---|
934 | if ref[6] > 0.: |
---|
935 | DS.append((ref[5]-ref[7])/ref[6]) |
---|
936 | Page.SetFocus() |
---|
937 | G2frame.G2plotNB.status.DestroyChildren() |
---|
938 | DS.sort() |
---|
939 | EDS = np.zeros_like(DS) |
---|
940 | DX = np.linspace(0.,1.,num=len(DS),endpoint=True) |
---|
941 | oldErr = np.seterr(invalid='ignore') #avoid problem at DX==0 |
---|
942 | T = np.sqrt(np.log(1.0/DX**2)) |
---|
943 | top = 2.515517+0.802853*T+0.010328*T**2 |
---|
944 | bot = 1.0+1.432788*T+0.189269*T**2+0.001308*T**3 |
---|
945 | EDS = np.where(DX>0,-(T-top/bot),(T-top/bot)) |
---|
946 | low1 = np.searchsorted(EDS,-1.) |
---|
947 | hi1 = np.searchsorted(EDS,1.) |
---|
948 | slp,intcp = np.polyfit(EDS[low1:hi1],DS[low1:hi1],deg=1) |
---|
949 | frac = 100.*(hi1-low1)/len(DS) |
---|
950 | G2frame.G2plotNB.status.SetStatusText( \ |
---|
951 | 'Over range -1. to 1. :'+' slope = %.3f, intercept = %.3f for %.2f%% of the fitted data'%(slp,intcp,frac),1) |
---|
952 | Plot.set_title('Normal probability for '+Pattern[-1]) |
---|
953 | Plot.set_xlabel(r'expected $\mathsf{\Delta/\sigma}$',fontsize=14) |
---|
954 | Plot.set_ylabel(r'observed $\mathsf{\Delta/\sigma}$',fontsize=14) |
---|
955 | Plot.plot(EDS,DS,'r+',label='result') |
---|
956 | Plot.plot([-2,2],[-2,2],'k',dashes=(5,5),label='ideal') |
---|
957 | Plot.legend(loc='upper left') |
---|
958 | np.seterr(invalid='warn') |
---|
959 | Page.canvas.draw() |
---|
960 | |
---|
961 | ################################################################################ |
---|
962 | ##### PlotISFG |
---|
963 | ################################################################################ |
---|
964 | |
---|
965 | def PlotISFG(G2frame,newPlot=False,type=''): |
---|
966 | ''' PLotting package for PDF analysis; displays I(q), S(q), F(q) and G(r) as single |
---|
967 | or multiple plots with waterfall and contour plots as options |
---|
968 | ''' |
---|
969 | if not type: |
---|
970 | type = G2frame.G2plotNB.plotList[G2frame.G2plotNB.nb.GetSelection()] |
---|
971 | if type not in ['I(Q)','S(Q)','F(Q)','G(R)']: |
---|
972 | return |
---|
973 | superMinusOne = unichr(0xaf)+unichr(0xb9) |
---|
974 | |
---|
975 | def OnPlotKeyPress(event): |
---|
976 | newPlot = False |
---|
977 | if event.key == 'u': |
---|
978 | if G2frame.Contour: |
---|
979 | G2frame.Cmax = min(1.0,G2frame.Cmax*1.2) |
---|
980 | elif G2frame.Offset[0] < 100.: |
---|
981 | G2frame.Offset[0] += 1. |
---|
982 | elif event.key == 'd': |
---|
983 | if G2frame.Contour: |
---|
984 | G2frame.Cmax = max(0.0,G2frame.Cmax*0.8) |
---|
985 | elif G2frame.Offset[0] > 0.: |
---|
986 | G2frame.Offset[0] -= 1. |
---|
987 | elif event.key == 'l': |
---|
988 | G2frame.Offset[1] -= 1. |
---|
989 | elif event.key == 'r': |
---|
990 | G2frame.Offset[1] += 1. |
---|
991 | elif event.key == 'o': |
---|
992 | G2frame.Offset = [0,0] |
---|
993 | elif event.key == 'c': |
---|
994 | newPlot = True |
---|
995 | if G2frame.Contour: |
---|
996 | G2frame.Contour = False |
---|
997 | else: |
---|
998 | G2frame.Contour = True |
---|
999 | G2frame.SinglePlot = False |
---|
1000 | G2frame.Offset = [0.,0.] |
---|
1001 | elif event.key == 's': |
---|
1002 | if G2frame.Contour: |
---|
1003 | choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] |
---|
1004 | choice.sort() |
---|
1005 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice) |
---|
1006 | if dlg.ShowModal() == wx.ID_OK: |
---|
1007 | sel = dlg.GetSelection() |
---|
1008 | G2frame.ContourColor = choice[sel] |
---|
1009 | else: |
---|
1010 | G2frame.ContourColor = 'Paired' |
---|
1011 | dlg.Destroy() |
---|
1012 | else: |
---|
1013 | if G2frame.SinglePlot: |
---|
1014 | G2frame.SinglePlot = False |
---|
1015 | else: |
---|
1016 | G2frame.SinglePlot = True |
---|
1017 | elif event.key == 'i': #for smoothing contour plot |
---|
1018 | choice = ['nearest','bilinear','bicubic','spline16','spline36','hanning', |
---|
1019 | 'hamming','hermite','kaiser','quadric','catrom','gaussian','bessel', |
---|
1020 | 'mitchell','sinc','lanczos'] |
---|
1021 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Interpolation',choice) |
---|
1022 | if dlg.ShowModal() == wx.ID_OK: |
---|
1023 | sel = dlg.GetSelection() |
---|
1024 | G2frame.Interpolate = choice[sel] |
---|
1025 | else: |
---|
1026 | G2frame.Interpolate = 'nearest' |
---|
1027 | dlg.Destroy() |
---|
1028 | elif event.key == 't' and not G2frame.Contour: |
---|
1029 | if G2frame.Legend: |
---|
1030 | G2frame.Legend = False |
---|
1031 | else: |
---|
1032 | G2frame.Legend = True |
---|
1033 | PlotISFG(G2frame,newPlot=newPlot,type=type) |
---|
1034 | |
---|
1035 | def OnKeyBox(event): |
---|
1036 | if G2frame.G2plotNB.nb.GetSelection() == G2frame.G2plotNB.plotList.index(type): |
---|
1037 | event.key = cb.GetValue()[0] |
---|
1038 | cb.SetValue(' key press') |
---|
1039 | wx.CallAfter(OnPlotKeyPress,event) |
---|
1040 | Page.canvas.SetFocus() # redirect the Focus from the button back to the plot |
---|
1041 | |
---|
1042 | def OnMotion(event): |
---|
1043 | xpos = event.xdata |
---|
1044 | if xpos: #avoid out of frame mouse position |
---|
1045 | ypos = event.ydata |
---|
1046 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
1047 | try: |
---|
1048 | if G2frame.Contour: |
---|
1049 | G2frame.G2plotNB.status.SetStatusText('R =%.3fA pattern ID =%5d'%(xpos,int(ypos)),1) |
---|
1050 | else: |
---|
1051 | G2frame.G2plotNB.status.SetStatusText('R =%.3fA %s =%.2f'%(xpos,type,ypos),1) |
---|
1052 | except TypeError: |
---|
1053 | G2frame.G2plotNB.status.SetStatusText('Select '+type+' pattern first',1) |
---|
1054 | |
---|
1055 | xylim = [] |
---|
1056 | try: |
---|
1057 | plotNum = G2frame.G2plotNB.plotList.index(type) |
---|
1058 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1059 | if not newPlot: |
---|
1060 | Plot = Page.figure.gca() #get previous plot & get limits |
---|
1061 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
1062 | Page.figure.clf() |
---|
1063 | Plot = Page.figure.gca() |
---|
1064 | except ValueError: |
---|
1065 | newPlot = True |
---|
1066 | G2frame.Cmax = 1.0 |
---|
1067 | Plot = G2frame.G2plotNB.addMpl(type).gca() |
---|
1068 | plotNum = G2frame.G2plotNB.plotList.index(type) |
---|
1069 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1070 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
1071 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
1072 | |
---|
1073 | Page.SetFocus() |
---|
1074 | G2frame.G2plotNB.status.DestroyChildren() |
---|
1075 | if G2frame.Contour: |
---|
1076 | Page.Choice = (' key press','d: lower contour max','u: raise contour max', |
---|
1077 | 'i: interpolation method','s: color scheme','c: contour off') |
---|
1078 | else: |
---|
1079 | Page.Choice = (' key press','l: offset left','r: offset right','d: offset down','u: offset up', |
---|
1080 | 'o: reset offset','t: toggle legend','c: contour on','s: toggle single plot') |
---|
1081 | Page.keyPress = OnPlotKeyPress |
---|
1082 | PatternId = G2frame.PatternId |
---|
1083 | PickId = G2frame.PickId |
---|
1084 | Plot.set_title(type) |
---|
1085 | if type == 'G(R)': |
---|
1086 | Plot.set_xlabel(r'$R,\AA$',fontsize=14) |
---|
1087 | else: |
---|
1088 | Plot.set_xlabel(r'$Q,\AA$'+superMinusOne,fontsize=14) |
---|
1089 | Plot.set_ylabel(r''+type,fontsize=14) |
---|
1090 | colors=['b','g','r','c','m','k'] |
---|
1091 | name = G2frame.PatternTree.GetItemText(PatternId)[4:] |
---|
1092 | Pattern = [] |
---|
1093 | if G2frame.SinglePlot: |
---|
1094 | name = G2frame.PatternTree.GetItemText(PatternId) |
---|
1095 | name = type+name[4:] |
---|
1096 | Id = G2gd.GetPatternTreeItemId(G2frame,PatternId,name) |
---|
1097 | Pattern = G2frame.PatternTree.GetItemPyData(Id) |
---|
1098 | if Pattern: |
---|
1099 | Pattern.append(name) |
---|
1100 | PlotList = [Pattern,] |
---|
1101 | else: |
---|
1102 | PlotList = [] |
---|
1103 | item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root) |
---|
1104 | while item: |
---|
1105 | if 'PDF' in G2frame.PatternTree.GetItemText(item): |
---|
1106 | name = type+G2frame.PatternTree.GetItemText(item)[4:] |
---|
1107 | Id = G2gd.GetPatternTreeItemId(G2frame,item,name) |
---|
1108 | Pattern = G2frame.PatternTree.GetItemPyData(Id) |
---|
1109 | if Pattern: |
---|
1110 | Pattern.append(name) |
---|
1111 | PlotList.append(Pattern) |
---|
1112 | item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie) |
---|
1113 | PDFdata = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'PDF Controls')) |
---|
1114 | numbDen = G2pwd.GetNumDensity(PDFdata['ElList'],PDFdata['Form Vol']) |
---|
1115 | Xb = [0.,10.] |
---|
1116 | Yb = [0.,-40.*np.pi*numbDen] |
---|
1117 | Ymax = 1.0 |
---|
1118 | lenX = 0 |
---|
1119 | for Pattern in PlotList: |
---|
1120 | xye = Pattern[1] |
---|
1121 | Ymax = max(Ymax,max(xye[1])) |
---|
1122 | offset = G2frame.Offset[0]*Ymax/100.0 |
---|
1123 | if G2frame.Contour: |
---|
1124 | ContourZ = [] |
---|
1125 | ContourY = [] |
---|
1126 | Nseq = 0 |
---|
1127 | for N,Pattern in enumerate(PlotList): |
---|
1128 | xye = Pattern[1] |
---|
1129 | if PickId: |
---|
1130 | ifpicked = Pattern[2] == G2frame.PatternTree.GetItemText(PatternId) |
---|
1131 | X = xye[0] |
---|
1132 | if not lenX: |
---|
1133 | lenX = len(X) |
---|
1134 | Y = xye[1]+offset*N |
---|
1135 | if G2frame.Contour: |
---|
1136 | if lenX == len(X): |
---|
1137 | ContourY.append(N) |
---|
1138 | ContourZ.append(Y) |
---|
1139 | ContourX = X |
---|
1140 | Nseq += 1 |
---|
1141 | Plot.set_ylabel('Data sequence',fontsize=12) |
---|
1142 | else: |
---|
1143 | X = xye[0]+G2frame.Offset[1]*.005*N |
---|
1144 | if ifpicked: |
---|
1145 | Plot.plot(X,Y,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
1146 | Page.canvas.SetToolTipString('') |
---|
1147 | else: |
---|
1148 | if G2frame.Legend: |
---|
1149 | Plot.plot(X,Y,colors[N%6],picker=False,label='Azm:'+Pattern[2].split('=')[1]) |
---|
1150 | else: |
---|
1151 | Plot.plot(X,Y,colors[N%6],picker=False) |
---|
1152 | if type == 'G(R)': |
---|
1153 | Plot.plot(Xb,Yb,color='k',dashes=(5,5)) |
---|
1154 | elif type == 'F(Q)': |
---|
1155 | Plot.axhline(0.,color=wx.BLACK) |
---|
1156 | elif type == 'S(Q)': |
---|
1157 | Plot.axhline(1.,color=wx.BLACK) |
---|
1158 | if G2frame.Contour: |
---|
1159 | acolor = mpl.cm.get_cmap(G2frame.ContourColor) |
---|
1160 | Img = Plot.imshow(ContourZ,cmap=acolor,vmin=0,vmax=Ymax*G2frame.Cmax,interpolation=G2frame.Interpolate, |
---|
1161 | extent=[ContourX[0],ContourX[-1],ContourY[0],ContourY[-1]],aspect='auto',origin='lower') |
---|
1162 | Page.figure.colorbar(Img) |
---|
1163 | elif G2frame.Legend: |
---|
1164 | Plot.legend(loc='best') |
---|
1165 | if not newPlot: |
---|
1166 | Page.toolbar.push_current() |
---|
1167 | Plot.set_xlim(xylim[0]) |
---|
1168 | Plot.set_ylim(xylim[1]) |
---|
1169 | xylim = [] |
---|
1170 | Page.toolbar.push_current() |
---|
1171 | Page.toolbar.draw() |
---|
1172 | else: |
---|
1173 | Page.canvas.draw() |
---|
1174 | |
---|
1175 | ################################################################################ |
---|
1176 | ##### PlotXY |
---|
1177 | ################################################################################ |
---|
1178 | |
---|
1179 | def PlotXY(G2frame,XY,newPlot=False,type=''): |
---|
1180 | '''simple plot of xy data, used for diagnostic purposes |
---|
1181 | ''' |
---|
1182 | def OnMotion(event): |
---|
1183 | xpos = event.xdata |
---|
1184 | if xpos: #avoid out of frame mouse position |
---|
1185 | ypos = event.ydata |
---|
1186 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
1187 | try: |
---|
1188 | G2frame.G2plotNB.status.SetStatusText('X =%9.3f %s =%9.3f'%(xpos,type,ypos),1) |
---|
1189 | except TypeError: |
---|
1190 | G2frame.G2plotNB.status.SetStatusText('Select '+type+' pattern first',1) |
---|
1191 | |
---|
1192 | try: |
---|
1193 | plotNum = G2frame.G2plotNB.plotList.index(type) |
---|
1194 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1195 | if not newPlot: |
---|
1196 | Plot = Page.figure.gca() |
---|
1197 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
1198 | Page.figure.clf() |
---|
1199 | Plot = Page.figure.gca() |
---|
1200 | except ValueError: |
---|
1201 | newPlot = True |
---|
1202 | Plot = G2frame.G2plotNB.addMpl(type).gca() |
---|
1203 | plotNum = G2frame.G2plotNB.plotList.index(type) |
---|
1204 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1205 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
1206 | |
---|
1207 | Page.Choice = None |
---|
1208 | Page.SetFocus() |
---|
1209 | G2frame.G2plotNB.status.DestroyChildren() |
---|
1210 | Plot.set_title(type) |
---|
1211 | Plot.set_xlabel(r'X',fontsize=14) |
---|
1212 | Plot.set_ylabel(r''+type,fontsize=14) |
---|
1213 | colors=['b','g','r','c','m','k'] |
---|
1214 | Ymax = 1.0 |
---|
1215 | lenX = 0 |
---|
1216 | X,Y = XY[:2] |
---|
1217 | Ymax = max(Ymax,max(Y)) |
---|
1218 | Plot.plot(X,Y,'k',picker=False) |
---|
1219 | if not newPlot: |
---|
1220 | Page.toolbar.push_current() |
---|
1221 | Plot.set_xlim(xylim[0]) |
---|
1222 | Plot.set_ylim(xylim[1]) |
---|
1223 | xylim = [] |
---|
1224 | Page.toolbar.push_current() |
---|
1225 | Page.toolbar.draw() |
---|
1226 | else: |
---|
1227 | Page.canvas.draw() |
---|
1228 | |
---|
1229 | ################################################################################ |
---|
1230 | ##### PlotPowderLines |
---|
1231 | ################################################################################ |
---|
1232 | |
---|
1233 | def PlotPowderLines(G2frame): |
---|
1234 | ''' plotting of powder lines (i.e. no powder pattern) as sticks |
---|
1235 | ''' |
---|
1236 | global HKL |
---|
1237 | |
---|
1238 | def OnMotion(event): |
---|
1239 | xpos = event.xdata |
---|
1240 | if xpos: #avoid out of frame mouse position |
---|
1241 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
1242 | G2frame.G2plotNB.status.SetFields(['','2-theta =%9.3f '%(xpos,)]) |
---|
1243 | if G2frame.PickId and G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Index Peak List','Unit Cells List']: |
---|
1244 | found = [] |
---|
1245 | if len(HKL): |
---|
1246 | view = Page.toolbar._views.forward()[0][:2] |
---|
1247 | wid = view[1]-view[0] |
---|
1248 | found = HKL[np.where(np.fabs(HKL.T[5]-xpos) < 0.002*wid)] |
---|
1249 | if len(found): |
---|
1250 | h,k,l = found[0][:3] |
---|
1251 | Page.canvas.SetToolTipString('%d,%d,%d'%(int(h),int(k),int(l))) |
---|
1252 | else: |
---|
1253 | Page.canvas.SetToolTipString('') |
---|
1254 | |
---|
1255 | try: |
---|
1256 | plotNum = G2frame.G2plotNB.plotList.index('Powder Lines') |
---|
1257 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1258 | Page.figure.clf() |
---|
1259 | Plot = Page.figure.gca() |
---|
1260 | except ValueError: |
---|
1261 | Plot = G2frame.G2plotNB.addMpl('Powder Lines').gca() |
---|
1262 | plotNum = G2frame.G2plotNB.plotList.index('Powder Lines') |
---|
1263 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1264 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
1265 | |
---|
1266 | Page.Choice = None |
---|
1267 | Page.SetFocus() |
---|
1268 | Plot.set_title('Powder Pattern Lines') |
---|
1269 | Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14) |
---|
1270 | PickId = G2frame.PickId |
---|
1271 | PatternId = G2frame.PatternId |
---|
1272 | peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List')) |
---|
1273 | for peak in peaks: |
---|
1274 | Plot.axvline(peak[0],color='b') |
---|
1275 | HKL = np.array(G2frame.HKL) |
---|
1276 | for hkl in G2frame.HKL: |
---|
1277 | Plot.axvline(hkl[5],color='r',dashes=(5,5)) |
---|
1278 | xmin = peaks[0][0] |
---|
1279 | xmax = peaks[-1][0] |
---|
1280 | delt = xmax-xmin |
---|
1281 | xlim = [max(0,xmin-delt/20.),min(180.,xmax+delt/20.)] |
---|
1282 | Plot.set_xlim(xlim) |
---|
1283 | Page.canvas.draw() |
---|
1284 | Page.toolbar.push_current() |
---|
1285 | |
---|
1286 | ################################################################################ |
---|
1287 | ##### PlotPeakWidths |
---|
1288 | ################################################################################ |
---|
1289 | |
---|
1290 | def PlotPeakWidths(G2frame): |
---|
1291 | ''' Plotting of instrument broadening terms as function of 2-theta |
---|
1292 | Seen when "Instrument Parameters" chosen from powder pattern data tree |
---|
1293 | ''' |
---|
1294 | # sig = lambda Th,U,V,W: 1.17741*math.sqrt(U*tand(Th)**2+V*tand(Th)+W)*math.pi/18000. |
---|
1295 | # gam = lambda Th,X,Y: (X/cosd(Th)+Y*tand(Th))*math.pi/18000. |
---|
1296 | gamFW = lambda s,g: np.exp(np.log(s**5+2.69269*s**4*g+2.42843*s**3*g**2+4.47163*s**2*g**3+0.07842*s*g**4+g**5)/5.) |
---|
1297 | # gamFW2 = lambda s,g: math.sqrt(s**2+(0.4654996*g)**2)+.5345004*g #Ubaldo Bafile - private communication |
---|
1298 | PatternId = G2frame.PatternId |
---|
1299 | limitID = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits') |
---|
1300 | if limitID: |
---|
1301 | limits = G2frame.PatternTree.GetItemPyData(limitID)[:2] |
---|
1302 | else: |
---|
1303 | return |
---|
1304 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData( \ |
---|
1305 | G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters')) |
---|
1306 | if 'C' in Parms['Type'][0]: |
---|
1307 | lam = G2mth.getWave(Parms) |
---|
1308 | else: |
---|
1309 | difC = Parms['difC'][0] |
---|
1310 | peakID = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List') |
---|
1311 | if peakID: |
---|
1312 | peaks = G2frame.PatternTree.GetItemPyData(peakID) |
---|
1313 | else: |
---|
1314 | peaks = [] |
---|
1315 | |
---|
1316 | try: |
---|
1317 | plotNum = G2frame.G2plotNB.plotList.index('Peak Widths') |
---|
1318 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1319 | Page.figure.clf() |
---|
1320 | Plot = Page.figure.gca() |
---|
1321 | except ValueError: |
---|
1322 | Plot = G2frame.G2plotNB.addMpl('Peak Widths').gca() |
---|
1323 | plotNum = G2frame.G2plotNB.plotList.index('Peak Widths') |
---|
1324 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1325 | Page.Choice = None |
---|
1326 | Page.SetFocus() |
---|
1327 | |
---|
1328 | Page.canvas.SetToolTipString('') |
---|
1329 | colors=['b','g','r','c','m','k'] |
---|
1330 | X = [] |
---|
1331 | Y = [] |
---|
1332 | Z = [] |
---|
1333 | W = [] |
---|
1334 | if 'C' in Parms['Type'][0]: |
---|
1335 | Plot.set_title('Instrument and sample peak widths') |
---|
1336 | Plot.set_xlabel(r'$Q, \AA^{-1}$',fontsize=14) |
---|
1337 | Plot.set_ylabel(r'$\Delta Q/Q, \Delta d/d$',fontsize=14) |
---|
1338 | try: |
---|
1339 | Xmin,Xmax = limits[1] |
---|
1340 | X = np.linspace(Xmin,Xmax,num=101,endpoint=True) |
---|
1341 | Q = 4.*np.pi*npsind(X/2.)/lam |
---|
1342 | Z = np.ones_like(X) |
---|
1343 | data = G2mth.setPeakparms(Parms,Parms2,X,Z) |
---|
1344 | s = 1.17741*np.sqrt(data[4])*np.pi/18000. |
---|
1345 | g = data[6]*np.pi/18000. |
---|
1346 | G = G2pwd.getgamFW(g,s) |
---|
1347 | Y = s/nptand(X/2.) |
---|
1348 | Z = g/nptand(X/2.) |
---|
1349 | W = G/nptand(X/2.) |
---|
1350 | Plot.plot(Q,Y,color='r',label='Gaussian') |
---|
1351 | Plot.plot(Q,Z,color='g',label='Lorentzian') |
---|
1352 | Plot.plot(Q,W,color='b',label='G+L') |
---|
1353 | |
---|
1354 | fit = G2mth.setPeakparms(Parms,Parms2,X,Z,useFit=True) |
---|
1355 | sf = 1.17741*np.sqrt(fit[4])*np.pi/18000. |
---|
1356 | gf = fit[6]*np.pi/18000. |
---|
1357 | Gf = G2pwd.getgamFW(gf,sf) |
---|
1358 | Yf = sf/nptand(X/2.) |
---|
1359 | Zf = gf/nptand(X/2.) |
---|
1360 | Wf = Gf/nptand(X/2.) |
---|
1361 | Plot.plot(Q,Yf,color='r',dashes=(5,5),label='Gaussian fit') |
---|
1362 | Plot.plot(Q,Zf,color='g',dashes=(5,5),label='Lorentzian fit') |
---|
1363 | Plot.plot(Q,Wf,color='b',dashes=(5,5),label='G+L fit') |
---|
1364 | |
---|
1365 | X = [] |
---|
1366 | Y = [] |
---|
1367 | Z = [] |
---|
1368 | W = [] |
---|
1369 | V = [] |
---|
1370 | for peak in peaks: |
---|
1371 | X.append(4.0*math.pi*sind(peak[0]/2.0)/lam) |
---|
1372 | try: |
---|
1373 | s = 1.17741*math.sqrt(peak[4])*math.pi/18000. |
---|
1374 | except ValueError: |
---|
1375 | s = 0.01 |
---|
1376 | g = peak[6]*math.pi/18000. |
---|
1377 | G = G2pwd.getgamFW(g,s) |
---|
1378 | Y.append(s/tand(peak[0]/2.)) |
---|
1379 | Z.append(g/tand(peak[0]/2.)) |
---|
1380 | W.append(G/tand(peak[0]/2.)) |
---|
1381 | if len(peaks): |
---|
1382 | Plot.plot(X,Y,'+',color='r',label='G peak') |
---|
1383 | Plot.plot(X,Z,'+',color='g',label='L peak') |
---|
1384 | Plot.plot(X,W,'+',color='b',label='G+L peak') |
---|
1385 | Plot.legend(loc='best') |
---|
1386 | Page.canvas.draw() |
---|
1387 | except ValueError: |
---|
1388 | print '**** ERROR - default U,V,W profile coefficients yield sqrt of negative value at 2theta =', \ |
---|
1389 | '%.3f'%(2*theta) |
---|
1390 | G2frame.G2plotNB.Delete('Peak Widths') |
---|
1391 | else: |
---|
1392 | Plot.set_title('Instrument and sample peak coefficients') |
---|
1393 | Plot.set_xlabel(r'$Q, \AA^{-1}$',fontsize=14) |
---|
1394 | Plot.set_ylabel(r'$\alpha, \beta, \Delta Q/Q, \Delta d/d$',fontsize=14) |
---|
1395 | Xmin,Xmax = limits[1] |
---|
1396 | T = np.linspace(Xmin,Xmax,num=101,endpoint=True) |
---|
1397 | Z = np.ones_like(T) |
---|
1398 | data = G2mth.setPeakparms(Parms,Parms2,T,Z) |
---|
1399 | ds = T/difC |
---|
1400 | Q = 2.*np.pi/ds |
---|
1401 | A = data[4] |
---|
1402 | B = data[6] |
---|
1403 | S = 1.17741*np.sqrt(data[8])/T |
---|
1404 | G = data[10]/T |
---|
1405 | Plot.plot(Q,A,color='r',label='Alpha') |
---|
1406 | Plot.plot(Q,B,color='g',label='Beta') |
---|
1407 | Plot.plot(Q,S,color='b',label='Gaussian') |
---|
1408 | Plot.plot(Q,G,color='m',label='Lorentzian') |
---|
1409 | |
---|
1410 | fit = G2mth.setPeakparms(Parms,Parms2,T,Z) |
---|
1411 | ds = T/difC |
---|
1412 | Q = 2.*np.pi/ds |
---|
1413 | Af = fit[4] |
---|
1414 | Bf = fit[6] |
---|
1415 | Sf = 1.17741*np.sqrt(fit[8])/T |
---|
1416 | Gf = fit[10]/T |
---|
1417 | Plot.plot(Q,Af,color='r',dashes=(5,5),label='Alpha fit') |
---|
1418 | Plot.plot(Q,Bf,color='g',dashes=(5,5),label='Beta fit') |
---|
1419 | Plot.plot(Q,Sf,color='b',dashes=(5,5),label='Gaussian fit') |
---|
1420 | Plot.plot(Q,Gf,color='m',dashes=(5,5),label='Lorentzian fit') |
---|
1421 | |
---|
1422 | T = [] |
---|
1423 | A = [] |
---|
1424 | B = [] |
---|
1425 | S = [] |
---|
1426 | G = [] |
---|
1427 | W = [] |
---|
1428 | Q = [] |
---|
1429 | V = [] |
---|
1430 | for peak in peaks: |
---|
1431 | T.append(peak[0]) |
---|
1432 | A.append(peak[4]) |
---|
1433 | B.append(peak[6]) |
---|
1434 | Q.append(2.*np.pi*difC/peak[0]) |
---|
1435 | S.append(1.17741*np.sqrt(peak[8])/peak[0]) |
---|
1436 | G.append(peak[10]/peak[0]) |
---|
1437 | |
---|
1438 | |
---|
1439 | Plot.plot(Q,A,'+',color='r',label='Alpha peak') |
---|
1440 | Plot.plot(Q,B,'+',color='g',label='Beta peak') |
---|
1441 | Plot.plot(Q,S,'+',color='b',label='Gaussian peak') |
---|
1442 | Plot.plot(Q,G,'+',color='m',label='Lorentzian peak') |
---|
1443 | Plot.legend(loc='best') |
---|
1444 | Page.canvas.draw() |
---|
1445 | |
---|
1446 | |
---|
1447 | ################################################################################ |
---|
1448 | ##### PlotSizeStrainPO |
---|
1449 | ################################################################################ |
---|
1450 | |
---|
1451 | def PlotSizeStrainPO(G2frame,data,Start=False): |
---|
1452 | '''Plot 3D mustrain/size/preferred orientation figure. In this instance data is for a phase |
---|
1453 | ''' |
---|
1454 | |
---|
1455 | PatternId = G2frame.PatternId |
---|
1456 | generalData = data['General'] |
---|
1457 | SGData = generalData['SGData'] |
---|
1458 | SGLaue = SGData['SGLaue'] |
---|
1459 | if Start: #initialize the spherical harmonics qlmn arrays |
---|
1460 | ptx.pyqlmninit() |
---|
1461 | Start = False |
---|
1462 | # MuStrKeys = G2spc.MustrainNames(SGData) |
---|
1463 | cell = generalData['Cell'][1:] |
---|
1464 | A,B = G2lat.cell2AB(cell[:6]) |
---|
1465 | Vol = cell[6] |
---|
1466 | useList = data['Histograms'] |
---|
1467 | phase = generalData['Name'] |
---|
1468 | plotType = generalData['Data plot type'] |
---|
1469 | plotDict = {'Mustrain':'Mustrain','Size':'Size','Preferred orientation':'Pref.Ori.'} |
---|
1470 | for ptype in plotDict: |
---|
1471 | G2frame.G2plotNB.Delete(ptype) |
---|
1472 | if plotType in ['None']: |
---|
1473 | return |
---|
1474 | |
---|
1475 | for item in useList: |
---|
1476 | if useList[item]['Show']: |
---|
1477 | break |
---|
1478 | else: |
---|
1479 | return #nothing to show!! |
---|
1480 | |
---|
1481 | numPlots = len(useList) |
---|
1482 | |
---|
1483 | if plotType in ['Mustrain','Size']: |
---|
1484 | Plot = mp3d.Axes3D(G2frame.G2plotNB.add3D(plotType)) |
---|
1485 | else: |
---|
1486 | Plot = G2frame.G2plotNB.addMpl(plotType).gca() |
---|
1487 | plotNum = G2frame.G2plotNB.plotList.index(plotType) |
---|
1488 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1489 | Page.Choice = None |
---|
1490 | Page.SetFocus() |
---|
1491 | G2frame.G2plotNB.status.SetStatusText('',1) |
---|
1492 | if not Page.IsShown(): |
---|
1493 | Page.Show() |
---|
1494 | |
---|
1495 | for item in useList: |
---|
1496 | if useList[item]['Show']: |
---|
1497 | PHI = np.linspace(0.,360.,30,True) |
---|
1498 | PSI = np.linspace(0.,180.,30,True) |
---|
1499 | X = np.outer(npsind(PHI),npsind(PSI)) |
---|
1500 | Y = np.outer(npcosd(PHI),npsind(PSI)) |
---|
1501 | Z = np.outer(np.ones(np.size(PHI)),npcosd(PSI)) |
---|
1502 | try: #temp patch instead of 'mustrain' for old files with 'microstrain' |
---|
1503 | coeff = useList[item][plotDict[plotType]] |
---|
1504 | except KeyError: |
---|
1505 | break |
---|
1506 | if plotType in ['Mustrain','Size']: |
---|
1507 | if coeff[0] == 'isotropic': |
---|
1508 | X *= coeff[1][0] |
---|
1509 | Y *= coeff[1][0] |
---|
1510 | Z *= coeff[1][0] |
---|
1511 | elif coeff[0] == 'uniaxial': |
---|
1512 | |
---|
1513 | def uniaxCalc(xyz,iso,aniso,axes): |
---|
1514 | Z = np.array(axes) |
---|
1515 | cp = abs(np.dot(xyz,Z)) |
---|
1516 | sp = np.sqrt(1.-cp**2) |
---|
1517 | R = iso*aniso/np.sqrt((iso*cp)**2+(aniso*sp)**2) |
---|
1518 | return R*xyz |
---|
1519 | |
---|
1520 | iso,aniso = coeff[1][:2] |
---|
1521 | axes = np.inner(A,np.array(coeff[3])) |
---|
1522 | axes /= nl.norm(axes) |
---|
1523 | Shkl = np.array(coeff[1]) |
---|
1524 | XYZ = np.dstack((X,Y,Z)) |
---|
1525 | XYZ = np.nan_to_num(np.apply_along_axis(uniaxCalc,2,XYZ,iso,aniso,axes)) |
---|
1526 | X,Y,Z = np.dsplit(XYZ,3) |
---|
1527 | X = X[:,:,0] |
---|
1528 | Y = Y[:,:,0] |
---|
1529 | Z = Z[:,:,0] |
---|
1530 | |
---|
1531 | elif coeff[0] == 'ellipsoidal': |
---|
1532 | |
---|
1533 | def ellipseCalc(xyz,E,R): |
---|
1534 | XYZ = xyz*E.T |
---|
1535 | return np.inner(XYZ.T,R) |
---|
1536 | |
---|
1537 | S6 = coeff[4] |
---|
1538 | Sij = G2lat.U6toUij(S6) |
---|
1539 | E,R = nl.eigh(Sij) |
---|
1540 | XYZ = np.dstack((X,Y,Z)) |
---|
1541 | XYZ = np.nan_to_num(np.apply_along_axis(ellipseCalc,2,XYZ,E,R)) |
---|
1542 | X,Y,Z = np.dsplit(XYZ,3) |
---|
1543 | X = X[:,:,0] |
---|
1544 | Y = Y[:,:,0] |
---|
1545 | Z = Z[:,:,0] |
---|
1546 | |
---|
1547 | elif coeff[0] == 'generalized': |
---|
1548 | |
---|
1549 | def genMustrain(xyz,SGData,A,Shkl): |
---|
1550 | uvw = np.inner(A.T,xyz) |
---|
1551 | Strm = np.array(G2spc.MustrainCoeff(uvw,SGData)) |
---|
1552 | sum = np.sum(np.multiply(Shkl,Strm)) |
---|
1553 | sum = np.where(sum > 0.01,sum,0.01) |
---|
1554 | sum = np.sqrt(sum)*math.pi/.18 #centidegrees to radians! |
---|
1555 | return sum*xyz |
---|
1556 | |
---|
1557 | Shkl = np.array(coeff[4]) |
---|
1558 | if np.any(Shkl): |
---|
1559 | XYZ = np.dstack((X,Y,Z)) |
---|
1560 | XYZ = np.nan_to_num(np.apply_along_axis(genMustrain,2,XYZ,SGData,A,Shkl)) |
---|
1561 | X,Y,Z = np.dsplit(XYZ,3) |
---|
1562 | X = X[:,:,0] |
---|
1563 | Y = Y[:,:,0] |
---|
1564 | Z = Z[:,:,0] |
---|
1565 | |
---|
1566 | if np.any(X) and np.any(Y) and np.any(Z): |
---|
1567 | errFlags = np.seterr(all='ignore') |
---|
1568 | Plot.plot_surface(X,Y,Z,rstride=1,cstride=1,color='g',linewidth=1) |
---|
1569 | np.seterr(all='ignore') |
---|
1570 | xyzlim = np.array([Plot.get_xlim3d(),Plot.get_ylim3d(),Plot.get_zlim3d()]).T |
---|
1571 | XYZlim = [min(xyzlim[0]),max(xyzlim[1])] |
---|
1572 | Plot.set_xlim3d(XYZlim) |
---|
1573 | Plot.set_ylim3d(XYZlim) |
---|
1574 | Plot.set_zlim3d(XYZlim) |
---|
1575 | Plot.set_aspect('equal') |
---|
1576 | if plotType == 'Size': |
---|
1577 | Plot.set_title('Crystallite size for '+phase+'\n'+coeff[0]+' model') |
---|
1578 | Plot.set_xlabel(r'X, $\mu$m') |
---|
1579 | Plot.set_ylabel(r'Y, $\mu$m') |
---|
1580 | Plot.set_zlabel(r'Z, $\mu$m') |
---|
1581 | else: |
---|
1582 | Plot.set_title(r'$\mu$strain for '+phase+'\n'+coeff[0]+' model') |
---|
1583 | Plot.set_xlabel(r'X, $\mu$strain') |
---|
1584 | Plot.set_ylabel(r'Y, $\mu$strain') |
---|
1585 | Plot.set_zlabel(r'Z, $\mu$strain') |
---|
1586 | else: |
---|
1587 | h,k,l = generalData['POhkl'] |
---|
1588 | if coeff[0] == 'MD': |
---|
1589 | print 'March-Dollase preferred orientation plot' |
---|
1590 | |
---|
1591 | else: |
---|
1592 | PH = np.array(generalData['POhkl']) |
---|
1593 | phi,beta = G2lat.CrsAng(PH,cell[:6],SGData) |
---|
1594 | SHCoef = {} |
---|
1595 | for item in coeff[5]: |
---|
1596 | L,N = eval(item.strip('C')) |
---|
1597 | SHCoef['C%d,0,%d'%(L,N)] = coeff[5][item] |
---|
1598 | ODFln = G2lat.Flnh(Start,SHCoef,phi,beta,SGData) |
---|
1599 | X = np.linspace(0,90.0,26) |
---|
1600 | Y = G2lat.polfcal(ODFln,'0',X,0.0) |
---|
1601 | Plot.plot(X,Y,color='k',label=str(PH)) |
---|
1602 | Plot.legend(loc='best') |
---|
1603 | Plot.set_title('Axial distribution for HKL='+str(PH)+' in '+phase) |
---|
1604 | Plot.set_xlabel(r'$\psi$',fontsize=16) |
---|
1605 | Plot.set_ylabel('MRD',fontsize=14) |
---|
1606 | Page.canvas.draw() |
---|
1607 | |
---|
1608 | ################################################################################ |
---|
1609 | ##### PlotTexture |
---|
1610 | ################################################################################ |
---|
1611 | |
---|
1612 | def PlotTexture(G2frame,data,Start=False): |
---|
1613 | '''Pole figure, inverse pole figure, 3D pole distribution and 3D inverse pole distribution |
---|
1614 | plotting. |
---|
1615 | dict generalData contains all phase info needed which is in data |
---|
1616 | ''' |
---|
1617 | |
---|
1618 | shModels = ['cylindrical','none','shear - 2/m','rolling - mmm'] |
---|
1619 | SamSym = dict(zip(shModels,['0','-1','2/m','mmm'])) |
---|
1620 | PatternId = G2frame.PatternId |
---|
1621 | generalData = data['General'] |
---|
1622 | SGData = generalData['SGData'] |
---|
1623 | textureData = generalData['SH Texture'] |
---|
1624 | G2frame.G2plotNB.Delete('Texture') |
---|
1625 | if not textureData['Order']: |
---|
1626 | return #no plot!! |
---|
1627 | SHData = generalData['SH Texture'] |
---|
1628 | SHCoef = SHData['SH Coeff'][1] |
---|
1629 | cell = generalData['Cell'][1:7] |
---|
1630 | Amat,Bmat = G2lat.cell2AB(cell) |
---|
1631 | sq2 = 1.0/math.sqrt(2.0) |
---|
1632 | |
---|
1633 | def rp2xyz(r,p): |
---|
1634 | z = npcosd(r) |
---|
1635 | xy = np.sqrt(1.-z**2) |
---|
1636 | return xy*npsind(p),xy*npcosd(p),z |
---|
1637 | |
---|
1638 | def OnMotion(event): |
---|
1639 | SHData = data['General']['SH Texture'] |
---|
1640 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
1641 | xpos = event.xdata |
---|
1642 | ypos = event.ydata |
---|
1643 | if 'Inverse' in SHData['PlotType']: |
---|
1644 | r = xpos**2+ypos**2 |
---|
1645 | if r <= 1.0: |
---|
1646 | if 'equal' in G2frame.Projection: |
---|
1647 | r,p = 2.*npasind(np.sqrt(r)*sq2),npatan2d(ypos,xpos) |
---|
1648 | else: |
---|
1649 | r,p = 2.*npatand(np.sqrt(r)),npatan2d(ypos,xpos) |
---|
1650 | ipf = G2lat.invpolfcal(IODFln,SGData,np.array([r,]),np.array([p,])) |
---|
1651 | xyz = np.inner(Amat.T,np.array([rp2xyz(r,p)])) |
---|
1652 | y,x,z = list(xyz/np.max(np.abs(xyz))) |
---|
1653 | |
---|
1654 | G2frame.G2plotNB.status.SetFields(['', |
---|
1655 | 'psi =%9.3f, beta =%9.3f, MRD =%9.3f hkl=%5.2f,%5.2f,%5.2f'%(r,p,ipf,x,y,z)]) |
---|
1656 | |
---|
1657 | elif 'Axial' in SHData['PlotType']: |
---|
1658 | pass |
---|
1659 | |
---|
1660 | else: #ordinary pole figure |
---|
1661 | z = xpos**2+ypos**2 |
---|
1662 | if z <= 1.0: |
---|
1663 | z = np.sqrt(z) |
---|
1664 | if 'equal' in G2frame.Projection: |
---|
1665 | r,p = 2.*npasind(z*sq2),npatan2d(ypos,xpos) |
---|
1666 | else: |
---|
1667 | r,p = 2.*npatand(z),npatan2d(ypos,xpos) |
---|
1668 | pf = G2lat.polfcal(ODFln,SamSym[textureData['Model']],np.array([r,]),np.array([p,])) |
---|
1669 | G2frame.G2plotNB.status.SetFields(['','phi =%9.3f, gam =%9.3f, MRD =%9.3f'%(r,p,pf)]) |
---|
1670 | |
---|
1671 | try: |
---|
1672 | plotNum = G2frame.G2plotNB.plotList.index('Texture') |
---|
1673 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1674 | Page.figure.clf() |
---|
1675 | Plot = Page.figure.gca() |
---|
1676 | if not Page.IsShown(): |
---|
1677 | Page.Show() |
---|
1678 | except ValueError: |
---|
1679 | Plot = G2frame.G2plotNB.addMpl('Texture').gca() |
---|
1680 | plotNum = G2frame.G2plotNB.plotList.index('Texture') |
---|
1681 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1682 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
1683 | |
---|
1684 | Page.Choice = None |
---|
1685 | Page.SetFocus() |
---|
1686 | G2frame.G2plotNB.status.SetFields(['','']) |
---|
1687 | PH = np.array(SHData['PFhkl']) |
---|
1688 | phi,beta = G2lat.CrsAng(PH,cell,SGData) |
---|
1689 | ODFln = G2lat.Flnh(Start,SHCoef,phi,beta,SGData) |
---|
1690 | PX = np.array(SHData['PFxyz']) |
---|
1691 | gam = atan2d(PX[0],PX[1]) |
---|
1692 | xy = math.sqrt(PX[0]**2+PX[1]**2) |
---|
1693 | xyz = math.sqrt(PX[0]**2+PX[1]**2+PX[2]**2) |
---|
1694 | psi = asind(xy/xyz) |
---|
1695 | IODFln = G2lat.Glnh(Start,SHCoef,psi,gam,SamSym[textureData['Model']]) |
---|
1696 | if 'Axial' in SHData['PlotType']: |
---|
1697 | X = np.linspace(0,90.0,26) |
---|
1698 | Y = G2lat.polfcal(ODFln,SamSym[textureData['Model']],X,0.0) |
---|
1699 | Plot.plot(X,Y,color='k',label=str(SHData['PFhkl'])) |
---|
1700 | Plot.legend(loc='best') |
---|
1701 | Plot.set_title('Axial distribution for HKL='+str(SHData['PFhkl'])) |
---|
1702 | Plot.set_xlabel(r'$\psi$',fontsize=16) |
---|
1703 | Plot.set_ylabel('MRD',fontsize=14) |
---|
1704 | |
---|
1705 | else: |
---|
1706 | npts = 201 |
---|
1707 | if 'Inverse' in SHData['PlotType']: |
---|
1708 | X,Y = np.meshgrid(np.linspace(1.,-1.,npts),np.linspace(-1.,1.,npts)) |
---|
1709 | R,P = np.sqrt(X**2+Y**2).flatten(),npatan2d(X,Y).flatten() |
---|
1710 | if 'equal' in G2frame.Projection: |
---|
1711 | R = np.where(R <= 1.,2.*npasind(R*sq2),0.0) |
---|
1712 | else: |
---|
1713 | R = np.where(R <= 1.,2.*npatand(R),0.0) |
---|
1714 | Z = np.zeros_like(R) |
---|
1715 | Z = G2lat.invpolfcal(IODFln,SGData,R,P) |
---|
1716 | Z = np.reshape(Z,(npts,npts)) |
---|
1717 | CS = Plot.contour(Y,X,Z,aspect='equal') |
---|
1718 | Plot.clabel(CS,fontsize=9,inline=1) |
---|
1719 | try: |
---|
1720 | Img = Plot.imshow(Z.T,aspect='equal',cmap=G2frame.ContourColor,extent=[-1,1,-1,1]) |
---|
1721 | except ValueError: |
---|
1722 | pass |
---|
1723 | Page.figure.colorbar(Img) |
---|
1724 | Plot.set_title('Inverse pole figure for XYZ='+str(SHData['PFxyz'])) |
---|
1725 | Plot.set_xlabel(G2frame.Projection.capitalize()+' projection') |
---|
1726 | |
---|
1727 | else: |
---|
1728 | X,Y = np.meshgrid(np.linspace(1.,-1.,npts),np.linspace(-1.,1.,npts)) |
---|
1729 | R,P = np.sqrt(X**2+Y**2).flatten(),npatan2d(X,Y).flatten() |
---|
1730 | if 'equal' in G2frame.Projection: |
---|
1731 | R = np.where(R <= 1.,2.*npasind(R*sq2),0.0) |
---|
1732 | else: |
---|
1733 | R = np.where(R <= 1.,2.*npatand(R),0.0) |
---|
1734 | Z = np.zeros_like(R) |
---|
1735 | Z = G2lat.polfcal(ODFln,SamSym[textureData['Model']],R,P) |
---|
1736 | Z = np.reshape(Z,(npts,npts)) |
---|
1737 | try: |
---|
1738 | CS = Plot.contour(Y,X,Z,aspect='equal') |
---|
1739 | Plot.clabel(CS,fontsize=9,inline=1) |
---|
1740 | except ValueError: |
---|
1741 | pass |
---|
1742 | Img = Plot.imshow(Z.T,aspect='equal',cmap=G2frame.ContourColor,extent=[-1,1,-1,1]) |
---|
1743 | Page.figure.colorbar(Img) |
---|
1744 | Plot.set_title('Pole figure for HKL='+str(SHData['PFhkl'])) |
---|
1745 | Plot.set_xlabel(G2frame.Projection.capitalize()+' projection') |
---|
1746 | Page.canvas.draw() |
---|
1747 | |
---|
1748 | ################################################################################ |
---|
1749 | ##### PlotCovariance |
---|
1750 | ################################################################################ |
---|
1751 | |
---|
1752 | def PlotCovariance(G2frame,Data): |
---|
1753 | 'needs a doc string' |
---|
1754 | if not Data: |
---|
1755 | print 'No covariance matrix available' |
---|
1756 | return |
---|
1757 | varyList = Data['varyList'] |
---|
1758 | values = Data['variables'] |
---|
1759 | Xmax = len(varyList) |
---|
1760 | covMatrix = Data['covMatrix'] |
---|
1761 | sig = np.sqrt(np.diag(covMatrix)) |
---|
1762 | xvar = np.outer(sig,np.ones_like(sig)) |
---|
1763 | covArray = np.divide(np.divide(covMatrix,xvar),xvar.T) |
---|
1764 | title = ' for\n'+Data['title'] |
---|
1765 | newAtomDict = Data['newAtomDict'] |
---|
1766 | |
---|
1767 | |
---|
1768 | def OnPlotKeyPress(event): |
---|
1769 | newPlot = False |
---|
1770 | if event.key == 's': |
---|
1771 | choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] |
---|
1772 | choice.sort() |
---|
1773 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice) |
---|
1774 | if dlg.ShowModal() == wx.ID_OK: |
---|
1775 | sel = dlg.GetSelection() |
---|
1776 | G2frame.VcovColor = choice[sel] |
---|
1777 | else: |
---|
1778 | G2frame.VcovColor = 'RdYlGn' |
---|
1779 | dlg.Destroy() |
---|
1780 | PlotCovariance(G2frame,Data) |
---|
1781 | |
---|
1782 | def OnMotion(event): |
---|
1783 | #there is a problem here - reports wrong values |
---|
1784 | if event.button: |
---|
1785 | ytics = imgAx.get_yticks() |
---|
1786 | ytics = np.where(ytics<len(varyList),ytics,-1) |
---|
1787 | ylabs = [np.where(0<=i ,varyList[int(i)],' ') for i in ytics] |
---|
1788 | imgAx.set_yticklabels(ylabs) |
---|
1789 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
1790 | xpos = int(event.xdata+.5) |
---|
1791 | ypos = int(event.ydata+.5) |
---|
1792 | if -1 < xpos < len(varyList) and -1 < ypos < len(varyList): |
---|
1793 | if xpos == ypos: |
---|
1794 | value = values[xpos] |
---|
1795 | name = varyList[xpos] |
---|
1796 | if varyList[xpos] in newAtomDict: |
---|
1797 | name,value = newAtomDict[name] |
---|
1798 | msg = '%s value = %.4g, esd = %.4g'%(name,value,sig[xpos]) |
---|
1799 | else: |
---|
1800 | msg = '%s - %s: %5.3f'%(varyList[xpos],varyList[ypos],covArray[xpos][ypos]) |
---|
1801 | Page.canvas.SetToolTipString(msg) |
---|
1802 | G2frame.G2plotNB.status.SetFields(['',msg]) |
---|
1803 | |
---|
1804 | try: |
---|
1805 | plotNum = G2frame.G2plotNB.plotList.index('Covariance') |
---|
1806 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1807 | Page.figure.clf() |
---|
1808 | Plot = Page.figure.gca() |
---|
1809 | if not Page.IsShown(): |
---|
1810 | Page.Show() |
---|
1811 | except ValueError: |
---|
1812 | Plot = G2frame.G2plotNB.addMpl('Covariance').gca() |
---|
1813 | plotNum = G2frame.G2plotNB.plotList.index('Covariance') |
---|
1814 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1815 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
1816 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
1817 | Page.Choice = ['s: to change colors'] |
---|
1818 | Page.keyPress = OnPlotKeyPress |
---|
1819 | Page.SetFocus() |
---|
1820 | G2frame.G2plotNB.status.SetFields(['','']) |
---|
1821 | acolor = mpl.cm.get_cmap(G2frame.VcovColor) |
---|
1822 | Img = Plot.imshow(covArray,aspect='equal',cmap=acolor,interpolation='nearest',origin='lower', |
---|
1823 | vmin=-1.,vmax=1.) |
---|
1824 | imgAx = Img.get_axes() |
---|
1825 | ytics = imgAx.get_yticks() |
---|
1826 | ylabs = [varyList[int(i)] for i in ytics[:-1]] |
---|
1827 | imgAx.set_yticklabels(ylabs) |
---|
1828 | colorBar = Page.figure.colorbar(Img) |
---|
1829 | Plot.set_title('V-Cov matrix'+title) |
---|
1830 | Plot.set_xlabel('Variable number') |
---|
1831 | Plot.set_ylabel('Variable name') |
---|
1832 | Page.canvas.draw() |
---|
1833 | |
---|
1834 | ################################################################################ |
---|
1835 | ##### PlotTorsion |
---|
1836 | ################################################################################ |
---|
1837 | |
---|
1838 | def PlotTorsion(G2frame,phaseName,Torsion,TorName,Names=[],Angles=[],Coeff=[]): |
---|
1839 | 'needs a doc string' |
---|
1840 | |
---|
1841 | global names |
---|
1842 | names = Names |
---|
1843 | sum = np.sum(Torsion) |
---|
1844 | torsion = np.log(2*Torsion+1.)/sum |
---|
1845 | tMin = np.min(torsion) |
---|
1846 | tMax = np.max(torsion) |
---|
1847 | torsion = 3.*(torsion-tMin)/(tMax-tMin) |
---|
1848 | X = np.linspace(0.,360.,num=45) |
---|
1849 | |
---|
1850 | def OnMotion(event): |
---|
1851 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
1852 | xpos = event.xdata |
---|
1853 | ypos = event.ydata |
---|
1854 | msg = 'torsion,energy: %5.3f %5.3f'%(xpos,ypos) |
---|
1855 | Page.canvas.SetToolTipString(msg) |
---|
1856 | G2frame.G2plotNB.status.SetFields(['',msg]) |
---|
1857 | if len(Angles): |
---|
1858 | fX = np.where(np.fabs(Angles-xpos)<1.0)[0] |
---|
1859 | if len(fX): |
---|
1860 | msg = 'atoms:'+names[fX[0]-1] |
---|
1861 | Page.canvas.SetToolTipString(msg) |
---|
1862 | |
---|
1863 | try: |
---|
1864 | plotNum = G2frame.G2plotNB.plotList.index('Torsion') |
---|
1865 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1866 | Page.figure.clf() |
---|
1867 | Plot = Page.figure.gca() |
---|
1868 | if not Page.IsShown(): |
---|
1869 | Page.Show() |
---|
1870 | except ValueError: |
---|
1871 | Plot = G2frame.G2plotNB.addMpl('Torsion').gca() |
---|
1872 | plotNum = G2frame.G2plotNB.plotList.index('Torsion') |
---|
1873 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1874 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
1875 | |
---|
1876 | Page.SetFocus() |
---|
1877 | G2frame.G2plotNB.status.SetFields(['','']) |
---|
1878 | Plot.plot(X,torsion,'b+') |
---|
1879 | if len(Coeff): |
---|
1880 | X2 = np.linspace(0.,360.,45) |
---|
1881 | Y2 = np.array([-G2mth.calcTorsionEnergy(x,Coeff)[1] for x in X2]) |
---|
1882 | Plot.plot(X2,Y2,'r') |
---|
1883 | if len(Angles): |
---|
1884 | Eval = np.array([-G2mth.calcTorsionEnergy(x,Coeff)[1] for x in Angles]) |
---|
1885 | Plot.plot(Angles,Eval,'ro') |
---|
1886 | Plot.set_xlim((0.,360.)) |
---|
1887 | Plot.set_title('Torsion angles for '+TorName+' in '+phaseName) |
---|
1888 | Plot.set_xlabel('angle',fontsize=16) |
---|
1889 | Plot.set_ylabel('Energy',fontsize=16) |
---|
1890 | Page.canvas.draw() |
---|
1891 | |
---|
1892 | ################################################################################ |
---|
1893 | ##### PlotRama |
---|
1894 | ################################################################################ |
---|
1895 | |
---|
1896 | def PlotRama(G2frame,phaseName,Rama,RamaName,Names=[],PhiPsi=[],Coeff=[]): |
---|
1897 | 'needs a doc string' |
---|
1898 | |
---|
1899 | global names |
---|
1900 | names = Names |
---|
1901 | rama = np.log(2*Rama+1.) |
---|
1902 | ramaMax = np.max(rama) |
---|
1903 | rama = np.reshape(rama,(45,45)) |
---|
1904 | global Phi,Psi |
---|
1905 | Phi = [] |
---|
1906 | Psi = [] |
---|
1907 | |
---|
1908 | def OnPlotKeyPress(event): |
---|
1909 | newPlot = False |
---|
1910 | if event.key == 's': |
---|
1911 | choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] |
---|
1912 | choice.sort() |
---|
1913 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice) |
---|
1914 | if dlg.ShowModal() == wx.ID_OK: |
---|
1915 | sel = dlg.GetSelection() |
---|
1916 | G2frame.RamaColor = choice[sel] |
---|
1917 | else: |
---|
1918 | G2frame.RamaColor = 'RdYlGn' |
---|
1919 | dlg.Destroy() |
---|
1920 | PlotRama(G2frame,phaseName,Rama) |
---|
1921 | |
---|
1922 | def OnMotion(event): |
---|
1923 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
1924 | xpos = event.xdata |
---|
1925 | ypos = event.ydata |
---|
1926 | msg = 'phi/psi: %5.3f %5.3f'%(xpos,ypos) |
---|
1927 | Page.canvas.SetToolTipString(msg) |
---|
1928 | G2frame.G2plotNB.status.SetFields(['',msg]) |
---|
1929 | if len(Phi): |
---|
1930 | fPhi = np.where(np.fabs(Phi-xpos)<1.0)[0] |
---|
1931 | fPsi = np.where(np.fabs(Psi-ypos)<1.0)[0] |
---|
1932 | if len(fPhi) and len(fPsi) and fPhi[0] == fPsi[0]: |
---|
1933 | msg = 'atoms:'+names[fPhi[0]-1] |
---|
1934 | Page.canvas.SetToolTipString(msg) |
---|
1935 | |
---|
1936 | try: |
---|
1937 | plotNum = G2frame.G2plotNB.plotList.index('Ramachandran') |
---|
1938 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1939 | Page.figure.clf() |
---|
1940 | Plot = Page.figure.gca() |
---|
1941 | if not Page.IsShown(): |
---|
1942 | Page.Show() |
---|
1943 | except ValueError: |
---|
1944 | Plot = G2frame.G2plotNB.addMpl('Ramachandran').gca() |
---|
1945 | plotNum = G2frame.G2plotNB.plotList.index('Ramachandran') |
---|
1946 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
1947 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
1948 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
1949 | |
---|
1950 | Page.Choice = ['s: to change colors'] |
---|
1951 | Page.keyPress = OnPlotKeyPress |
---|
1952 | Page.SetFocus() |
---|
1953 | G2frame.G2plotNB.status.SetFields(['','']) |
---|
1954 | acolor = mpl.cm.get_cmap(G2frame.RamaColor) |
---|
1955 | if RamaName == 'All' or '-1' in RamaName: |
---|
1956 | if len(Coeff): |
---|
1957 | X,Y = np.meshgrid(np.linspace(-180.,180.,45),np.linspace(-180.,180.,45)) |
---|
1958 | Z = np.array([-G2mth.calcRamaEnergy(x,y,Coeff)[1] for x,y in zip(X.flatten(),Y.flatten())]) |
---|
1959 | Plot.contour(X,Y,np.reshape(Z,(45,45))) |
---|
1960 | Img = Plot.imshow(rama,aspect='equal',cmap=acolor,interpolation='nearest', |
---|
1961 | extent=[-180,180,-180,180],origin='lower') |
---|
1962 | if len(PhiPsi): |
---|
1963 | Phi,Psi = PhiPsi.T |
---|
1964 | Phi = np.where(Phi>180.,Phi-360.,Phi) |
---|
1965 | Psi = np.where(Psi>180.,Psi-360.,Psi) |
---|
1966 | Plot.plot(Phi,Psi,'ro',picker=3) |
---|
1967 | Plot.set_xlim((-180.,180.)) |
---|
1968 | Plot.set_ylim((-180.,180.)) |
---|
1969 | else: |
---|
1970 | if len(Coeff): |
---|
1971 | X,Y = np.meshgrid(np.linspace(0.,360.,45),np.linspace(0.,360.,45)) |
---|
1972 | Z = np.array([-G2mth.calcRamaEnergy(x,y,Coeff)[1] for x,y in zip(X.flatten(),Y.flatten())]) |
---|
1973 | Plot.contour(X,Y,np.reshape(Z,(45,45))) |
---|
1974 | Img = Plot.imshow(rama,aspect='equal',cmap=acolor,interpolation='nearest', |
---|
1975 | extent=[0,360,0,360],origin='lower') |
---|
1976 | if len(PhiPsi): |
---|
1977 | Phi,Psi = PhiPsi.T |
---|
1978 | Plot.plot(Phi,Psi,'ro',picker=3) |
---|
1979 | Plot.set_xlim((0.,360.)) |
---|
1980 | Plot.set_ylim((0.,360.)) |
---|
1981 | Plot.set_title('Ramachandran for '+RamaName+' in '+phaseName) |
---|
1982 | Plot.set_xlabel(r'$\phi$',fontsize=16) |
---|
1983 | Plot.set_ylabel(r'$\psi$',fontsize=16) |
---|
1984 | colorBar = Page.figure.colorbar(Img) |
---|
1985 | Page.canvas.draw() |
---|
1986 | |
---|
1987 | |
---|
1988 | ################################################################################ |
---|
1989 | ##### PlotSeq |
---|
1990 | ################################################################################ |
---|
1991 | |
---|
1992 | def PlotSeq(G2frame,SeqData,SeqSig,SeqNames,sampleParm): |
---|
1993 | 'needs a doc string' |
---|
1994 | |
---|
1995 | def OnKeyPress(event): |
---|
1996 | if event.key == 's' and sampleParm: |
---|
1997 | if G2frame.xAxis: |
---|
1998 | G2frame.xAxis = False |
---|
1999 | else: |
---|
2000 | G2frame.xAxis = True |
---|
2001 | Draw(False) |
---|
2002 | try: |
---|
2003 | plotNum = G2frame.G2plotNB.plotList.index('Sequential refinement') |
---|
2004 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
2005 | Page.figure.clf() |
---|
2006 | Plot = Page.figure.gca() |
---|
2007 | if not Page.IsShown(): |
---|
2008 | Page.Show() |
---|
2009 | except ValueError: |
---|
2010 | Plot = G2frame.G2plotNB.addMpl('Sequential refinement').gca() |
---|
2011 | plotNum = G2frame.G2plotNB.plotList.index('Sequential refinement') |
---|
2012 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
2013 | Page.canvas.mpl_connect('key_press_event', OnKeyPress) |
---|
2014 | G2frame.xAxis = False |
---|
2015 | Page.Choice = ['s to toggle x-axis = sample environment parameter'] |
---|
2016 | Page.keyPress = OnKeyPress |
---|
2017 | |
---|
2018 | def Draw(newPlot): |
---|
2019 | Page.SetFocus() |
---|
2020 | G2frame.G2plotNB.status.SetFields(['','press ']) |
---|
2021 | if len(SeqData): |
---|
2022 | Plot.clear() |
---|
2023 | if G2frame.xAxis: |
---|
2024 | xName = sampleParm.keys()[0] |
---|
2025 | X = sampleParm[xName] |
---|
2026 | else: |
---|
2027 | X = np.arange(0,len(SeqData[0]),1) |
---|
2028 | xName = 'Data sequence number' |
---|
2029 | for Y,sig,name in zip(SeqData,SeqSig,SeqNames): |
---|
2030 | Plot.errorbar(X,Y,yerr=sig,label=name) |
---|
2031 | Plot.legend(loc='best') |
---|
2032 | Plot.set_ylabel('Parameter values') |
---|
2033 | Plot.set_xlabel(xName) |
---|
2034 | Page.canvas.draw() |
---|
2035 | Draw(True) |
---|
2036 | |
---|
2037 | ################################################################################ |
---|
2038 | ##### PlotExposedImage & PlotImage |
---|
2039 | ################################################################################ |
---|
2040 | |
---|
2041 | def PlotExposedImage(G2frame,newPlot=False,event=None): |
---|
2042 | '''General access module for 2D image plotting |
---|
2043 | ''' |
---|
2044 | plotNo = G2frame.G2plotNB.nb.GetSelection() |
---|
2045 | if G2frame.G2plotNB.nb.GetPageText(plotNo) == '2D Powder Image': |
---|
2046 | PlotImage(G2frame,newPlot,event,newImage=True) |
---|
2047 | elif G2frame.G2plotNB.nb.GetPageText(plotNo) == '2D Integration': |
---|
2048 | PlotIntegration(G2frame,newPlot,event) |
---|
2049 | |
---|
2050 | def PlotImage(G2frame,newPlot=False,event=None,newImage=True): |
---|
2051 | '''Plot of 2D detector images as contoured plot. Also plot calibration ellipses, |
---|
2052 | masks, etc. |
---|
2053 | ''' |
---|
2054 | from matplotlib.patches import Ellipse,Arc,Circle,Polygon |
---|
2055 | import numpy.ma as ma |
---|
2056 | Dsp = lambda tth,wave: wave/(2.*sind(tth/2.)) |
---|
2057 | global Data,Masks |
---|
2058 | colors=['b','g','r','c','m','k'] |
---|
2059 | Data = G2frame.PatternTree.GetItemPyData( |
---|
2060 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls')) |
---|
2061 | Masks = G2frame.PatternTree.GetItemPyData( |
---|
2062 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks')) |
---|
2063 | try: #may be absent |
---|
2064 | StrSta = G2frame.PatternTree.GetItemPyData( |
---|
2065 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Stress/Strain')) |
---|
2066 | except TypeError: #is missing |
---|
2067 | StrSta = {} |
---|
2068 | |
---|
2069 | def OnImMotion(event): |
---|
2070 | Page.canvas.SetToolTipString('') |
---|
2071 | sizexy = Data['size'] |
---|
2072 | if event.xdata and event.ydata and len(G2frame.ImageZ): #avoid out of frame errors |
---|
2073 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
2074 | item = G2frame.itemPicked |
---|
2075 | pixelSize = Data['pixelSize'] |
---|
2076 | scalex = 1000./pixelSize[0] |
---|
2077 | scaley = 1000./pixelSize[1] |
---|
2078 | if item and G2frame.PatternTree.GetItemText(G2frame.PickId) == 'Image Controls': |
---|
2079 | if 'Text' in str(item): |
---|
2080 | Page.canvas.SetToolTipString('%8.3f %8.3fmm'%(event.xdata,event.ydata)) |
---|
2081 | else: |
---|
2082 | xcent,ycent = Data['center'] |
---|
2083 | xpos = event.xdata-xcent |
---|
2084 | ypos = event.ydata-ycent |
---|
2085 | tth,azm = G2img.GetTthAzm(event.xdata,event.ydata,Data) |
---|
2086 | if 'line3' in str(item) or 'line4' in str(item) and not Data['fullIntegrate']: |
---|
2087 | Page.canvas.SetToolTipString('%6d deg'%(azm)) |
---|
2088 | elif 'line1' in str(item) or 'line2' in str(item): |
---|
2089 | Page.canvas.SetToolTipString('%8.3fdeg'%(tth)) |
---|
2090 | else: |
---|
2091 | xpos = event.xdata |
---|
2092 | ypos = event.ydata |
---|
2093 | xpix = xpos*scalex |
---|
2094 | ypix = ypos*scaley |
---|
2095 | Int = 0 |
---|
2096 | if (0 <= xpix <= sizexy[0]) and (0 <= ypix <= sizexy[1]): |
---|
2097 | Int = G2frame.ImageZ[ypix][xpix] |
---|
2098 | tth,azm,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data) |
---|
2099 | Q = 2.*math.pi/dsp |
---|
2100 | if G2frame.setPoly: |
---|
2101 | G2frame.G2plotNB.status.SetFields(['','Polygon mask pick - LB next point, RB close polygon']) |
---|
2102 | else: |
---|
2103 | G2frame.G2plotNB.status.SetFields(\ |
---|
2104 | ['','Detector 2-th =%9.3fdeg, dsp =%9.3fA, Q = %6.5fA-1, azm = %7.2fdeg, I = %6d'%(tth,dsp,Q,azm,Int)]) |
---|
2105 | |
---|
2106 | def OnImPlotKeyPress(event): |
---|
2107 | try: |
---|
2108 | PickName = G2frame.PatternTree.GetItemText(G2frame.PickId) |
---|
2109 | except TypeError: |
---|
2110 | return |
---|
2111 | if PickName == 'Masks': |
---|
2112 | Xpos = event.xdata |
---|
2113 | if not Xpos: #got point out of frame |
---|
2114 | return |
---|
2115 | Ypos = event.ydata |
---|
2116 | if event.key == 's': |
---|
2117 | Masks['Points'].append([Xpos,Ypos,1.]) |
---|
2118 | elif event.key == 'r': |
---|
2119 | tth = G2img.GetTth(Xpos,Ypos,Data) |
---|
2120 | Masks['Rings'].append([tth,0.1]) |
---|
2121 | elif event.key == 'a': |
---|
2122 | tth,azm = G2img.GetTthAzm(Xpos,Ypos,Data) |
---|
2123 | azm = int(azm) |
---|
2124 | Masks['Arcs'].append([tth,[azm-5,azm+5],0.1]) |
---|
2125 | elif event.key == 'p': |
---|
2126 | G2frame.setPoly = True |
---|
2127 | Masks['Polygons'].append([]) |
---|
2128 | G2frame.G2plotNB.status.SetFields(['','Polygon mask active - LB pick next point, RB close polygon']) |
---|
2129 | G2imG.UpdateMasks(G2frame,Masks) |
---|
2130 | elif PickName == 'Image Controls': |
---|
2131 | if event.key == 'c': |
---|
2132 | Xpos = event.xdata |
---|
2133 | if not Xpos: #got point out of frame |
---|
2134 | return |
---|
2135 | Ypos = event.ydata |
---|
2136 | dlg = wx.MessageDialog(G2frame,'Are you sure you want to change the center?', |
---|
2137 | 'Center change',style=wx.OK|wx.CANCEL) |
---|
2138 | try: |
---|
2139 | if dlg.ShowModal() == wx.ID_OK: |
---|
2140 | print 'move center to: ',Xpos,Ypos |
---|
2141 | Data['center'] = [Xpos,Ypos] |
---|
2142 | G2imG.UpdateImageControls(G2frame,Data,Masks) |
---|
2143 | finally: |
---|
2144 | dlg.Destroy() |
---|
2145 | elif event.key == 'l': |
---|
2146 | if G2frame.logPlot: |
---|
2147 | G2frame.logPlot = False |
---|
2148 | else: |
---|
2149 | G2frame.logPlot = True |
---|
2150 | PlotImage(G2frame,newImage=True) |
---|
2151 | |
---|
2152 | def OnKeyBox(event): |
---|
2153 | if G2frame.G2plotNB.nb.GetSelection() == G2frame.G2plotNB.plotList.index('2D Powder Image'): |
---|
2154 | event.key = cb.GetValue()[0] |
---|
2155 | cb.SetValue(' key press') |
---|
2156 | if event.key in 'l': |
---|
2157 | wx.CallAfter(OnImPlotKeyPress,event) |
---|
2158 | Page.canvas.SetFocus() # redirect the Focus from the button back to the plot |
---|
2159 | |
---|
2160 | def OnImPick(event): |
---|
2161 | if G2frame.PatternTree.GetItemText(G2frame.PickId) not in ['Image Controls','Masks']: |
---|
2162 | return |
---|
2163 | if G2frame.setPoly: |
---|
2164 | polygon = Masks['Polygons'][-1] |
---|
2165 | xpos,ypos = event.mouseevent.xdata,event.mouseevent.ydata |
---|
2166 | if xpos and ypos: #point inside image |
---|
2167 | if len(polygon) > 2 and event.mouseevent.button == 3: |
---|
2168 | x0,y0 = polygon[0] |
---|
2169 | polygon.append([x0,y0]) |
---|
2170 | G2frame.setPoly = False |
---|
2171 | G2frame.G2plotNB.status.SetFields(['','Polygon closed - RB drag a vertex to change shape']) |
---|
2172 | else: |
---|
2173 | G2frame.G2plotNB.status.SetFields(['','New polygon point: %.1f,%.1f'%(xpos,ypos)]) |
---|
2174 | polygon.append([xpos,ypos]) |
---|
2175 | G2imG.UpdateMasks(G2frame,Masks) |
---|
2176 | else: |
---|
2177 | if G2frame.itemPicked is not None: return |
---|
2178 | G2frame.itemPicked = event.artist |
---|
2179 | G2frame.mousePicked = event.mouseevent |
---|
2180 | |
---|
2181 | def OnImRelease(event): |
---|
2182 | try: |
---|
2183 | PickName = G2frame.PatternTree.GetItemText(G2frame.PickId) |
---|
2184 | except TypeError: |
---|
2185 | return |
---|
2186 | if PickName not in ['Image Controls','Masks']: |
---|
2187 | return |
---|
2188 | pixelSize = Data['pixelSize'] |
---|
2189 | scalex = 1000./pixelSize[0] |
---|
2190 | scaley = 1000./pixelSize[1] |
---|
2191 | pixLimit = Data['pixLimit'] |
---|
2192 | if G2frame.itemPicked is None and PickName == 'Image Controls' and len(G2frame.ImageZ): |
---|
2193 | # sizexy = Data['size'] |
---|
2194 | Xpos = event.xdata |
---|
2195 | if not (Xpos and G2frame.ifGetRing): #got point out of frame |
---|
2196 | return |
---|
2197 | Ypos = event.ydata |
---|
2198 | if Ypos and not Page.toolbar._active: #make sure zoom/pan not selected |
---|
2199 | if event.button == 1: |
---|
2200 | Xpix = Xpos*scalex |
---|
2201 | Ypix = Ypos*scaley |
---|
2202 | xpos,ypos,I,J = G2img.ImageLocalMax(G2frame.ImageZ,pixLimit,Xpix,Ypix) |
---|
2203 | if I and J: |
---|
2204 | xpos += .5 #shift to pixel center |
---|
2205 | ypos += .5 |
---|
2206 | xpos /= scalex #convert to mm |
---|
2207 | ypos /= scaley |
---|
2208 | Data['ring'].append([xpos,ypos]) |
---|
2209 | elif event.button == 3: |
---|
2210 | G2frame.dataFrame.GetStatusBar().SetStatusText('Calibrating...') |
---|
2211 | if G2img.ImageCalibrate(G2frame,Data): |
---|
2212 | G2frame.dataFrame.GetStatusBar().SetStatusText('Calibration successful - Show ring picks to check') |
---|
2213 | print 'Calibration successful' |
---|
2214 | else: |
---|
2215 | G2frame.dataFrame.GetStatusBar().SetStatusText('Calibration failed - Show ring picks to diagnose') |
---|
2216 | print 'Calibration failed' |
---|
2217 | G2frame.ifGetRing = False |
---|
2218 | G2imG.UpdateImageControls(G2frame,Data,Masks) |
---|
2219 | return |
---|
2220 | PlotImage(G2frame,newImage=False) |
---|
2221 | return |
---|
2222 | else: |
---|
2223 | xpos = event.xdata |
---|
2224 | if xpos: #avoid out of frame mouse position |
---|
2225 | ypos = event.ydata |
---|
2226 | if G2frame.ifGetRing: #delete a calibration ring pick |
---|
2227 | xypos = [xpos,ypos] |
---|
2228 | rings = Data['ring'] |
---|
2229 | for ring in rings: |
---|
2230 | if np.allclose(ring,xypos,.01,0): |
---|
2231 | rings.remove(ring) |
---|
2232 | else: |
---|
2233 | tth,azm,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data) |
---|
2234 | itemPicked = str(G2frame.itemPicked) |
---|
2235 | if 'Line2D' in itemPicked and PickName == 'Image Controls': |
---|
2236 | if 'line1' in itemPicked: |
---|
2237 | Data['IOtth'][0] = max(tth,0.001) |
---|
2238 | elif 'line2' in itemPicked: |
---|
2239 | Data['IOtth'][1] = tth |
---|
2240 | elif 'line3' in itemPicked: |
---|
2241 | Data['LRazimuth'][0] = int(azm) |
---|
2242 | if Data['fullIntegrate']: |
---|
2243 | Data['LRazimuth'][1] = Data['LRazimuth'][0]+360 |
---|
2244 | elif 'line4' in itemPicked and not Data['fullIntegrate']: |
---|
2245 | Data['LRazimuth'][1] = int(azm) |
---|
2246 | |
---|
2247 | if Data['LRazimuth'][0] > Data['LRazimuth'][1]: |
---|
2248 | Data['LRazimuth'][0] -= 360 |
---|
2249 | |
---|
2250 | azLim = np.array(Data['LRazimuth']) |
---|
2251 | if np.any(azLim>360): |
---|
2252 | azLim -= 360 |
---|
2253 | Data['LRazimuth'] = list(azLim) |
---|
2254 | |
---|
2255 | if Data['IOtth'][0] > Data['IOtth'][1]: |
---|
2256 | Data['IOtth'][0],Data['IOtth'][1] = Data['IOtth'][1],Data['IOtth'][0] |
---|
2257 | |
---|
2258 | G2frame.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0])) |
---|
2259 | G2frame.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1])) |
---|
2260 | G2frame.Lazim.SetValue("%6d" % (Data['LRazimuth'][0])) |
---|
2261 | G2frame.Razim.SetValue("%6d" % (Data['LRazimuth'][1])) |
---|
2262 | elif 'Circle' in itemPicked and PickName == 'Masks': |
---|
2263 | spots = Masks['Points'] |
---|
2264 | newPos = itemPicked.split(')')[0].split('(')[2].split(',') |
---|
2265 | newPos = np.array([float(newPos[0]),float(newPos[1])]) |
---|
2266 | for spot in spots: |
---|
2267 | if np.allclose(np.array([spot[:2]]),newPos): |
---|
2268 | spot[:2] = xpos,ypos |
---|
2269 | G2imG.UpdateMasks(G2frame,Masks) |
---|
2270 | elif 'Line2D' in itemPicked and PickName == 'Masks': |
---|
2271 | Obj = G2frame.itemPicked.findobj() |
---|
2272 | rings = Masks['Rings'] |
---|
2273 | arcs = Masks['Arcs'] |
---|
2274 | polygons = Masks['Polygons'] |
---|
2275 | for ring in G2frame.ringList: |
---|
2276 | if Obj == ring[0]: |
---|
2277 | rN = ring[1] |
---|
2278 | if ring[2] == 'o': |
---|
2279 | rings[rN][0] = G2img.GetTth(xpos,ypos,Data)-rings[rN][1]/2. |
---|
2280 | else: |
---|
2281 | rings[rN][0] = G2img.GetTth(xpos,ypos,Data)+rings[rN][1]/2. |
---|
2282 | for arc in G2frame.arcList: |
---|
2283 | if Obj == arc[0]: |
---|
2284 | aN = arc[1] |
---|
2285 | if arc[2] == 'o': |
---|
2286 | arcs[aN][0] = G2img.GetTth(xpos,ypos,Data)-arcs[aN][2]/2 |
---|
2287 | elif arc[2] == 'i': |
---|
2288 | arcs[aN][0] = G2img.GetTth(xpos,ypos,Data)+arcs[aN][2]/2 |
---|
2289 | elif arc[2] == 'l': |
---|
2290 | arcs[aN][1][0] = int(G2img.GetAzm(xpos,ypos,Data)) |
---|
2291 | else: |
---|
2292 | arcs[aN][1][1] = int(G2img.GetAzm(xpos,ypos,Data)) |
---|
2293 | for poly in G2frame.polyList: |
---|
2294 | if Obj == poly[0]: |
---|
2295 | ind = G2frame.itemPicked.contains(G2frame.mousePicked)[1]['ind'][0] |
---|
2296 | oldPos = np.array([G2frame.mousePicked.xdata,G2frame.mousePicked.ydata]) |
---|
2297 | pN = poly[1] |
---|
2298 | for i,xy in enumerate(polygons[pN]): |
---|
2299 | if np.allclose(np.array([xy]),oldPos,atol=1.0): |
---|
2300 | polygons[pN][i] = xpos,ypos |
---|
2301 | G2imG.UpdateMasks(G2frame,Masks) |
---|
2302 | # else: #keep for future debugging |
---|
2303 | # print str(G2frame.itemPicked),event.xdata,event.ydata,event.button |
---|
2304 | PlotImage(G2frame,newImage=True) |
---|
2305 | G2frame.itemPicked = None |
---|
2306 | |
---|
2307 | try: |
---|
2308 | plotNum = G2frame.G2plotNB.plotList.index('2D Powder Image') |
---|
2309 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
2310 | if not newPlot: |
---|
2311 | Plot = Page.figure.gca() #get previous powder plot & get limits |
---|
2312 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
2313 | if newImage: |
---|
2314 | Page.figure.clf() |
---|
2315 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
2316 | |
---|
2317 | except ValueError: |
---|
2318 | Plot = G2frame.G2plotNB.addMpl('2D Powder Image').gca() |
---|
2319 | plotNum = G2frame.G2plotNB.plotList.index('2D Powder Image') |
---|
2320 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
2321 | Page.canvas.mpl_connect('key_press_event', OnImPlotKeyPress) |
---|
2322 | Page.canvas.mpl_connect('motion_notify_event', OnImMotion) |
---|
2323 | Page.canvas.mpl_connect('pick_event', OnImPick) |
---|
2324 | Page.canvas.mpl_connect('button_release_event', OnImRelease) |
---|
2325 | xylim = [] |
---|
2326 | Page.Choice = None |
---|
2327 | if not event: #event from GUI TextCtrl - don't want focus to change to plot!!! |
---|
2328 | Page.SetFocus() |
---|
2329 | Title = G2frame.PatternTree.GetItemText(G2frame.Image)[4:] |
---|
2330 | G2frame.G2plotNB.status.DestroyChildren() |
---|
2331 | if G2frame.logPlot: |
---|
2332 | Title = 'log('+Title+')' |
---|
2333 | Plot.set_title(Title) |
---|
2334 | try: |
---|
2335 | if G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Image Controls',]: |
---|
2336 | Page.Choice = (' key press','l: log(I) on',) |
---|
2337 | if G2frame.logPlot: |
---|
2338 | Page.Choice[1] = 'l: log(I) off' |
---|
2339 | Page.keyPress = OnImPlotKeyPress |
---|
2340 | except TypeError: |
---|
2341 | pass |
---|
2342 | size,imagefile = G2frame.PatternTree.GetItemPyData(G2frame.Image) |
---|
2343 | if imagefile != G2frame.oldImagefile: |
---|
2344 | imagefile = G2IO.CheckImageFile(G2frame,imagefile) |
---|
2345 | if not imagefile: |
---|
2346 | G2frame.G2plotNB.Delete('2D Powder Image') |
---|
2347 | return |
---|
2348 | G2frame.PatternTree.SetItemPyData(G2frame.Image,[size,imagefile]) |
---|
2349 | G2frame.ImageZ = G2IO.GetImageData(G2frame,imagefile,imageOnly=True) |
---|
2350 | G2frame.oldImagefile = imagefile |
---|
2351 | |
---|
2352 | imScale = 1 |
---|
2353 | if len(G2frame.ImageZ) > 1024: |
---|
2354 | imScale = len(G2frame.ImageZ)/1024 |
---|
2355 | sizexy = Data['size'] |
---|
2356 | pixelSize = Data['pixelSize'] |
---|
2357 | scalex = 1000./pixelSize[0] |
---|
2358 | scaley = 1000./pixelSize[1] |
---|
2359 | Xmax = sizexy[0]*pixelSize[0]/1000. |
---|
2360 | Ymax = sizexy[1]*pixelSize[1]/1000. |
---|
2361 | xlim = (0,Xmax) |
---|
2362 | ylim = (Ymax,0) |
---|
2363 | Imin,Imax = Data['range'][1] |
---|
2364 | acolor = mpl.cm.get_cmap(Data['color']) |
---|
2365 | xcent,ycent = Data['center'] |
---|
2366 | Plot.set_xlabel('Image x-axis, mm',fontsize=12) |
---|
2367 | Plot.set_ylabel('Image y-axis, mm',fontsize=12) |
---|
2368 | #do threshold mask - "real" mask - others are just bondaries |
---|
2369 | Zlim = Masks['Thresholds'][1] |
---|
2370 | wx.BeginBusyCursor() |
---|
2371 | try: |
---|
2372 | |
---|
2373 | if newImage: |
---|
2374 | MA = ma.masked_greater(ma.masked_less(G2frame.ImageZ,Zlim[0]),Zlim[1]) |
---|
2375 | MaskA = ma.getmaskarray(MA) |
---|
2376 | A = G2img.ImageCompress(MA,imScale) |
---|
2377 | AM = G2img.ImageCompress(MaskA,imScale) |
---|
2378 | if G2frame.logPlot: |
---|
2379 | A = np.where(A>0,np.log(A),0) |
---|
2380 | AM = np.where(AM>0,np.log(AM),0) |
---|
2381 | Imin,Imax = [np.amin(A),np.amax(A)] |
---|
2382 | ImgM = Plot.imshow(AM,aspect='equal',cmap='Reds', |
---|
2383 | interpolation='nearest',vmin=0,vmax=2,extent=[0,Xmax,Ymax,0]) |
---|
2384 | Img = Plot.imshow(A,aspect='equal',cmap=acolor, |
---|
2385 | interpolation='nearest',vmin=Imin,vmax=Imax,extent=[0,Xmax,Ymax,0]) |
---|
2386 | if G2frame.setPoly: |
---|
2387 | Img.set_picker(True) |
---|
2388 | |
---|
2389 | Plot.plot(xcent,ycent,'x') |
---|
2390 | #G2frame.PatternTree.GetItemText(item) |
---|
2391 | if Data['showLines']: |
---|
2392 | LRAzim = Data['LRazimuth'] #NB: integers |
---|
2393 | Nazm = Data['outAzimuths'] |
---|
2394 | delAzm = float(LRAzim[1]-LRAzim[0])/Nazm |
---|
2395 | AzmthOff = Data['azmthOff'] |
---|
2396 | IOtth = Data['IOtth'] |
---|
2397 | wave = Data['wavelength'] |
---|
2398 | dspI = wave/(2.0*sind(IOtth[0]/2.0)) |
---|
2399 | ellI = G2img.GetEllipse(dspI,Data) #=False if dsp didn't yield an ellipse (ugh! a parabola or a hyperbola) |
---|
2400 | dspO = wave/(2.0*sind(IOtth[1]/2.0)) |
---|
2401 | ellO = G2img.GetEllipse(dspO,Data) #Ditto & more likely for outer ellipse |
---|
2402 | Azm = np.array(range(LRAzim[0],LRAzim[1]+1))-AzmthOff |
---|
2403 | if ellI: |
---|
2404 | xyI = [] |
---|
2405 | for azm in Azm: |
---|
2406 | xyI.append(G2img.GetDetectorXY(dspI,azm-90.,Data)) |
---|
2407 | xyI = np.array(xyI) |
---|
2408 | arcxI,arcyI = xyI.T |
---|
2409 | Plot.plot(arcxI,arcyI,picker=3) |
---|
2410 | if ellO: |
---|
2411 | xyO = [] |
---|
2412 | for azm in Azm: |
---|
2413 | xyO.append(G2img.GetDetectorXY(dspO,azm-90.,Data)) |
---|
2414 | xyO = np.array(xyO) |
---|
2415 | arcxO,arcyO = xyO.T |
---|
2416 | Plot.plot(arcxO,arcyO,picker=3) |
---|
2417 | if ellO and ellI: |
---|
2418 | Plot.plot([arcxI[0],arcxO[0]],[arcyI[0],arcyO[0]],picker=3) |
---|
2419 | Plot.plot([arcxI[-1],arcxO[-1]],[arcyI[-1],arcyO[-1]],picker=3) |
---|
2420 | for i in range(Nazm): |
---|
2421 | cake = LRAzim[0]+i*delAzm-AzmthOff |
---|
2422 | if Data['centerAzm']: |
---|
2423 | cake += delAzm/2. |
---|
2424 | ind = np.searchsorted(Azm,cake) |
---|
2425 | Plot.plot([arcxI[ind],arcxO[ind]],[arcyI[ind],arcyO[ind]],color='k',dashes=(5,5)) |
---|
2426 | |
---|
2427 | if G2frame.PatternTree.GetItemText(G2frame.PickId) in 'Image Controls': |
---|
2428 | for xring,yring in Data['ring']: |
---|
2429 | Plot.plot(xring,yring,'r+',picker=3) |
---|
2430 | if Data['setRings']: |
---|
2431 | # rings = np.concatenate((Data['rings']),axis=0) |
---|
2432 | N = 0 |
---|
2433 | for ring in Data['rings']: |
---|
2434 | xring,yring = np.array(ring).T[:2] |
---|
2435 | Plot.plot(xring,yring,'+',color=colors[N%6]) |
---|
2436 | N += 1 |
---|
2437 | for ellipse in Data['ellipses']: |
---|
2438 | cent,phi,[width,height],col = ellipse |
---|
2439 | Plot.add_artist(Ellipse([cent[0],cent[1]],2*width,2*height,phi,ec=col,fc='none')) |
---|
2440 | Plot.text(cent[0],cent[1],'+',color=col,ha='center',va='center') |
---|
2441 | if G2frame.PatternTree.GetItemText(G2frame.PickId) in 'Stress/Strain': |
---|
2442 | print 'plot stress/strain stuff' |
---|
2443 | for ring in StrSta['d-zero']: |
---|
2444 | xring,yring = ring['ImxyObs'] |
---|
2445 | Plot.plot(xring,yring,'r+') |
---|
2446 | # for xring,yring in ring['ImxyCalc'].T: |
---|
2447 | # Plot.add_artist(Polygon(ring['ImxyCalc'].T,ec='b',fc='none')) |
---|
2448 | # Plot.plot(xring,yring) |
---|
2449 | #masks - mask lines numbered after integration limit lines |
---|
2450 | spots = Masks['Points'] |
---|
2451 | rings = Masks['Rings'] |
---|
2452 | arcs = Masks['Arcs'] |
---|
2453 | polygons = Masks['Polygons'] |
---|
2454 | for x,y,d in spots: |
---|
2455 | Plot.add_artist(Circle((x,y),radius=d/2,fc='none',ec='r',picker=3)) |
---|
2456 | G2frame.ringList = [] |
---|
2457 | for iring,(tth,thick) in enumerate(rings): |
---|
2458 | wave = Data['wavelength'] |
---|
2459 | x1,y1 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth+thick/2.,wave),Data))),2) |
---|
2460 | x2,y2 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth-thick/2.,wave),Data))),2) |
---|
2461 | G2frame.ringList.append([Plot.plot(x1,y1,'r',picker=3),iring,'o']) |
---|
2462 | G2frame.ringList.append([Plot.plot(x2,y2,'r',picker=3),iring,'i']) |
---|
2463 | G2frame.arcList = [] |
---|
2464 | for iarc,(tth,azm,thick) in enumerate(arcs): |
---|
2465 | wave = Data['wavelength'] |
---|
2466 | x1,y1 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(tth+thick/2.,wave),Data),azm)),2) |
---|
2467 | x2,y2 = np.hsplit(np.array(G2img.makeIdealRing(G2img.GetEllipse(Dsp(max(0.01,tth-thick/2.),wave),Data),azm)),2) |
---|
2468 | G2frame.arcList.append([Plot.plot(x1,y1,'r',picker=3),iarc,'o']) |
---|
2469 | G2frame.arcList.append([Plot.plot(x2,y2,'r',picker=3),iarc,'i']) |
---|
2470 | G2frame.arcList.append([Plot.plot([x1[0],x2[0]],[y1[0],y2[0]],'r',picker=3),iarc,'l']) |
---|
2471 | G2frame.arcList.append([Plot.plot([x1[-1],x2[-1]],[y1[-1],y2[-1]],'r',picker=3),iarc,'u']) |
---|
2472 | G2frame.polyList = [] |
---|
2473 | for ipoly,polygon in enumerate(polygons): |
---|
2474 | x,y = np.hsplit(np.array(polygon),2) |
---|
2475 | G2frame.polyList.append([Plot.plot(x,y,'r+',picker=10),ipoly]) |
---|
2476 | Plot.plot(x,y,'r') |
---|
2477 | if newImage: |
---|
2478 | colorBar = Page.figure.colorbar(Img) |
---|
2479 | Plot.set_xlim(xlim) |
---|
2480 | Plot.set_ylim(ylim) |
---|
2481 | Plot.invert_yaxis() |
---|
2482 | if not newPlot and xylim: |
---|
2483 | Page.toolbar.push_current() |
---|
2484 | Plot.set_xlim(xylim[0]) |
---|
2485 | Plot.set_ylim(xylim[1]) |
---|
2486 | xylim = [] |
---|
2487 | Page.toolbar.push_current() |
---|
2488 | Page.toolbar.draw() |
---|
2489 | else: |
---|
2490 | Page.canvas.draw() |
---|
2491 | finally: |
---|
2492 | wx.EndBusyCursor() |
---|
2493 | |
---|
2494 | ################################################################################ |
---|
2495 | ##### PlotIntegration |
---|
2496 | ################################################################################ |
---|
2497 | |
---|
2498 | def PlotIntegration(G2frame,newPlot=False,event=None): |
---|
2499 | '''Plot of 2D image after image integration with 2-theta and azimuth as coordinates |
---|
2500 | ''' |
---|
2501 | |
---|
2502 | def OnMotion(event): |
---|
2503 | Page.canvas.SetToolTipString('') |
---|
2504 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
2505 | azm = event.ydata |
---|
2506 | tth = event.xdata |
---|
2507 | if azm and tth: |
---|
2508 | G2frame.G2plotNB.status.SetFields(\ |
---|
2509 | ['','Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm)]) |
---|
2510 | |
---|
2511 | try: |
---|
2512 | plotNum = G2frame.G2plotNB.plotList.index('2D Integration') |
---|
2513 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
2514 | if not newPlot: |
---|
2515 | Plot = Page.figure.gca() #get previous plot & get limits |
---|
2516 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
2517 | Page.figure.clf() |
---|
2518 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
2519 | |
---|
2520 | except ValueError: |
---|
2521 | Plot = G2frame.G2plotNB.addMpl('2D Integration').gca() |
---|
2522 | plotNum = G2frame.G2plotNB.plotList.index('2D Integration') |
---|
2523 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
2524 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
2525 | Page.views = False |
---|
2526 | view = False |
---|
2527 | Page.Choice = None |
---|
2528 | if not event: |
---|
2529 | Page.SetFocus() |
---|
2530 | |
---|
2531 | Data = G2frame.PatternTree.GetItemPyData( |
---|
2532 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls')) |
---|
2533 | image = G2frame.Integrate[0] |
---|
2534 | xsc = G2frame.Integrate[1] |
---|
2535 | ysc = G2frame.Integrate[2] |
---|
2536 | Imin,Imax = Data['range'][1] |
---|
2537 | acolor = mpl.cm.get_cmap(Data['color']) |
---|
2538 | Plot.set_title(G2frame.PatternTree.GetItemText(G2frame.Image)[4:]) |
---|
2539 | Plot.set_ylabel('azimuth',fontsize=12) |
---|
2540 | Plot.set_xlabel('2-theta',fontsize=12) |
---|
2541 | Img = Plot.imshow(image,cmap=acolor,vmin=Imin,vmax=Imax,interpolation='nearest', \ |
---|
2542 | extent=[ysc[0],ysc[-1],xsc[-1],xsc[0]],aspect='auto') |
---|
2543 | colorBar = Page.figure.colorbar(Img) |
---|
2544 | if Data['ellipses']: |
---|
2545 | for ellipse in Data['ellipses']: |
---|
2546 | ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color |
---|
2547 | x,y = np.hsplit(ring,2) |
---|
2548 | tth,azm = G2img.GetTthAzm(x,y,Data) |
---|
2549 | # azm = np.where(azm < 0.,azm+360,azm) |
---|
2550 | Plot.plot(tth,azm,'b,') |
---|
2551 | if not newPlot: |
---|
2552 | Page.toolbar.push_current() |
---|
2553 | Plot.set_xlim(xylim[0]) |
---|
2554 | Plot.set_ylim(xylim[1]) |
---|
2555 | xylim = [] |
---|
2556 | Page.toolbar.push_current() |
---|
2557 | Page.toolbar.draw() |
---|
2558 | else: |
---|
2559 | Page.canvas.draw() |
---|
2560 | |
---|
2561 | ################################################################################ |
---|
2562 | ##### PlotTRImage |
---|
2563 | ################################################################################ |
---|
2564 | |
---|
2565 | def PlotTRImage(G2frame,tax,tay,taz,newPlot=False): |
---|
2566 | '''a test plot routine - not normally used |
---|
2567 | ''' |
---|
2568 | |
---|
2569 | def OnMotion(event): |
---|
2570 | Page.canvas.SetToolTipString('') |
---|
2571 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
2572 | azm = event.xdata |
---|
2573 | tth = event.ydata |
---|
2574 | if azm and tth: |
---|
2575 | G2frame.G2plotNB.status.SetFields(\ |
---|
2576 | ['','Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm)]) |
---|
2577 | |
---|
2578 | try: |
---|
2579 | plotNum = G2frame.G2plotNB.plotList.index('2D Transformed Powder Image') |
---|
2580 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
2581 | if not newPlot: |
---|
2582 | Plot = Page.figure.gca() #get previous plot & get limits |
---|
2583 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
2584 | Page.figure.clf() |
---|
2585 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
2586 | |
---|
2587 | except ValueError: |
---|
2588 | Plot = G2frame.G2plotNB.addMpl('2D Transformed Powder Image').gca() |
---|
2589 | plotNum = G2frame.G2plotNB.plotList.index('2D Transformed Powder Image') |
---|
2590 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
2591 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
2592 | Page.views = False |
---|
2593 | view = False |
---|
2594 | Page.Choice = None |
---|
2595 | Page.SetFocus() |
---|
2596 | |
---|
2597 | Data = G2frame.PatternTree.GetItemPyData( |
---|
2598 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls')) |
---|
2599 | Imin,Imax = Data['range'][1] |
---|
2600 | step = (Imax-Imin)/5. |
---|
2601 | V = np.arange(Imin,Imax,step) |
---|
2602 | acolor = mpl.cm.get_cmap(Data['color']) |
---|
2603 | Plot.set_title(G2frame.PatternTree.GetItemText(G2frame.Image)[4:]) |
---|
2604 | Plot.set_xlabel('azimuth',fontsize=12) |
---|
2605 | Plot.set_ylabel('2-theta',fontsize=12) |
---|
2606 | Plot.contour(tax,tay,taz,V,cmap=acolor) |
---|
2607 | if Data['showLines']: |
---|
2608 | IOtth = Data['IOtth'] |
---|
2609 | if Data['fullIntegrate']: |
---|
2610 | LRAzim = [-180,180] |
---|
2611 | else: |
---|
2612 | LRAzim = Data['LRazimuth'] #NB: integers |
---|
2613 | Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[0],IOtth[0]],picker=True) |
---|
2614 | Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[1],IOtth[1]],picker=True) |
---|
2615 | if not Data['fullIntegrate']: |
---|
2616 | Plot.plot([LRAzim[0],LRAzim[0]],[IOtth[0],IOtth[1]],picker=True) |
---|
2617 | Plot.plot([LRAzim[1],LRAzim[1]],[IOtth[0],IOtth[1]],picker=True) |
---|
2618 | if Data['setRings']: |
---|
2619 | rings = np.concatenate((Data['rings']),axis=0) |
---|
2620 | for xring,yring,dsp in rings: |
---|
2621 | x,y = G2img.GetTthAzm(xring,yring,Data) |
---|
2622 | Plot.plot(y,x,'r+') |
---|
2623 | if Data['ellipses']: |
---|
2624 | for ellipse in Data['ellipses']: |
---|
2625 | ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color |
---|
2626 | x,y = np.hsplit(ring,2) |
---|
2627 | tth,azm = G2img.GetTthAzm(x,y,Data) |
---|
2628 | Plot.plot(azm,tth,'b,') |
---|
2629 | if not newPlot: |
---|
2630 | Page.toolbar.push_current() |
---|
2631 | Plot.set_xlim(xylim[0]) |
---|
2632 | Plot.set_ylim(xylim[1]) |
---|
2633 | xylim = [] |
---|
2634 | Page.toolbar.push_current() |
---|
2635 | Page.toolbar.draw() |
---|
2636 | else: |
---|
2637 | Page.canvas.draw() |
---|
2638 | |
---|
2639 | ################################################################################ |
---|
2640 | ##### PlotStructure |
---|
2641 | ################################################################################ |
---|
2642 | |
---|
2643 | def PlotStructure(G2frame,data): |
---|
2644 | '''Crystal structure plotting package. Can show structures as balls, sticks, lines, |
---|
2645 | thermal motion ellipsoids and polyhedra |
---|
2646 | ''' |
---|
2647 | |
---|
2648 | def FindPeaksBonds(XYZ): |
---|
2649 | rFact = data['Drawing']['radiusFactor'] |
---|
2650 | Bonds = [[] for x in XYZ] |
---|
2651 | for i,xyz in enumerate(XYZ): |
---|
2652 | Dx = XYZ-xyz |
---|
2653 | dist = np.sqrt(np.sum(np.inner(Dx,Amat)**2,axis=1)) |
---|
2654 | IndB = ma.nonzero(ma.masked_greater(dist,rFact*2.2)) |
---|
2655 | for j in IndB[0]: |
---|
2656 | Bonds[i].append(Dx[j]/2.) |
---|
2657 | Bonds[j].append(-Dx[j]/2.) |
---|
2658 | return Bonds |
---|
2659 | |
---|
2660 | ForthirdPI = 4.0*math.pi/3.0 |
---|
2661 | generalData = data['General'] |
---|
2662 | cell = generalData['Cell'][1:7] |
---|
2663 | Vol = generalData['Cell'][7:8][0] |
---|
2664 | Amat,Bmat = G2lat.cell2AB(cell) #Amat - crystal to cartesian, Bmat - inverse |
---|
2665 | Gmat,gmat = G2lat.cell2Gmat(cell) |
---|
2666 | A4mat = np.concatenate((np.concatenate((Amat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
2667 | B4mat = np.concatenate((np.concatenate((Bmat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
2668 | SGData = generalData['SGData'] |
---|
2669 | Mydir = generalData['Mydir'] |
---|
2670 | atomData = data['Atoms'] |
---|
2671 | mapPeaks = [] |
---|
2672 | drawingData = data['Drawing'] |
---|
2673 | if 'Map Peaks' in data: |
---|
2674 | mapPeaks = np.array(data['Map Peaks']) |
---|
2675 | peakMax = 100. |
---|
2676 | if len(mapPeaks): |
---|
2677 | peakMax = np.max(mapPeaks.T[0]) |
---|
2678 | resRBData = data['RBModels'].get('Residue',[]) |
---|
2679 | vecRBData = data['RBModels'].get('Vector',[]) |
---|
2680 | rbAtmDict = {} |
---|
2681 | for rbObj in resRBData+vecRBData: |
---|
2682 | exclList = ['X' for i in range(len(rbObj['Ids']))] |
---|
2683 | rbAtmDict.update(dict(zip(rbObj['Ids'],exclList))) |
---|
2684 | testRBObj = data.get('testRBObj',{}) |
---|
2685 | rbObj = testRBObj.get('rbObj',{}) |
---|
2686 | MCSA = data.get('MCSA',{}) |
---|
2687 | mcsaModels = MCSA.get('Models',[]) |
---|
2688 | if mcsaModels: |
---|
2689 | XYZs,Types = G2mth.UpdateMCSAxyz(Bmat,MCSA) |
---|
2690 | mcsaXYZ = [] |
---|
2691 | mcsaTypes = [] |
---|
2692 | for xyz,atyp in zip(XYZs,Types): |
---|
2693 | for item in G2spc.GenAtom(xyz,SGData): |
---|
2694 | mcsaXYZ.append(item[0]) |
---|
2695 | mcsaTypes.append(atyp) |
---|
2696 | mcsaBonds = FindPeaksBonds(mcsaXYZ) |
---|
2697 | # mcsaXYZ,atTypes = G2mth.UpdateMCSAxyz(Bmat,MCSA) |
---|
2698 | # XYZeq = [] |
---|
2699 | # for xyz in mcsaXYZ: |
---|
2700 | # XYZeq += G2spc.GenAtom(xyz,SGData)[0][1:] #skip self xyz |
---|
2701 | # |
---|
2702 | # mcsaBonds = FindPeaksBonds(mcsaXYZ) |
---|
2703 | drawAtoms = drawingData.get('Atoms',[]) |
---|
2704 | mapData = {} |
---|
2705 | flipData = {} |
---|
2706 | rhoXYZ = [] |
---|
2707 | showBonds = False |
---|
2708 | if 'Map' in generalData: |
---|
2709 | mapData = generalData['Map'] |
---|
2710 | showBonds = mapData.get('Show bonds',False) |
---|
2711 | if 'Flip' in generalData: |
---|
2712 | flipData = generalData['Flip'] |
---|
2713 | flipData['mapRoll'] = [0,0,0] |
---|
2714 | Wt = np.array([255,255,255]) |
---|
2715 | Rd = np.array([255,0,0]) |
---|
2716 | Gr = np.array([0,255,0]) |
---|
2717 | wxGreen = wx.Color(0,255,0) |
---|
2718 | Bl = np.array([0,0,255]) |
---|
2719 | Or = np.array([255,128,0]) |
---|
2720 | wxOrange = wx.Color(255,128,0) |
---|
2721 | uBox = np.array([[0,0,0],[1,0,0],[1,1,0],[0,1,0],[0,0,1],[1,0,1],[1,1,1],[0,1,1]]) |
---|
2722 | uEdges = np.array([ |
---|
2723 | [uBox[0],uBox[1]],[uBox[0],uBox[3]],[uBox[0],uBox[4]],[uBox[1],uBox[2]], |
---|
2724 | [uBox[2],uBox[3]],[uBox[1],uBox[5]],[uBox[2],uBox[6]],[uBox[3],uBox[7]], |
---|
2725 | [uBox[4],uBox[5]],[uBox[5],uBox[6]],[uBox[6],uBox[7]],[uBox[7],uBox[4]]]) |
---|
2726 | mD = 0.1 |
---|
2727 | mV = np.array([[[-mD,0,0],[mD,0,0]],[[0,-mD,0],[0,mD,0]],[[0,0,-mD],[0,0,mD]]]) |
---|
2728 | mapPeakVecs = np.inner(mV,Bmat) |
---|
2729 | |
---|
2730 | uColors = [Rd,Gr,Bl,Wt, Wt,Wt,Wt,Wt, Wt,Wt,Wt,Wt] |
---|
2731 | altDown = False |
---|
2732 | shiftDown = False |
---|
2733 | ctrlDown = False |
---|
2734 | |
---|
2735 | def OnKeyBox(event): |
---|
2736 | import Image |
---|
2737 | # Draw() #make sure plot is fresh!! |
---|
2738 | mode = cb.GetValue() |
---|
2739 | if mode in ['jpeg','bmp','tiff',]: |
---|
2740 | Fname = os.path.join(Mydir,generalData['Name']+'.'+mode) |
---|
2741 | size = Page.canvas.GetSize() |
---|
2742 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1) |
---|
2743 | if mode in ['jpeg',]: |
---|
2744 | Pix = glReadPixels(0,0,size[0],size[1],GL_RGBA, GL_UNSIGNED_BYTE) |
---|
2745 | im = Image.new("RGBA", (size[0],size[1])) |
---|
2746 | else: |
---|
2747 | Pix = glReadPixels(0,0,size[0],size[1],GL_RGB, GL_UNSIGNED_BYTE) |
---|
2748 | im = Image.new("RGB", (size[0],size[1])) |
---|
2749 | im.fromstring(Pix) |
---|
2750 | im.save(Fname,mode) |
---|
2751 | cb.SetValue(' save as/key:') |
---|
2752 | G2frame.G2plotNB.status.SetStatusText('Drawing saved to: '+Fname,1) |
---|
2753 | else: |
---|
2754 | event.key = cb.GetValue()[0] |
---|
2755 | cb.SetValue(' save as/key:') |
---|
2756 | wx.CallAfter(OnKey,event) |
---|
2757 | Page.canvas.SetFocus() # redirect the Focus from the button back to the plot |
---|
2758 | |
---|
2759 | def OnKey(event): #on key UP!! |
---|
2760 | # Draw() #make sure plot is fresh!! |
---|
2761 | try: |
---|
2762 | keyCode = event.GetKeyCode() |
---|
2763 | if keyCode > 255: |
---|
2764 | keyCode = 0 |
---|
2765 | key = chr(keyCode) |
---|
2766 | except AttributeError: #if from OnKeyBox above |
---|
2767 | key = str(event.key).upper() |
---|
2768 | indx = drawingData['selectedAtoms'] |
---|
2769 | cx,ct = drawingData['atomPtrs'][:2] |
---|
2770 | if key in ['C']: |
---|
2771 | drawingData['viewPoint'] = [[.5,.5,.5],[0,0]] |
---|
2772 | drawingData['viewDir'] = [0,0,1] |
---|
2773 | drawingData['oldxy'] = [] |
---|
2774 | V0 = np.array([0,0,1]) |
---|
2775 | V = np.inner(Amat,V0) |
---|
2776 | V /= np.sqrt(np.sum(V**2)) |
---|
2777 | A = np.arccos(np.sum(V*V0)) |
---|
2778 | Q = G2mth.AV2Q(A,[0,1,0]) |
---|
2779 | drawingData['Quaternion'] = Q |
---|
2780 | SetViewPointText(drawingData['viewPoint'][0]) |
---|
2781 | SetViewDirText(drawingData['viewDir']) |
---|
2782 | Q = drawingData['Quaternion'] |
---|
2783 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
2784 | elif key in ['N']: |
---|
2785 | drawAtoms = drawingData['Atoms'] |
---|
2786 | if not len(drawAtoms): #no atoms |
---|
2787 | return |
---|
2788 | pI = drawingData['viewPoint'][1] |
---|
2789 | if not len(pI): |
---|
2790 | pI = [0,0] |
---|
2791 | if indx: |
---|
2792 | pI[0] = indx[pI[1]] |
---|
2793 | Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3] |
---|
2794 | pI[1] += 1 |
---|
2795 | if pI[1] >= len(indx): |
---|
2796 | pI[1] = 0 |
---|
2797 | else: |
---|
2798 | Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3] |
---|
2799 | pI[0] += 1 |
---|
2800 | if pI[0] >= len(drawAtoms): |
---|
2801 | pI[0] = 0 |
---|
2802 | drawingData['viewPoint'] = [[Tx,Ty,Tz],pI] |
---|
2803 | SetViewPointText(drawingData['viewPoint'][0]) |
---|
2804 | G2frame.G2plotNB.status.SetStatusText('View point at atom '+drawAtoms[pI[0]][ct-1]+str(pI),1) |
---|
2805 | |
---|
2806 | elif key in ['P']: |
---|
2807 | drawAtoms = drawingData['Atoms'] |
---|
2808 | if not len(drawAtoms): #no atoms |
---|
2809 | return |
---|
2810 | pI = drawingData['viewPoint'][1] |
---|
2811 | if not len(pI): |
---|
2812 | pI = [0,0] |
---|
2813 | if indx: |
---|
2814 | pI[0] = indx[pI[1]] |
---|
2815 | Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3] |
---|
2816 | pI[1] -= 1 |
---|
2817 | if pI[1] < 0: |
---|
2818 | pI[1] = len(indx)-1 |
---|
2819 | else: |
---|
2820 | Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3] |
---|
2821 | pI[0] -= 1 |
---|
2822 | if pI[0] < 0: |
---|
2823 | pI[0] = len(drawAtoms)-1 |
---|
2824 | drawingData['viewPoint'] = [[Tx,Ty,Tz],pI] |
---|
2825 | SetViewPointText(drawingData['viewPoint'][0]) |
---|
2826 | G2frame.G2plotNB.status.SetStatusText('View point at atom '+drawAtoms[pI[0]][ct-1]+str(pI),1) |
---|
2827 | elif key in ['U','D','L','R'] and mapData['Flip'] == True: |
---|
2828 | dirDict = {'U':[0,1],'D':[0,-1],'L':[-1,0],'R':[1,0]} |
---|
2829 | SetMapRoll(dirDict[key]) |
---|
2830 | SetPeakRoll(dirDict[key]) |
---|
2831 | SetMapPeaksText(mapPeaks) |
---|
2832 | Draw('key') |
---|
2833 | |
---|
2834 | def GetTruePosition(xy,Add=False): |
---|
2835 | View = glGetIntegerv(GL_VIEWPORT) |
---|
2836 | Proj = glGetDoublev(GL_PROJECTION_MATRIX) |
---|
2837 | Model = glGetDoublev(GL_MODELVIEW_MATRIX) |
---|
2838 | Zmax = 1. |
---|
2839 | if Add: |
---|
2840 | Indx = GetSelectedAtoms() |
---|
2841 | if G2frame.dataDisplay.GetPageText(getSelection()) == 'Map peaks': |
---|
2842 | for i,peak in enumerate(mapPeaks): |
---|
2843 | x,y,z = peak[1:4] |
---|
2844 | X,Y,Z = gluProject(x,y,z,Model,Proj,View) |
---|
2845 | XY = [int(X),int(View[3]-Y)] |
---|
2846 | if np.allclose(xy,XY,atol=10) and Z < Zmax: |
---|
2847 | Zmax = Z |
---|
2848 | try: |
---|
2849 | Indx.remove(i) |
---|
2850 | ClearSelectedAtoms() |
---|
2851 | for id in Indx: |
---|
2852 | SetSelectedAtoms(id,Add) |
---|
2853 | except: |
---|
2854 | SetSelectedAtoms(i,Add) |
---|
2855 | else: |
---|
2856 | cx = drawingData['atomPtrs'][0] |
---|
2857 | for i,atom in enumerate(drawAtoms): |
---|
2858 | x,y,z = atom[cx:cx+3] |
---|
2859 | X,Y,Z = gluProject(x,y,z,Model,Proj,View) |
---|
2860 | XY = [int(X),int(View[3]-Y)] |
---|
2861 | if np.allclose(xy,XY,atol=10) and Z < Zmax: |
---|
2862 | Zmax = Z |
---|
2863 | try: |
---|
2864 | Indx.remove(i) |
---|
2865 | ClearSelectedAtoms() |
---|
2866 | for id in Indx: |
---|
2867 | SetSelectedAtoms(id,Add) |
---|
2868 | except: |
---|
2869 | SetSelectedAtoms(i,Add) |
---|
2870 | |
---|
2871 | def OnMouseDown(event): |
---|
2872 | xy = event.GetPosition() |
---|
2873 | if event.ShiftDown(): |
---|
2874 | if event.LeftIsDown(): |
---|
2875 | GetTruePosition(xy) |
---|
2876 | elif event.RightIsDown(): |
---|
2877 | GetTruePosition(xy,True) |
---|
2878 | else: |
---|
2879 | drawingData['oldxy'] = list(xy) |
---|
2880 | |
---|
2881 | def OnMouseMove(event): |
---|
2882 | if event.ShiftDown(): #don't want any inadvertant moves when picking |
---|
2883 | return |
---|
2884 | newxy = event.GetPosition() |
---|
2885 | |
---|
2886 | if event.Dragging(): |
---|
2887 | if event.AltDown() and rbObj: |
---|
2888 | if event.LeftIsDown(): |
---|
2889 | SetRBRotation(newxy) |
---|
2890 | Q = rbObj['Orient'][0] |
---|
2891 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
2892 | elif event.RightIsDown(): |
---|
2893 | SetRBTranslation(newxy) |
---|
2894 | Tx,Ty,Tz = rbObj['Orig'][0] |
---|
2895 | G2frame.G2plotNB.status.SetStatusText('New view point: %.4f, %.4f, %.4f'%(Tx,Ty,Tz),1) |
---|
2896 | elif event.MiddleIsDown(): |
---|
2897 | SetRBRotationZ(newxy) |
---|
2898 | Q = rbObj['Orient'][0] |
---|
2899 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
2900 | Draw('move') |
---|
2901 | elif not event.ControlDown(): |
---|
2902 | if event.LeftIsDown(): |
---|
2903 | SetRotation(newxy) |
---|
2904 | Q = drawingData['Quaternion'] |
---|
2905 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
2906 | elif event.RightIsDown(): |
---|
2907 | SetTranslation(newxy) |
---|
2908 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
2909 | G2frame.G2plotNB.status.SetStatusText('New view point: %.4f, %.4f, %.4f'%(Tx,Ty,Tz),1) |
---|
2910 | elif event.MiddleIsDown(): |
---|
2911 | SetRotationZ(newxy) |
---|
2912 | Q = drawingData['Quaternion'] |
---|
2913 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
2914 | Draw('move') |
---|
2915 | |
---|
2916 | |
---|
2917 | def OnMouseWheel(event): |
---|
2918 | if event.ShiftDown(): |
---|
2919 | return |
---|
2920 | drawingData['cameraPos'] += event.GetWheelRotation()/24. |
---|
2921 | drawingData['cameraPos'] = max(10,min(500,drawingData['cameraPos'])) |
---|
2922 | G2frame.G2plotNB.status.SetStatusText('New camera distance: %.2f'%(drawingData['cameraPos']),1) |
---|
2923 | page = getSelection() |
---|
2924 | if page: |
---|
2925 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Options': |
---|
2926 | G2frame.dataDisplay.cameraPosTxt.SetLabel('Camera Position: '+'%.2f'%(drawingData['cameraPos'])) |
---|
2927 | G2frame.dataDisplay.cameraSlider.SetValue(drawingData['cameraPos']) |
---|
2928 | Draw('wheel') |
---|
2929 | |
---|
2930 | def getSelection(): |
---|
2931 | try: |
---|
2932 | return G2frame.dataDisplay.GetSelection() |
---|
2933 | except AttributeError: |
---|
2934 | G2frame.G2plotNB.status.SetStatusText('Select this from Phase data window!') |
---|
2935 | return 0 |
---|
2936 | |
---|
2937 | def SetViewPointText(VP): |
---|
2938 | page = getSelection() |
---|
2939 | if page: |
---|
2940 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Options': |
---|
2941 | G2frame.dataDisplay.viewPoint.SetValue('%.3f %.3f %.3f'%(VP[0],VP[1],VP[2])) |
---|
2942 | |
---|
2943 | def SetRBOrigText(): |
---|
2944 | page = getSelection() |
---|
2945 | if page: |
---|
2946 | if G2frame.dataDisplay.GetPageText(page) == 'RB Models': |
---|
2947 | for i,sizer in enumerate(testRBObj['Sizers']['Xsizers']): |
---|
2948 | sizer.SetValue('%8.5f'%(testRBObj['rbObj']['Orig'][0][i])) |
---|
2949 | |
---|
2950 | def SetRBOrienText(): |
---|
2951 | page = getSelection() |
---|
2952 | if page: |
---|
2953 | if G2frame.dataDisplay.GetPageText(page) == 'RB Models': |
---|
2954 | for i,sizer in enumerate(testRBObj['Sizers']['Osizers']): |
---|
2955 | sizer.SetValue('%8.5f'%(testRBObj['rbObj']['Orient'][0][i])) |
---|
2956 | |
---|
2957 | def SetViewDirText(VD): |
---|
2958 | page = getSelection() |
---|
2959 | if page: |
---|
2960 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Options': |
---|
2961 | G2frame.dataDisplay.viewDir.SetValue('%.3f %.3f %.3f'%(VD[0],VD[1],VD[2])) |
---|
2962 | |
---|
2963 | def SetMapPeaksText(mapPeaks): |
---|
2964 | page = getSelection() |
---|
2965 | if page: |
---|
2966 | if G2frame.dataDisplay.GetPageText(page) == 'Map peaks': |
---|
2967 | G2frame.MapPeaksTable.SetData(mapPeaks) |
---|
2968 | panel = G2frame.dataDisplay.GetPage(page).GetChildren() |
---|
2969 | names = [child.GetName() for child in panel] |
---|
2970 | panel[names.index('grid window')].Refresh() |
---|
2971 | |
---|
2972 | def ClearSelectedAtoms(): |
---|
2973 | page = getSelection() |
---|
2974 | if page: |
---|
2975 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms': |
---|
2976 | G2frame.dataDisplay.GetPage(page).ClearSelection() #this is the Atoms grid in Draw Atoms |
---|
2977 | elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks': |
---|
2978 | G2frame.dataDisplay.GetPage(page).ClearSelection() #this is the Atoms grid in Atoms |
---|
2979 | elif G2frame.dataDisplay.GetPageText(page) == 'Atoms': |
---|
2980 | G2frame.dataDisplay.GetPage(page).ClearSelection() #this is the Atoms grid in Atoms |
---|
2981 | |
---|
2982 | |
---|
2983 | def SetSelectedAtoms(ind,Add=False): |
---|
2984 | page = getSelection() |
---|
2985 | if page: |
---|
2986 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms': |
---|
2987 | G2frame.dataDisplay.GetPage(page).SelectRow(ind,Add) #this is the Atoms grid in Draw Atoms |
---|
2988 | elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks': |
---|
2989 | G2frame.dataDisplay.GetPage(page).SelectRow(ind,Add) |
---|
2990 | elif G2frame.dataDisplay.GetPageText(page) == 'Atoms': |
---|
2991 | Id = drawAtoms[ind][-3] |
---|
2992 | for i,atom in enumerate(atomData): |
---|
2993 | if atom[-1] == Id: |
---|
2994 | G2frame.dataDisplay.GetPage(page).SelectRow(i) #this is the Atoms grid in Atoms |
---|
2995 | |
---|
2996 | def GetSelectedAtoms(): |
---|
2997 | page = getSelection() |
---|
2998 | Ind = [] |
---|
2999 | if page: |
---|
3000 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms': |
---|
3001 | Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows() #this is the Atoms grid in Draw Atoms |
---|
3002 | elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks': |
---|
3003 | Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows() |
---|
3004 | elif G2frame.dataDisplay.GetPageText(page) == 'Atoms': |
---|
3005 | Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows() #this is the Atoms grid in Atoms |
---|
3006 | return Ind |
---|
3007 | |
---|
3008 | def SetBackground(): |
---|
3009 | R,G,B,A = Page.camera['backColor'] |
---|
3010 | glClearColor(R,G,B,A) |
---|
3011 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
---|
3012 | |
---|
3013 | def SetLights(): |
---|
3014 | glEnable(GL_DEPTH_TEST) |
---|
3015 | glShadeModel(GL_SMOOTH) |
---|
3016 | glEnable(GL_LIGHTING) |
---|
3017 | glEnable(GL_LIGHT0) |
---|
3018 | glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0) |
---|
3019 | glLightfv(GL_LIGHT0,GL_AMBIENT,[1,1,1,.8]) |
---|
3020 | glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1]) |
---|
3021 | |
---|
3022 | def GetRoll(newxy,rho): |
---|
3023 | Q = drawingData['Quaternion'] |
---|
3024 | dxy = G2mth.prodQVQ(G2mth.invQ(Q),np.inner(Bmat,newxy+[0,])) |
---|
3025 | dxy = np.array(dxy*rho.shape) |
---|
3026 | roll = np.where(dxy>0.5,1,np.where(dxy<-.5,-1,0)) |
---|
3027 | return roll |
---|
3028 | |
---|
3029 | def SetMapRoll(newxy): |
---|
3030 | rho = mapData['rho'] |
---|
3031 | roll = GetRoll(newxy,rho) |
---|
3032 | mapData['rho'] = np.roll(np.roll(np.roll(rho,roll[0],axis=0),roll[1],axis=1),roll[2],axis=2) |
---|
3033 | drawingData['oldxy'] = list(newxy) |
---|
3034 | |
---|
3035 | def SetPeakRoll(newxy): |
---|
3036 | rho = mapData['rho'] |
---|
3037 | roll = GetRoll(newxy,rho) |
---|
3038 | steps = 1./np.array(rho.shape) |
---|
3039 | dxy = roll*steps |
---|
3040 | for peak in mapPeaks: |
---|
3041 | peak[1:4] += dxy |
---|
3042 | peak[1:4] %= 1. |
---|
3043 | peak[4] = np.sqrt(np.sum(np.inner(Amat,peak[1:4])**2)) |
---|
3044 | |
---|
3045 | def SetTranslation(newxy): |
---|
3046 | #first get translation vector in screen coords. |
---|
3047 | oldxy = drawingData['oldxy'] |
---|
3048 | if not len(oldxy): oldxy = list(newxy) |
---|
3049 | dxy = newxy-oldxy |
---|
3050 | drawingData['oldxy'] = list(newxy) |
---|
3051 | V = np.array([-dxy[0],dxy[1],0.]) |
---|
3052 | #then transform to rotated crystal coordinates & apply to view point |
---|
3053 | Q = drawingData['Quaternion'] |
---|
3054 | V = np.inner(Bmat,G2mth.prodQVQ(G2mth.invQ(Q),V)) |
---|
3055 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
3056 | Tx += V[0]*0.01 |
---|
3057 | Ty += V[1]*0.01 |
---|
3058 | Tz += V[2]*0.01 |
---|
3059 | drawingData['viewPoint'][0] = Tx,Ty,Tz |
---|
3060 | SetViewPointText([Tx,Ty,Tz]) |
---|
3061 | |
---|
3062 | def SetRBTranslation(newxy): |
---|
3063 | #first get translation vector in screen coords. |
---|
3064 | oldxy = drawingData['oldxy'] |
---|
3065 | if not len(oldxy): oldxy = list(newxy) |
---|
3066 | dxy = newxy-oldxy |
---|
3067 | drawingData['oldxy'] = list(newxy) |
---|
3068 | V = np.array([-dxy[0],dxy[1],0.]) |
---|
3069 | #then transform to rotated crystal coordinates & apply to RB origin |
---|
3070 | Q = drawingData['Quaternion'] |
---|
3071 | V = np.inner(Bmat,G2mth.prodQVQ(G2mth.invQ(Q),V)) |
---|
3072 | Tx,Ty,Tz = rbObj['Orig'][0] |
---|
3073 | Tx -= V[0]*0.01 |
---|
3074 | Ty -= V[1]*0.01 |
---|
3075 | Tz -= V[2]*0.01 |
---|
3076 | rbObj['Orig'][0] = Tx,Ty,Tz |
---|
3077 | SetRBOrigText() |
---|
3078 | |
---|
3079 | def SetRotation(newxy): |
---|
3080 | #first get rotation vector in screen coords. & angle increment |
---|
3081 | oldxy = drawingData['oldxy'] |
---|
3082 | if not len(oldxy): oldxy = list(newxy) |
---|
3083 | dxy = newxy-oldxy |
---|
3084 | drawingData['oldxy'] = list(newxy) |
---|
3085 | V = np.array([dxy[1],dxy[0],0.]) |
---|
3086 | A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2) |
---|
3087 | # next transform vector back to xtal coordinates via inverse quaternion |
---|
3088 | # & make new quaternion |
---|
3089 | Q = drawingData['Quaternion'] |
---|
3090 | V = G2mth.prodQVQ(G2mth.invQ(Q),np.inner(Bmat,V)) |
---|
3091 | DQ = G2mth.AVdeg2Q(A,V) |
---|
3092 | Q = G2mth.prodQQ(Q,DQ) |
---|
3093 | drawingData['Quaternion'] = Q |
---|
3094 | # finally get new view vector - last row of rotation matrix |
---|
3095 | VD = np.inner(Bmat,G2mth.Q2Mat(Q)[2]) |
---|
3096 | VD /= np.sqrt(np.sum(VD**2)) |
---|
3097 | drawingData['viewDir'] = VD |
---|
3098 | SetViewDirText(VD) |
---|
3099 | |
---|
3100 | def SetRotationZ(newxy): |
---|
3101 | #first get rotation vector (= view vector) in screen coords. & angle increment |
---|
3102 | View = glGetIntegerv(GL_VIEWPORT) |
---|
3103 | cent = [View[2]/2,View[3]/2] |
---|
3104 | oldxy = drawingData['oldxy'] |
---|
3105 | if not len(oldxy): oldxy = list(newxy) |
---|
3106 | dxy = newxy-oldxy |
---|
3107 | drawingData['oldxy'] = list(newxy) |
---|
3108 | V = drawingData['viewDir'] |
---|
3109 | A = [0,0] |
---|
3110 | A[0] = dxy[1]*.25 |
---|
3111 | A[1] = dxy[0]*.25 |
---|
3112 | if newxy[0] > cent[0]: |
---|
3113 | A[0] *= -1 |
---|
3114 | if newxy[1] < cent[1]: |
---|
3115 | A[1] *= -1 |
---|
3116 | # next transform vector back to xtal coordinates & make new quaternion |
---|
3117 | Q = drawingData['Quaternion'] |
---|
3118 | V = np.inner(Amat,V) |
---|
3119 | Qx = G2mth.AVdeg2Q(A[0],V) |
---|
3120 | Qy = G2mth.AVdeg2Q(A[1],V) |
---|
3121 | Q = G2mth.prodQQ(Q,Qx) |
---|
3122 | Q = G2mth.prodQQ(Q,Qy) |
---|
3123 | drawingData['Quaternion'] = Q |
---|
3124 | |
---|
3125 | def SetRBRotation(newxy): |
---|
3126 | #first get rotation vector in screen coords. & angle increment |
---|
3127 | oldxy = drawingData['oldxy'] |
---|
3128 | if not len(oldxy): oldxy = list(newxy) |
---|
3129 | dxy = newxy-oldxy |
---|
3130 | drawingData['oldxy'] = list(newxy) |
---|
3131 | V = np.array([dxy[1],dxy[0],0.]) |
---|
3132 | A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2) |
---|
3133 | # next transform vector back to xtal coordinates via inverse quaternion |
---|
3134 | # & make new quaternion |
---|
3135 | Q = rbObj['Orient'][0] #rotate RB to Cart |
---|
3136 | QC = drawingData['Quaternion'] #rotate Cart to drawing |
---|
3137 | V = G2mth.prodQVQ(G2mth.invQ(QC),V) |
---|
3138 | V = G2mth.prodQVQ(G2mth.invQ(Q),V) |
---|
3139 | DQ = G2mth.AVdeg2Q(A,V) |
---|
3140 | Q = G2mth.prodQQ(Q,DQ) |
---|
3141 | rbObj['Orient'][0] = Q |
---|
3142 | SetRBOrienText() |
---|
3143 | |
---|
3144 | def SetRBRotationZ(newxy): |
---|
3145 | #first get rotation vector (= view vector) in screen coords. & angle increment |
---|
3146 | View = glGetIntegerv(GL_VIEWPORT) |
---|
3147 | cent = [View[2]/2,View[3]/2] |
---|
3148 | oldxy = drawingData['oldxy'] |
---|
3149 | if not len(oldxy): oldxy = list(newxy) |
---|
3150 | dxy = newxy-oldxy |
---|
3151 | drawingData['oldxy'] = list(newxy) |
---|
3152 | V = drawingData['viewDir'] |
---|
3153 | A = [0,0] |
---|
3154 | A[0] = dxy[1]*.25 |
---|
3155 | A[1] = dxy[0]*.25 |
---|
3156 | if newxy[0] < cent[0]: |
---|
3157 | A[0] *= -1 |
---|
3158 | if newxy[1] > cent[1]: |
---|
3159 | A[1] *= -1 |
---|
3160 | # next transform vector back to RB coordinates & make new quaternion |
---|
3161 | Q = rbObj['Orient'][0] #rotate RB to cart |
---|
3162 | V = np.inner(Amat,V) |
---|
3163 | V = -G2mth.prodQVQ(G2mth.invQ(Q),V) |
---|
3164 | Qx = G2mth.AVdeg2Q(A[0],V) |
---|
3165 | Qy = G2mth.AVdeg2Q(A[1],V) |
---|
3166 | Q = G2mth.prodQQ(Q,Qx) |
---|
3167 | Q = G2mth.prodQQ(Q,Qy) |
---|
3168 | rbObj['Orient'][0] = Q |
---|
3169 | SetRBOrienText() |
---|
3170 | |
---|
3171 | def RenderBox(): |
---|
3172 | glEnable(GL_COLOR_MATERIAL) |
---|
3173 | glLineWidth(2) |
---|
3174 | glEnable(GL_BLEND) |
---|
3175 | glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) |
---|
3176 | glEnable(GL_LINE_SMOOTH) |
---|
3177 | glBegin(GL_LINES) |
---|
3178 | for line,color in zip(uEdges,uColors): |
---|
3179 | glColor3ubv(color) |
---|
3180 | glVertex3fv(line[0]) |
---|
3181 | glVertex3fv(line[1]) |
---|
3182 | glEnd() |
---|
3183 | glColor4ubv([0,0,0,0]) |
---|
3184 | glDisable(GL_LINE_SMOOTH) |
---|
3185 | glDisable(GL_BLEND) |
---|
3186 | glDisable(GL_COLOR_MATERIAL) |
---|
3187 | |
---|
3188 | def RenderUnitVectors(x,y,z): |
---|
3189 | xyz = np.array([x,y,z]) |
---|
3190 | glEnable(GL_COLOR_MATERIAL) |
---|
3191 | glLineWidth(1) |
---|
3192 | glPushMatrix() |
---|
3193 | glTranslate(x,y,z) |
---|
3194 | glScalef(1/cell[0],1/cell[1],1/cell[2]) |
---|
3195 | glBegin(GL_LINES) |
---|
3196 | for line,color in zip(uEdges,uColors)[:3]: |
---|
3197 | glColor3ubv(color) |
---|
3198 | glVertex3fv(-line[1]/2.) |
---|
3199 | glVertex3fv(line[1]/2.) |
---|
3200 | glEnd() |
---|
3201 | glPopMatrix() |
---|
3202 | glColor4ubv([0,0,0,0]) |
---|
3203 | glDisable(GL_COLOR_MATERIAL) |
---|
3204 | |
---|
3205 | def RenderSphere(x,y,z,radius,color): |
---|
3206 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
3207 | glPushMatrix() |
---|
3208 | glTranslate(x,y,z) |
---|
3209 | glMultMatrixf(B4mat.T) |
---|
3210 | q = gluNewQuadric() |
---|
3211 | gluSphere(q,radius,20,10) |
---|
3212 | glPopMatrix() |
---|
3213 | |
---|
3214 | def RenderDots(XYZ,RC): |
---|
3215 | glEnable(GL_COLOR_MATERIAL) |
---|
3216 | XYZ = np.array(XYZ) |
---|
3217 | glPushMatrix() |
---|
3218 | for xyz,rc in zip(XYZ,RC): |
---|
3219 | x,y,z = xyz |
---|
3220 | r,c = rc |
---|
3221 | glColor3ubv(c) |
---|
3222 | glPointSize(r*50) |
---|
3223 | glBegin(GL_POINTS) |
---|
3224 | glVertex3fv(xyz) |
---|
3225 | glEnd() |
---|
3226 | glPopMatrix() |
---|
3227 | glColor4ubv([0,0,0,0]) |
---|
3228 | glDisable(GL_COLOR_MATERIAL) |
---|
3229 | |
---|
3230 | def RenderSmallSphere(x,y,z,radius,color): |
---|
3231 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
3232 | glPushMatrix() |
---|
3233 | glTranslate(x,y,z) |
---|
3234 | glMultMatrixf(B4mat.T) |
---|
3235 | q = gluNewQuadric() |
---|
3236 | gluSphere(q,radius,4,2) |
---|
3237 | glPopMatrix() |
---|
3238 | |
---|
3239 | def RenderEllipsoid(x,y,z,ellipseProb,E,R4,color): |
---|
3240 | s1,s2,s3 = E |
---|
3241 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
3242 | glPushMatrix() |
---|
3243 | glTranslate(x,y,z) |
---|
3244 | glMultMatrixf(B4mat.T) |
---|
3245 | glMultMatrixf(R4.T) |
---|
3246 | glEnable(GL_NORMALIZE) |
---|
3247 | glScale(s1,s2,s3) |
---|
3248 | q = gluNewQuadric() |
---|
3249 | gluSphere(q,ellipseProb,20,10) |
---|
3250 | glDisable(GL_NORMALIZE) |
---|
3251 | glPopMatrix() |
---|
3252 | |
---|
3253 | def RenderBonds(x,y,z,Bonds,radius,color,slice=20): |
---|
3254 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
3255 | glPushMatrix() |
---|
3256 | glTranslate(x,y,z) |
---|
3257 | glMultMatrixf(B4mat.T) |
---|
3258 | for bond in Bonds: |
---|
3259 | glPushMatrix() |
---|
3260 | Dx = np.inner(Amat,bond) |
---|
3261 | Z = np.sqrt(np.sum(Dx**2)) |
---|
3262 | if Z: |
---|
3263 | azm = atan2d(-Dx[1],-Dx[0]) |
---|
3264 | phi = acosd(Dx[2]/Z) |
---|
3265 | glRotate(-azm,0,0,1) |
---|
3266 | glRotate(phi,1,0,0) |
---|
3267 | q = gluNewQuadric() |
---|
3268 | gluCylinder(q,radius,radius,Z,slice,2) |
---|
3269 | glPopMatrix() |
---|
3270 | glPopMatrix() |
---|
3271 | |
---|
3272 | def RenderLines(x,y,z,Bonds,color): |
---|
3273 | glShadeModel(GL_FLAT) |
---|
3274 | xyz = np.array([x,y,z]) |
---|
3275 | glEnable(GL_COLOR_MATERIAL) |
---|
3276 | glLineWidth(1) |
---|
3277 | glColor3fv(color) |
---|
3278 | glPushMatrix() |
---|
3279 | glBegin(GL_LINES) |
---|
3280 | for bond in Bonds: |
---|
3281 | glVertex3fv(xyz) |
---|
3282 | glVertex3fv(xyz+bond) |
---|
3283 | glEnd() |
---|
3284 | glColor4ubv([0,0,0,0]) |
---|
3285 | glPopMatrix() |
---|
3286 | glDisable(GL_COLOR_MATERIAL) |
---|
3287 | glShadeModel(GL_SMOOTH) |
---|
3288 | |
---|
3289 | def RenderPolyhedra(x,y,z,Faces,color): |
---|
3290 | glShadeModel(GL_FLAT) |
---|
3291 | glPushMatrix() |
---|
3292 | glTranslate(x,y,z) |
---|
3293 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
3294 | glShadeModel(GL_SMOOTH) |
---|
3295 | glMultMatrixf(B4mat.T) |
---|
3296 | for face,norm in Faces: |
---|
3297 | glPolygonMode(GL_FRONT_AND_BACK,GL_FILL) |
---|
3298 | glFrontFace(GL_CW) |
---|
3299 | glNormal3fv(norm) |
---|
3300 | glBegin(GL_TRIANGLES) |
---|
3301 | for vert in face: |
---|
3302 | glVertex3fv(vert) |
---|
3303 | glEnd() |
---|
3304 | glPopMatrix() |
---|
3305 | glShadeModel(GL_SMOOTH) |
---|
3306 | |
---|
3307 | def RenderMapPeak(x,y,z,color,den): |
---|
3308 | glShadeModel(GL_FLAT) |
---|
3309 | xyz = np.array([x,y,z]) |
---|
3310 | glEnable(GL_COLOR_MATERIAL) |
---|
3311 | glLineWidth(3) |
---|
3312 | glColor3fv(color*den/255) |
---|
3313 | glPushMatrix() |
---|
3314 | glBegin(GL_LINES) |
---|
3315 | for vec in mapPeakVecs: |
---|
3316 | glVertex3fv(vec[0]+xyz) |
---|
3317 | glVertex3fv(vec[1]+xyz) |
---|
3318 | glEnd() |
---|
3319 | glColor4ubv([0,0,0,0]) |
---|
3320 | glPopMatrix() |
---|
3321 | glDisable(GL_COLOR_MATERIAL) |
---|
3322 | glShadeModel(GL_SMOOTH) |
---|
3323 | |
---|
3324 | def RenderBackbone(Backbone,BackboneColor,radius): |
---|
3325 | glPushMatrix() |
---|
3326 | glMultMatrixf(B4mat.T) |
---|
3327 | glEnable(GL_COLOR_MATERIAL) |
---|
3328 | glShadeModel(GL_SMOOTH) |
---|
3329 | gleSetJoinStyle(TUBE_NORM_EDGE | TUBE_JN_ANGLE | TUBE_JN_CAP) |
---|
3330 | glePolyCylinder(Backbone,BackboneColor,radius) |
---|
3331 | glPopMatrix() |
---|
3332 | glDisable(GL_COLOR_MATERIAL) |
---|
3333 | |
---|
3334 | def RenderLabel(x,y,z,label,r,color,matRot): |
---|
3335 | ''' |
---|
3336 | color wx.Color object |
---|
3337 | ''' |
---|
3338 | glPushMatrix() |
---|
3339 | glTranslate(x,y,z) |
---|
3340 | glMultMatrixf(B4mat.T) |
---|
3341 | glDisable(GL_LIGHTING) |
---|
3342 | glRasterPos3f(0,0,0) |
---|
3343 | glMultMatrixf(matRot) |
---|
3344 | glRotate(180,1,0,0) #fix to flip about x-axis |
---|
3345 | text = gltext.Text(text=label,font=Font,foreground=color) |
---|
3346 | text.draw_text(scale=0.025) |
---|
3347 | glEnable(GL_LIGHTING) |
---|
3348 | glPopMatrix() |
---|
3349 | |
---|
3350 | def RenderMap(rho,rhoXYZ,indx,Rok): |
---|
3351 | glShadeModel(GL_FLAT) |
---|
3352 | cLevel = drawingData['contourLevel'] |
---|
3353 | XYZ = [] |
---|
3354 | RC = [] |
---|
3355 | for i,xyz in enumerate(rhoXYZ): |
---|
3356 | if not Rok[i]: |
---|
3357 | x,y,z = xyz |
---|
3358 | I,J,K = indx[i] |
---|
3359 | alpha = 1.0 |
---|
3360 | if cLevel < 1.: |
---|
3361 | alpha = (abs(rho[I,J,K])/mapData['rhoMax']-cLevel)/(1.-cLevel) |
---|
3362 | if rho[I,J,K] < 0.: |
---|
3363 | XYZ.append(xyz) |
---|
3364 | RC.append([0.1*alpha,Rd]) |
---|
3365 | else: |
---|
3366 | XYZ.append(xyz) |
---|
3367 | RC.append([0.1*alpha,Gr]) |
---|
3368 | RenderDots(XYZ,RC) |
---|
3369 | glShadeModel(GL_SMOOTH) |
---|
3370 | |
---|
3371 | def Draw(caller=''): |
---|
3372 | #useful debug? |
---|
3373 | # if caller: |
---|
3374 | # print caller |
---|
3375 | # end of useful debug |
---|
3376 | mapData = generalData['Map'] |
---|
3377 | pageName = '' |
---|
3378 | page = getSelection() |
---|
3379 | if page: |
---|
3380 | pageName = G2frame.dataDisplay.GetPageText(page) |
---|
3381 | rhoXYZ = [] |
---|
3382 | if len(mapData['rho']): |
---|
3383 | VP = np.array(drawingData['viewPoint'][0])-np.array([.5,.5,.5]) |
---|
3384 | contLevel = drawingData['contourLevel']*mapData['rhoMax'] |
---|
3385 | if 'delt-F' in mapData['MapType']: |
---|
3386 | rho = ma.array(mapData['rho'],mask=(np.abs(mapData['rho'])<contLevel)) |
---|
3387 | else: |
---|
3388 | rho = ma.array(mapData['rho'],mask=(mapData['rho']<contLevel)) |
---|
3389 | steps = 1./np.array(rho.shape) |
---|
3390 | incre = np.where(VP>=0,VP%steps,VP%steps-steps) |
---|
3391 | Vsteps = -np.array(VP/steps,dtype='i') |
---|
3392 | rho = np.roll(np.roll(np.roll(rho,Vsteps[0],axis=0),Vsteps[1],axis=1),Vsteps[2],axis=2) |
---|
3393 | indx = np.array(ma.nonzero(rho)).T |
---|
3394 | rhoXYZ = indx*steps+VP-incre |
---|
3395 | Nc = len(rhoXYZ) |
---|
3396 | rcube = 2000.*Vol/(ForthirdPI*Nc) |
---|
3397 | rmax = math.exp(math.log(rcube)/3.)**2 |
---|
3398 | radius = min(drawingData['mapSize']**2,rmax) |
---|
3399 | view = np.array(drawingData['viewPoint'][0]) |
---|
3400 | Rok = np.sum(np.inner(Amat,rhoXYZ-view).T**2,axis=1)>radius |
---|
3401 | Ind = GetSelectedAtoms() |
---|
3402 | VS = np.array(Page.canvas.GetSize()) |
---|
3403 | aspect = float(VS[0])/float(VS[1]) |
---|
3404 | cPos = drawingData['cameraPos'] |
---|
3405 | Zclip = drawingData['Zclip']*cPos/200. |
---|
3406 | Q = drawingData['Quaternion'] |
---|
3407 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
3408 | cx,ct,cs,ci = drawingData['atomPtrs'] |
---|
3409 | bondR = drawingData['bondRadius'] |
---|
3410 | G,g = G2lat.cell2Gmat(cell) |
---|
3411 | GS = G |
---|
3412 | GS[0][1] = GS[1][0] = math.sqrt(GS[0][0]*GS[1][1]) |
---|
3413 | GS[0][2] = GS[2][0] = math.sqrt(GS[0][0]*GS[2][2]) |
---|
3414 | GS[1][2] = GS[2][1] = math.sqrt(GS[1][1]*GS[2][2]) |
---|
3415 | ellipseProb = G2lat.criticalEllipse(drawingData['ellipseProb']/100.) |
---|
3416 | |
---|
3417 | SetBackground() |
---|
3418 | glInitNames() |
---|
3419 | glPushName(0) |
---|
3420 | |
---|
3421 | glMatrixMode(GL_PROJECTION) |
---|
3422 | glLoadIdentity() |
---|
3423 | glViewport(0,0,VS[0],VS[1]) |
---|
3424 | gluPerspective(20.,aspect,cPos-Zclip,cPos+Zclip) |
---|
3425 | gluLookAt(0,0,cPos,0,0,0,0,1,0) |
---|
3426 | SetLights() |
---|
3427 | |
---|
3428 | glMatrixMode(GL_MODELVIEW) |
---|
3429 | glLoadIdentity() |
---|
3430 | matRot = G2mth.Q2Mat(Q) |
---|
3431 | matRot = np.concatenate((np.concatenate((matRot,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
3432 | glMultMatrixf(matRot.T) |
---|
3433 | glMultMatrixf(A4mat.T) |
---|
3434 | glTranslate(-Tx,-Ty,-Tz) |
---|
3435 | if drawingData['unitCellBox']: |
---|
3436 | RenderBox() |
---|
3437 | if drawingData['showABC']: |
---|
3438 | x,y,z = drawingData['viewPoint'][0] |
---|
3439 | RenderUnitVectors(x,y,z) |
---|
3440 | Backbones = {} |
---|
3441 | BackboneColor = [] |
---|
3442 | time0 = time.time() |
---|
3443 | # glEnable(GL_BLEND) |
---|
3444 | # glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) |
---|
3445 | for iat,atom in enumerate(drawingData['Atoms']): |
---|
3446 | x,y,z = atom[cx:cx+3] |
---|
3447 | Bonds = atom[-2] |
---|
3448 | Faces = atom[-1] |
---|
3449 | try: |
---|
3450 | atNum = generalData['AtomTypes'].index(atom[ct]) |
---|
3451 | except ValueError: |
---|
3452 | atNum = -1 |
---|
3453 | CL = atom[cs+2] |
---|
3454 | atColor = np.array(CL)/255. |
---|
3455 | if drawingData['showRigidBodies'] and atom[ci] in rbAtmDict: |
---|
3456 | bndColor = Or |
---|
3457 | else: |
---|
3458 | bndColor = atColor |
---|
3459 | if iat in Ind and G2frame.dataDisplay.GetPageText(getSelection()) != 'Map peaks': |
---|
3460 | atColor = np.array(Gr)/255. |
---|
3461 | # color += [.25,] |
---|
3462 | radius = 0.5 |
---|
3463 | if atom[cs] != '': |
---|
3464 | try: |
---|
3465 | glLoadName(atom[-3]) |
---|
3466 | except: #problem with old files - missing code |
---|
3467 | pass |
---|
3468 | if 'balls' in atom[cs]: |
---|
3469 | vdwScale = drawingData['vdwScale'] |
---|
3470 | ballScale = drawingData['ballScale'] |
---|
3471 | if atNum < 0: |
---|
3472 | radius = 0.2 |
---|
3473 | elif 'H' == atom[ct]: |
---|
3474 | if drawingData['showHydrogen']: |
---|
3475 | if 'vdW' in atom[cs] and atNum >= 0: |
---|
3476 | radius = vdwScale*generalData['vdWRadii'][atNum] |
---|
3477 | else: |
---|
3478 | radius = ballScale*drawingData['sizeH'] |
---|
3479 | else: |
---|
3480 | radius = 0.0 |
---|
3481 | else: |
---|
3482 | if 'vdW' in atom[cs]: |
---|
3483 | radius = vdwScale*generalData['vdWRadii'][atNum] |
---|
3484 | else: |
---|
3485 | radius = ballScale*generalData['BondRadii'][atNum] |
---|
3486 | RenderSphere(x,y,z,radius,atColor) |
---|
3487 | if 'sticks' in atom[cs]: |
---|
3488 | RenderBonds(x,y,z,Bonds,bondR,bndColor) |
---|
3489 | elif 'ellipsoids' in atom[cs]: |
---|
3490 | RenderBonds(x,y,z,Bonds,bondR,bndColor) |
---|
3491 | if atom[cs+3] == 'A': |
---|
3492 | Uij = atom[cs+5:cs+11] |
---|
3493 | U = np.multiply(G2spc.Uij2U(Uij),GS) |
---|
3494 | U = np.inner(Amat,np.inner(U,Amat).T) |
---|
3495 | E,R = nl.eigh(U) |
---|
3496 | R4 = np.concatenate((np.concatenate((R,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
3497 | E = np.sqrt(E) |
---|
3498 | if atom[ct] == 'H' and not drawingData['showHydrogen']: |
---|
3499 | pass |
---|
3500 | else: |
---|
3501 | RenderEllipsoid(x,y,z,ellipseProb,E,R4,atColor) |
---|
3502 | else: |
---|
3503 | if atom[ct] == 'H' and not drawingData['showHydrogen']: |
---|
3504 | pass |
---|
3505 | else: |
---|
3506 | radius = ellipseProb*math.sqrt(abs(atom[cs+4])) |
---|
3507 | RenderSphere(x,y,z,radius,atColor) |
---|
3508 | elif 'lines' in atom[cs]: |
---|
3509 | radius = 0.1 |
---|
3510 | RenderLines(x,y,z,Bonds,bndColor) |
---|
3511 | # RenderBonds(x,y,z,Bonds,0.05,color,6) |
---|
3512 | elif atom[cs] == 'sticks': |
---|
3513 | radius = 0.1 |
---|
3514 | RenderBonds(x,y,z,Bonds,bondR,bndColor) |
---|
3515 | elif atom[cs] == 'polyhedra': |
---|
3516 | RenderPolyhedra(x,y,z,Faces,atColor) |
---|
3517 | elif atom[cs] == 'backbone': |
---|
3518 | if atom[ct-1].split()[0] in ['C','N']: |
---|
3519 | if atom[2] not in Backbones: |
---|
3520 | Backbones[atom[2]] = [] |
---|
3521 | Backbones[atom[2]].append(list(np.inner(Amat,np.array([x,y,z])))) |
---|
3522 | BackboneColor.append(list(atColor)) |
---|
3523 | |
---|
3524 | if atom[cs+1] == 'type': |
---|
3525 | RenderLabel(x,y,z,' '+atom[ct],radius,wxGreen,matRot) |
---|
3526 | elif atom[cs+1] == 'name': |
---|
3527 | RenderLabel(x,y,z,' '+atom[ct-1],radius,wxGreen,matRot) |
---|
3528 | elif atom[cs+1] == 'number': |
---|
3529 | RenderLabel(x,y,z,' '+str(iat),radius,wxGreen,matRot) |
---|
3530 | elif atom[cs+1] == 'residue' and atom[ct-1] == 'CA': |
---|
3531 | RenderLabel(x,y,z,' '+atom[ct-4],radius,wxGreen,matRot) |
---|
3532 | elif atom[cs+1] == '1-letter' and atom[ct-1] == 'CA': |
---|
3533 | RenderLabel(x,y,z,' '+atom[ct-3],radius,wxGreen,matRot) |
---|
3534 | elif atom[cs+1] == 'chain' and atom[ct-1] == 'CA': |
---|
3535 | RenderLabel(x,y,z,' '+atom[ct-2],radius,wxGreen,matRot) |
---|
3536 | # glDisable(GL_BLEND) |
---|
3537 | if len(rhoXYZ): |
---|
3538 | RenderMap(rho,rhoXYZ,indx,Rok) |
---|
3539 | if len(mapPeaks): |
---|
3540 | XYZ = mapPeaks.T[1:4].T |
---|
3541 | mapBonds = FindPeaksBonds(XYZ) |
---|
3542 | for ind,[mag,x,y,z,d] in enumerate(mapPeaks): |
---|
3543 | if ind in Ind and pageName == 'Map peaks': |
---|
3544 | RenderMapPeak(x,y,z,Gr,1.0) |
---|
3545 | else: |
---|
3546 | RenderMapPeak(x,y,z,Wt,mag/peakMax) |
---|
3547 | if showBonds: |
---|
3548 | RenderLines(x,y,z,mapBonds[ind],Wt) |
---|
3549 | if len(testRBObj) and pageName == 'RB Models': |
---|
3550 | XYZ = G2mth.UpdateRBXYZ(Bmat,testRBObj['rbObj'],testRBObj['rbData'],testRBObj['rbType'])[0] |
---|
3551 | rbBonds = FindPeaksBonds(XYZ) |
---|
3552 | for ind,[x,y,z] in enumerate(XYZ): |
---|
3553 | aType = testRBObj['rbAtTypes'][ind] |
---|
3554 | name = ' '+aType+str(ind) |
---|
3555 | color = np.array(testRBObj['AtInfo'][aType][1]) |
---|
3556 | RenderSphere(x,y,z,0.2,color/255.) |
---|
3557 | RenderBonds(x,y,z,rbBonds[ind],0.03,Gr) |
---|
3558 | RenderLabel(x,y,z,name,0.2,wxOrange,matRot) |
---|
3559 | if len(mcsaModels) > 1 and pageName == 'MC/SA': #skip the default MD entry |
---|
3560 | for ind,[x,y,z] in enumerate(mcsaXYZ): |
---|
3561 | aType = mcsaTypes[ind] |
---|
3562 | name = ' '+aType+str(ind) |
---|
3563 | color = np.array(MCSA['AtInfo'][aType][1]) |
---|
3564 | RenderSphere(x,y,z,0.2,color/255.) |
---|
3565 | RenderBonds(x,y,z,mcsaBonds[ind],0.03,Gr) |
---|
3566 | RenderLabel(x,y,z,name,0.2,wxOrange,matRot) |
---|
3567 | if Backbones: |
---|
3568 | for chain in Backbones: |
---|
3569 | Backbone = Backbones[chain] |
---|
3570 | RenderBackbone(Backbone,BackboneColor,bondR) |
---|
3571 | # print time.time()-time0 |
---|
3572 | Page.canvas.SwapBuffers() |
---|
3573 | |
---|
3574 | def OnSize(event): |
---|
3575 | Draw('size') |
---|
3576 | |
---|
3577 | def OnFocus(event): #not needed?? Bind commented out below |
---|
3578 | Draw('focus') |
---|
3579 | |
---|
3580 | try: |
---|
3581 | plotNum = G2frame.G2plotNB.plotList.index(generalData['Name']) |
---|
3582 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
3583 | except ValueError: |
---|
3584 | Plot = G2frame.G2plotNB.addOgl(generalData['Name']) |
---|
3585 | plotNum = G2frame.G2plotNB.plotList.index(generalData['Name']) |
---|
3586 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
3587 | Page.views = False |
---|
3588 | view = False |
---|
3589 | altDown = False |
---|
3590 | Font = Page.GetFont() |
---|
3591 | Page.SetFocus() |
---|
3592 | Page.Choice = None |
---|
3593 | if mapData['Flip']: |
---|
3594 | choice = [' save as/key:','jpeg','tiff','bmp','c: center on 1/2,1/2,1/2', |
---|
3595 | 'u: roll up','d: roll down','l: roll left','r: roll right'] |
---|
3596 | else: |
---|
3597 | choice = [' save as/key:','jpeg','tiff','bmp','c: center on 1/2,1/2,1/2','n: next','p: previous'] |
---|
3598 | cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,choices=choice) |
---|
3599 | cb.Bind(wx.EVT_COMBOBOX, OnKeyBox) |
---|
3600 | cb.SetValue(' save as/key:') |
---|
3601 | Page.canvas.Bind(wx.EVT_MOUSEWHEEL, OnMouseWheel) |
---|
3602 | Page.canvas.Bind(wx.EVT_LEFT_DOWN, OnMouseDown) |
---|
3603 | Page.canvas.Bind(wx.EVT_RIGHT_DOWN, OnMouseDown) |
---|
3604 | Page.canvas.Bind(wx.EVT_MIDDLE_DOWN, OnMouseDown) |
---|
3605 | Page.canvas.Bind(wx.EVT_KEY_UP, OnKey) |
---|
3606 | Page.canvas.Bind(wx.EVT_MOTION, OnMouseMove) |
---|
3607 | Page.canvas.Bind(wx.EVT_SIZE, OnSize) |
---|
3608 | # Page.canvas.Bind(wx.EVT_SET_FOCUS, OnFocus) |
---|
3609 | Page.camera['position'] = drawingData['cameraPos'] |
---|
3610 | Page.camera['viewPoint'] = np.inner(Amat,drawingData['viewPoint'][0]) |
---|
3611 | Page.camera['backColor'] = np.array(list(drawingData['backColor'])+[0,])/255. |
---|
3612 | try: |
---|
3613 | Page.canvas.SetCurrent() |
---|
3614 | except: |
---|
3615 | pass |
---|
3616 | Draw('main') |
---|
3617 | |
---|
3618 | ################################################################################ |
---|
3619 | #### Plot Rigid Body |
---|
3620 | ################################################################################ |
---|
3621 | |
---|
3622 | def PlotRigidBody(G2frame,rbType,AtInfo,rbData,defaults): |
---|
3623 | '''RB plotting package. Can show rigid body structures as balls & sticks |
---|
3624 | ''' |
---|
3625 | |
---|
3626 | def FindBonds(XYZ): |
---|
3627 | rbTypes = rbData['rbTypes'] |
---|
3628 | Radii = [] |
---|
3629 | for Atype in rbTypes: |
---|
3630 | Radii.append(AtInfo[Atype][0]) |
---|
3631 | if Atype == 'H': |
---|
3632 | Radii[-1] = 0.5 |
---|
3633 | Radii = np.array(Radii) |
---|
3634 | Bonds = [[] for i in range(len(Radii))] |
---|
3635 | for i,xyz in enumerate(XYZ): |
---|
3636 | Dx = XYZ-xyz |
---|
3637 | dist = np.sqrt(np.sum(Dx**2,axis=1)) |
---|
3638 | sumR = Radii[i]+Radii |
---|
3639 | IndB = ma.nonzero(ma.masked_greater(dist-0.85*sumR,0.)) |
---|
3640 | for j in IndB[0]: |
---|
3641 | Bonds[i].append(Dx[j]*Radii[i]/sumR[j]) |
---|
3642 | Bonds[j].append(-Dx[j]*Radii[j]/sumR[j]) |
---|
3643 | return Bonds |
---|
3644 | |
---|
3645 | Wt = np.array([255,255,255]) |
---|
3646 | Rd = np.array([255,0,0]) |
---|
3647 | Gr = np.array([0,255,0]) |
---|
3648 | Bl = np.array([0,0,255]) |
---|
3649 | uBox = np.array([[0,0,0],[1,0,0],[0,1,0],[0,0,1]]) |
---|
3650 | uEdges = np.array([[uBox[0],uBox[1]],[uBox[0],uBox[2]],[uBox[0],uBox[3]]]) |
---|
3651 | uColors = [Rd,Gr,Bl] |
---|
3652 | if rbType == 'Vector': |
---|
3653 | atNames = [str(i)+':'+Ty for i,Ty in enumerate(rbData['rbTypes'])] |
---|
3654 | XYZ = np.array([[0.,0.,0.] for Ty in rbData['rbTypes']]) |
---|
3655 | for imag,mag in enumerate(rbData['VectMag']): |
---|
3656 | XYZ += mag*rbData['rbVect'][imag] |
---|
3657 | Bonds = FindBonds(XYZ) |
---|
3658 | elif rbType == 'Residue': |
---|
3659 | # atNames = [str(i)+':'+Ty for i,Ty in enumerate(rbData['atNames'])] |
---|
3660 | atNames = rbData['atNames'] |
---|
3661 | XYZ = np.copy(rbData['rbXYZ']) #don't mess with original! |
---|
3662 | Seq = rbData['rbSeq'] |
---|
3663 | for ia,ib,ang,mv in Seq: |
---|
3664 | va = XYZ[ia]-XYZ[ib] |
---|
3665 | Q = G2mth.AVdeg2Q(ang,va) |
---|
3666 | for im in mv: |
---|
3667 | vb = XYZ[im]-XYZ[ib] |
---|
3668 | vb = G2mth.prodQVQ(Q,vb) |
---|
3669 | XYZ[im] = XYZ[ib]+vb |
---|
3670 | Bonds = FindBonds(XYZ) |
---|
3671 | elif rbType == 'Z-matrix': |
---|
3672 | pass |
---|
3673 | |
---|
3674 | # def SetRBOrigin(): |
---|
3675 | # page = getSelection() |
---|
3676 | # if page: |
---|
3677 | # if G2frame.dataDisplay.GetPageText(page) == 'Rigid bodies': |
---|
3678 | # G2frame.MapPeaksTable.SetData(mapPeaks) |
---|
3679 | # panel = G2frame.dataDisplay.GetPage(page).GetChildren() |
---|
3680 | # names = [child.GetName() for child in panel] |
---|
3681 | # panel[names.index('grid window')].Refresh() |
---|
3682 | |
---|
3683 | def OnMouseDown(event): |
---|
3684 | xy = event.GetPosition() |
---|
3685 | defaults['oldxy'] = list(xy) |
---|
3686 | |
---|
3687 | def OnMouseMove(event): |
---|
3688 | newxy = event.GetPosition() |
---|
3689 | |
---|
3690 | if event.Dragging(): |
---|
3691 | if event.LeftIsDown(): |
---|
3692 | SetRotation(newxy) |
---|
3693 | Q = defaults['Quaternion'] |
---|
3694 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
3695 | # elif event.RightIsDown(): |
---|
3696 | # SetRBOrigin(newxy) |
---|
3697 | elif event.MiddleIsDown(): |
---|
3698 | SetRotationZ(newxy) |
---|
3699 | Q = defaults['Quaternion'] |
---|
3700 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
3701 | Draw('move') |
---|
3702 | |
---|
3703 | def OnMouseWheel(event): |
---|
3704 | defaults['cameraPos'] += event.GetWheelRotation()/24 |
---|
3705 | defaults['cameraPos'] = max(10,min(500,defaults['cameraPos'])) |
---|
3706 | G2frame.G2plotNB.status.SetStatusText('New camera distance: %.2f'%(defaults['cameraPos']),1) |
---|
3707 | Draw('wheel') |
---|
3708 | |
---|
3709 | def SetBackground(): |
---|
3710 | R,G,B,A = Page.camera['backColor'] |
---|
3711 | glClearColor(R,G,B,A) |
---|
3712 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
---|
3713 | |
---|
3714 | def SetLights(): |
---|
3715 | glEnable(GL_DEPTH_TEST) |
---|
3716 | glShadeModel(GL_FLAT) |
---|
3717 | glEnable(GL_LIGHTING) |
---|
3718 | glEnable(GL_LIGHT0) |
---|
3719 | glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0) |
---|
3720 | glLightfv(GL_LIGHT0,GL_AMBIENT,[1,1,1,.8]) |
---|
3721 | glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1]) |
---|
3722 | |
---|
3723 | # def SetRBOrigin(newxy): |
---|
3724 | ##first get translation vector in screen coords. |
---|
3725 | # oldxy = defaults['oldxy'] |
---|
3726 | # if not len(oldxy): oldxy = list(newxy) |
---|
3727 | # dxy = newxy-oldxy |
---|
3728 | # defaults['oldxy'] = list(newxy) |
---|
3729 | # V = np.array([dxy[0],-dxy[1],0.])/100. |
---|
3730 | # Q = defaults['Quaternion'] |
---|
3731 | # V = G2mth.prodQVQ(G2mth.invQ(Q),V) |
---|
3732 | # rbData['rbXYZ'] += V |
---|
3733 | # PlotRigidBody(G2frame,rbType,AtInfo,rbData,defaults) |
---|
3734 | # |
---|
3735 | def SetRotation(newxy): |
---|
3736 | #first get rotation vector in screen coords. & angle increment |
---|
3737 | oldxy = defaults['oldxy'] |
---|
3738 | if not len(oldxy): oldxy = list(newxy) |
---|
3739 | dxy = newxy-oldxy |
---|
3740 | defaults['oldxy'] = list(newxy) |
---|
3741 | V = np.array([dxy[1],dxy[0],0.]) |
---|
3742 | A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2) |
---|
3743 | # next transform vector back to xtal coordinates via inverse quaternion |
---|
3744 | # & make new quaternion |
---|
3745 | Q = defaults['Quaternion'] |
---|
3746 | V = G2mth.prodQVQ(G2mth.invQ(Q),V) |
---|
3747 | DQ = G2mth.AVdeg2Q(A,V) |
---|
3748 | Q = G2mth.prodQQ(Q,DQ) |
---|
3749 | defaults['Quaternion'] = Q |
---|
3750 | # finally get new view vector - last row of rotation matrix |
---|
3751 | VD = G2mth.Q2Mat(Q)[2] |
---|
3752 | VD /= np.sqrt(np.sum(VD**2)) |
---|
3753 | defaults['viewDir'] = VD |
---|
3754 | |
---|
3755 | def SetRotationZ(newxy): |
---|
3756 | #first get rotation vector (= view vector) in screen coords. & angle increment |
---|
3757 | View = glGetIntegerv(GL_VIEWPORT) |
---|
3758 | cent = [View[2]/2,View[3]/2] |
---|
3759 | oldxy = defaults['oldxy'] |
---|
3760 | if not len(oldxy): oldxy = list(newxy) |
---|
3761 | dxy = newxy-oldxy |
---|
3762 | defaults['oldxy'] = list(newxy) |
---|
3763 | V = defaults['viewDir'] |
---|
3764 | A = [0,0] |
---|
3765 | A[0] = dxy[1]*.25 |
---|
3766 | A[1] = dxy[0]*.25 |
---|
3767 | if newxy[0] > cent[0]: |
---|
3768 | A[0] *= -1 |
---|
3769 | if newxy[1] < cent[1]: |
---|
3770 | A[1] *= -1 |
---|
3771 | # next transform vector back to xtal coordinates & make new quaternion |
---|
3772 | Q = defaults['Quaternion'] |
---|
3773 | Qx = G2mth.AVdeg2Q(A[0],V) |
---|
3774 | Qy = G2mth.AVdeg2Q(A[1],V) |
---|
3775 | Q = G2mth.prodQQ(Q,Qx) |
---|
3776 | Q = G2mth.prodQQ(Q,Qy) |
---|
3777 | defaults['Quaternion'] = Q |
---|
3778 | |
---|
3779 | def RenderUnitVectors(x,y,z): |
---|
3780 | xyz = np.array([x,y,z]) |
---|
3781 | glEnable(GL_COLOR_MATERIAL) |
---|
3782 | glLineWidth(1) |
---|
3783 | glPushMatrix() |
---|
3784 | glTranslate(x,y,z) |
---|
3785 | glBegin(GL_LINES) |
---|
3786 | for line,color in zip(uEdges,uColors): |
---|
3787 | glColor3ubv(color) |
---|
3788 | glVertex3fv(-line[1]) |
---|
3789 | glVertex3fv(line[1]) |
---|
3790 | glEnd() |
---|
3791 | glPopMatrix() |
---|
3792 | glColor4ubv([0,0,0,0]) |
---|
3793 | glDisable(GL_COLOR_MATERIAL) |
---|
3794 | |
---|
3795 | def RenderSphere(x,y,z,radius,color): |
---|
3796 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
3797 | glPushMatrix() |
---|
3798 | glTranslate(x,y,z) |
---|
3799 | q = gluNewQuadric() |
---|
3800 | gluSphere(q,radius,20,10) |
---|
3801 | glPopMatrix() |
---|
3802 | |
---|
3803 | def RenderBonds(x,y,z,Bonds,radius,color,slice=20): |
---|
3804 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
3805 | glPushMatrix() |
---|
3806 | glTranslate(x,y,z) |
---|
3807 | for Dx in Bonds: |
---|
3808 | glPushMatrix() |
---|
3809 | Z = np.sqrt(np.sum(Dx**2)) |
---|
3810 | if Z: |
---|
3811 | azm = atan2d(-Dx[1],-Dx[0]) |
---|
3812 | phi = acosd(Dx[2]/Z) |
---|
3813 | glRotate(-azm,0,0,1) |
---|
3814 | glRotate(phi,1,0,0) |
---|
3815 | q = gluNewQuadric() |
---|
3816 | gluCylinder(q,radius,radius,Z,slice,2) |
---|
3817 | glPopMatrix() |
---|
3818 | glPopMatrix() |
---|
3819 | |
---|
3820 | def RenderLabel(x,y,z,label,matRot): |
---|
3821 | glPushMatrix() |
---|
3822 | glTranslate(x,y,z) |
---|
3823 | glDisable(GL_LIGHTING) |
---|
3824 | glRasterPos3f(0,0,0) |
---|
3825 | glMultMatrixf(matRot) |
---|
3826 | glRotate(180,1,0,0) #fix to flip about x-axis |
---|
3827 | text = gltext.TextElement(text=label,font=Font,foreground=wx.WHITE) |
---|
3828 | text.draw_text(scale=0.025) |
---|
3829 | glEnable(GL_LIGHTING) |
---|
3830 | glPopMatrix() |
---|
3831 | |
---|
3832 | def Draw(caller=''): |
---|
3833 | #useful debug? |
---|
3834 | # if caller: |
---|
3835 | # print caller |
---|
3836 | # end of useful debug |
---|
3837 | cPos = defaults['cameraPos'] |
---|
3838 | VS = np.array(Page.canvas.GetSize()) |
---|
3839 | aspect = float(VS[0])/float(VS[1]) |
---|
3840 | Zclip = 500.0 |
---|
3841 | Q = defaults['Quaternion'] |
---|
3842 | SetBackground() |
---|
3843 | glInitNames() |
---|
3844 | glPushName(0) |
---|
3845 | |
---|
3846 | glMatrixMode(GL_PROJECTION) |
---|
3847 | glLoadIdentity() |
---|
3848 | glViewport(0,0,VS[0],VS[1]) |
---|
3849 | gluPerspective(20.,aspect,0.1,500.) |
---|
3850 | gluLookAt(0,0,cPos,0,0,0,0,1,0) |
---|
3851 | SetLights() |
---|
3852 | |
---|
3853 | glMatrixMode(GL_MODELVIEW) |
---|
3854 | glLoadIdentity() |
---|
3855 | matRot = G2mth.Q2Mat(Q) |
---|
3856 | matRot = np.concatenate((np.concatenate((matRot,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
3857 | glMultMatrixf(matRot.T) |
---|
3858 | RenderUnitVectors(0.,0.,0.) |
---|
3859 | radius = 0.2 |
---|
3860 | for iat,atom in enumerate(XYZ): |
---|
3861 | x,y,z = atom |
---|
3862 | CL = AtInfo[rbData['rbTypes'][iat]][1] |
---|
3863 | color = np.array(CL)/255. |
---|
3864 | RenderSphere(x,y,z,radius,color) |
---|
3865 | RenderBonds(x,y,z,Bonds[iat],0.05,color) |
---|
3866 | RenderLabel(x,y,z,' '+atNames[iat],matRot) |
---|
3867 | Page.canvas.SwapBuffers() |
---|
3868 | |
---|
3869 | def OnSize(event): |
---|
3870 | Draw('size') |
---|
3871 | |
---|
3872 | try: |
---|
3873 | plotNum = G2frame.G2plotNB.plotList.index('Rigid body') |
---|
3874 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
3875 | except ValueError: |
---|
3876 | Plot = G2frame.G2plotNB.addOgl('Rigid body') |
---|
3877 | plotNum = G2frame.G2plotNB.plotList.index('Rigid body') |
---|
3878 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
3879 | Page.views = False |
---|
3880 | view = False |
---|
3881 | altDown = False |
---|
3882 | Page.SetFocus() |
---|
3883 | Font = Page.GetFont() |
---|
3884 | Page.canvas.Bind(wx.EVT_MOUSEWHEEL, OnMouseWheel) |
---|
3885 | Page.canvas.Bind(wx.EVT_LEFT_DOWN, OnMouseDown) |
---|
3886 | Page.canvas.Bind(wx.EVT_RIGHT_DOWN, OnMouseDown) |
---|
3887 | Page.canvas.Bind(wx.EVT_MIDDLE_DOWN, OnMouseDown) |
---|
3888 | Page.canvas.Bind(wx.EVT_MOTION, OnMouseMove) |
---|
3889 | Page.canvas.Bind(wx.EVT_SIZE, OnSize) |
---|
3890 | Page.camera['position'] = defaults['cameraPos'] |
---|
3891 | Page.camera['backColor'] = np.array([0,0,0,0]) |
---|
3892 | Page.canvas.SetCurrent() |
---|
3893 | Draw('main') |
---|