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