[762] | 1 | # -*- coding: utf-8 -*- |
---|
[939] | 2 | ''' |
---|
| 3 | *GSASIIplot: plotting routines* |
---|
| 4 | =============================== |
---|
| 5 | |
---|
| 6 | ''' |
---|
[762] | 7 | ########### SVN repository information ################### |
---|
| 8 | # $Date: 2015-09-24 21:34:39 +0000 (Thu, 24 Sep 2015) $ |
---|
| 9 | # $Author: vondreele $ |
---|
| 10 | # $Revision: 1978 $ |
---|
| 11 | # $URL: trunk/GSASIIplot.py $ |
---|
| 12 | # $Id: GSASIIplot.py 1978 2015-09-24 21:34:39Z vondreele $ |
---|
| 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: 1978 $") |
---|
| 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 |
---|
[1657] | 39 | import GSASIIctrls as G2G |
---|
[762] | 40 | import pytexture as ptx |
---|
| 41 | from OpenGL.GL import * |
---|
| 42 | from OpenGL.GLU import * |
---|
| 43 | from OpenGL.GLE import * |
---|
[985] | 44 | import gltext |
---|
[762] | 45 | from matplotlib.backends.backend_wx import _load_bitmap |
---|
| 46 | from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas |
---|
| 47 | from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as Toolbar |
---|
| 48 | |
---|
| 49 | # useful degree trig functions |
---|
| 50 | sind = lambda x: math.sin(x*math.pi/180.) |
---|
| 51 | cosd = lambda x: math.cos(x*math.pi/180.) |
---|
| 52 | tand = lambda x: math.tan(x*math.pi/180.) |
---|
| 53 | asind = lambda x: 180.*math.asin(x)/math.pi |
---|
| 54 | acosd = lambda x: 180.*math.acos(x)/math.pi |
---|
| 55 | atan2d = lambda x,y: 180.*math.atan2(y,x)/math.pi |
---|
| 56 | atand = lambda x: 180.*math.atan(x)/math.pi |
---|
| 57 | # numpy versions |
---|
| 58 | npsind = lambda x: np.sin(x*np.pi/180.) |
---|
| 59 | npcosd = lambda x: np.cos(x*np.pi/180.) |
---|
[798] | 60 | nptand = lambda x: np.tan(x*np.pi/180.) |
---|
[762] | 61 | npacosd = lambda x: 180.*np.arccos(x)/np.pi |
---|
| 62 | npasind = lambda x: 180.*np.arcsin(x)/np.pi |
---|
| 63 | npatand = lambda x: 180.*np.arctan(x)/np.pi |
---|
| 64 | npatan2d = lambda x,y: 180.*np.arctan2(x,y)/np.pi |
---|
[1625] | 65 | GkDelta = unichr(0x0394) |
---|
[762] | 66 | |
---|
| 67 | class G2PlotMpl(wx.Panel): |
---|
[1889] | 68 | 'Creates a Matplotlib 2-D plot in the GSAS-II graphics window' |
---|
[762] | 69 | def __init__(self,parent,id=-1,dpi=None,**kwargs): |
---|
| 70 | wx.Panel.__init__(self,parent,id=id,**kwargs) |
---|
| 71 | mpl.rcParams['legend.fontsize'] = 10 |
---|
| 72 | self.figure = mpl.figure.Figure(dpi=dpi,figsize=(5,6)) |
---|
| 73 | self.canvas = Canvas(self,-1,self.figure) |
---|
| 74 | self.toolbar = GSASIItoolbar(self.canvas) |
---|
| 75 | |
---|
| 76 | self.toolbar.Realize() |
---|
| 77 | |
---|
| 78 | sizer=wx.BoxSizer(wx.VERTICAL) |
---|
| 79 | sizer.Add(self.canvas,1,wx.EXPAND) |
---|
| 80 | sizer.Add(self.toolbar,0,wx.LEFT|wx.EXPAND) |
---|
| 81 | self.SetSizer(sizer) |
---|
| 82 | |
---|
| 83 | class G2PlotOgl(wx.Panel): |
---|
[1889] | 84 | 'Creates an OpenGL plot in the GSAS-II graphics window' |
---|
[762] | 85 | def __init__(self,parent,id=-1,dpi=None,**kwargs): |
---|
| 86 | self.figure = wx.Panel.__init__(self,parent,id=id,**kwargs) |
---|
[1379] | 87 | if 'win' in sys.platform: #Windows (& Mac) already double buffered |
---|
[834] | 88 | self.canvas = wx.glcanvas.GLCanvas(self,-1,**kwargs) |
---|
| 89 | else: #fix from Jim Hester for X systems |
---|
| 90 | attribs = (wx.glcanvas.WX_GL_DOUBLEBUFFER,) |
---|
| 91 | self.canvas = wx.glcanvas.GLCanvas(self,-1,attribList=attribs,**kwargs) |
---|
[1379] | 92 | # create GL context for wx > 2.8 |
---|
| 93 | i,j= wx.__version__.split('.')[0:2] |
---|
| 94 | if int(i)+int(j)/10. > 2.8: |
---|
| 95 | self.context = wx.glcanvas.GLContext(self.canvas) |
---|
| 96 | self.canvas.SetCurrent(self.context) |
---|
| 97 | else: |
---|
| 98 | self.context = None |
---|
[762] | 99 | self.camera = {} |
---|
| 100 | sizer=wx.BoxSizer(wx.VERTICAL) |
---|
| 101 | sizer.Add(self.canvas,1,wx.EXPAND) |
---|
| 102 | self.SetSizer(sizer) |
---|
| 103 | |
---|
| 104 | class G2Plot3D(wx.Panel): |
---|
[1889] | 105 | 'Creates a 3D Matplotlib plot in the GSAS-II graphics window' |
---|
[762] | 106 | def __init__(self,parent,id=-1,dpi=None,**kwargs): |
---|
| 107 | wx.Panel.__init__(self,parent,id=id,**kwargs) |
---|
| 108 | self.figure = mpl.figure.Figure(dpi=dpi,figsize=(6,6)) |
---|
| 109 | self.canvas = Canvas(self,-1,self.figure) |
---|
| 110 | self.toolbar = GSASIItoolbar(self.canvas) |
---|
| 111 | |
---|
| 112 | self.toolbar.Realize() |
---|
| 113 | |
---|
| 114 | sizer=wx.BoxSizer(wx.VERTICAL) |
---|
| 115 | sizer.Add(self.canvas,1,wx.EXPAND) |
---|
| 116 | sizer.Add(self.toolbar,0,wx.LEFT|wx.EXPAND) |
---|
| 117 | self.SetSizer(sizer) |
---|
| 118 | |
---|
| 119 | class G2PlotNoteBook(wx.Panel): |
---|
[1889] | 120 | 'create a tabbed window for GSAS-II graphics' |
---|
[762] | 121 | def __init__(self,parent,id=-1): |
---|
| 122 | wx.Panel.__init__(self,parent,id=id) |
---|
| 123 | #so one can't delete a plot page!! |
---|
| 124 | self.nb = wx.aui.AuiNotebook(self, \ |
---|
| 125 | style=wx.aui.AUI_NB_DEFAULT_STYLE ^ wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB) |
---|
| 126 | sizer = wx.BoxSizer() |
---|
| 127 | sizer.Add(self.nb,1,wx.EXPAND) |
---|
| 128 | self.SetSizer(sizer) |
---|
| 129 | self.status = parent.CreateStatusBar() |
---|
| 130 | self.status.SetFieldsCount(2) |
---|
| 131 | self.status.SetStatusWidths([150,-1]) |
---|
| 132 | self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged) |
---|
[1004] | 133 | self.nb.Bind(wx.EVT_KEY_UP,self.OnNotebookKey) |
---|
[762] | 134 | |
---|
| 135 | self.plotList = [] |
---|
| 136 | |
---|
[1004] | 137 | def OnNotebookKey(self,event): |
---|
| 138 | '''Called when a keystroke event gets picked up by the notebook window |
---|
| 139 | rather the child. This is not expected, but somehow it does sometimes |
---|
| 140 | on the Mac and perhaps Linux. |
---|
| 141 | |
---|
| 142 | Assume that the page associated with the currently displayed tab |
---|
| 143 | has a child, .canvas; give that child the focus and pass it the event. |
---|
| 144 | ''' |
---|
| 145 | try: |
---|
[1077] | 146 | Page = self.nb.GetPage(self.nb.GetSelection()) |
---|
| 147 | except ValueError: # occurs with no plot tabs |
---|
| 148 | return |
---|
| 149 | try: |
---|
[1004] | 150 | Page.canvas.SetFocus() |
---|
| 151 | wx.PostEvent(Page.canvas,event) |
---|
| 152 | except AttributeError: |
---|
| 153 | pass |
---|
| 154 | |
---|
[762] | 155 | def addMpl(self,name=""): |
---|
[939] | 156 | 'Add a tabbed page with a matplotlib plot' |
---|
[762] | 157 | page = G2PlotMpl(self.nb) |
---|
| 158 | self.nb.AddPage(page,name) |
---|
| 159 | |
---|
| 160 | self.plotList.append(name) |
---|
| 161 | |
---|
| 162 | return page.figure |
---|
| 163 | |
---|
| 164 | def add3D(self,name=""): |
---|
[939] | 165 | 'Add a tabbed page with a 3D plot' |
---|
[762] | 166 | page = G2Plot3D(self.nb) |
---|
| 167 | self.nb.AddPage(page,name) |
---|
| 168 | |
---|
| 169 | self.plotList.append(name) |
---|
| 170 | |
---|
| 171 | return page.figure |
---|
| 172 | |
---|
| 173 | def addOgl(self,name=""): |
---|
[939] | 174 | 'Add a tabbed page with an openGL plot' |
---|
[762] | 175 | page = G2PlotOgl(self.nb) |
---|
| 176 | self.nb.AddPage(page,name) |
---|
| 177 | |
---|
| 178 | self.plotList.append(name) |
---|
| 179 | |
---|
| 180 | return page.figure |
---|
| 181 | |
---|
| 182 | def Delete(self,name): |
---|
[939] | 183 | 'delete a tabbed page' |
---|
[762] | 184 | try: |
---|
| 185 | item = self.plotList.index(name) |
---|
| 186 | del self.plotList[item] |
---|
| 187 | self.nb.DeletePage(item) |
---|
| 188 | except ValueError: #no plot of this name - do nothing |
---|
| 189 | return |
---|
| 190 | |
---|
| 191 | def clear(self): |
---|
[939] | 192 | 'clear all pages from plot window' |
---|
[762] | 193 | while self.nb.GetPageCount(): |
---|
| 194 | self.nb.DeletePage(0) |
---|
| 195 | self.plotList = [] |
---|
| 196 | self.status.DestroyChildren() |
---|
| 197 | |
---|
| 198 | def Rename(self,oldName,newName): |
---|
[939] | 199 | 'rename a tab' |
---|
[762] | 200 | try: |
---|
| 201 | item = self.plotList.index(oldName) |
---|
| 202 | self.plotList[item] = newName |
---|
| 203 | self.nb.SetPageText(item,newName) |
---|
| 204 | except ValueError: #no plot of this name - do nothing |
---|
| 205 | return |
---|
| 206 | |
---|
[939] | 207 | def OnPageChanged(self,event): |
---|
| 208 | 'respond to someone pressing a tab on the plot window' |
---|
[762] | 209 | if self.plotList: |
---|
| 210 | self.status.SetStatusText('Better to select this from GSAS-II data tree',1) |
---|
| 211 | self.status.DestroyChildren() #get rid of special stuff on status bar |
---|
| 212 | |
---|
| 213 | class GSASIItoolbar(Toolbar): |
---|
[1583] | 214 | 'Override the matplotlib toolbar so we can add more icons' |
---|
[762] | 215 | ON_MPL_HELP = wx.NewId() |
---|
[796] | 216 | ON_MPL_KEY = wx.NewId() |
---|
[1583] | 217 | arrows = {} |
---|
| 218 | for direc in ('left','right','up','down','Expand X', |
---|
[1585] | 219 | 'Shrink X','Expand Y','Shrink Y'): |
---|
[1583] | 220 | arrows[direc] = wx.NewId() |
---|
[762] | 221 | def __init__(self,plotCanvas): |
---|
[1583] | 222 | '''Adds additional icons to toolbar''' |
---|
[762] | 223 | Toolbar.__init__(self,plotCanvas) |
---|
[1583] | 224 | self.plotCanvas = plotCanvas |
---|
[1635] | 225 | POSITION_OF_CONFIGURE_SUBPLOTS_BTN = 6 # remove one button, nos. start at 1! |
---|
[1894] | 226 | self.DeleteToolByPos(POSITION_OF_CONFIGURE_SUBPLOTS_BTN) #doesn't work in miniconda |
---|
[1585] | 227 | self.parent = self.GetParent() |
---|
[832] | 228 | key = os.path.join(os.path.split(__file__)[0],'key.ico') |
---|
[796] | 229 | self.AddSimpleTool(self.ON_MPL_KEY,_load_bitmap(key),'Key press','Select key press') |
---|
| 230 | wx.EVT_TOOL(self,self.ON_MPL_KEY,self.OnKey) |
---|
[762] | 231 | help = os.path.join(os.path.split(__file__)[0],'help.ico') |
---|
| 232 | self.AddSimpleTool(self.ON_MPL_HELP,_load_bitmap(help),'Help on','Show help on') |
---|
| 233 | wx.EVT_TOOL(self,self.ON_MPL_HELP,self.OnHelp) |
---|
[1583] | 234 | # add arrow keys to control zooming |
---|
| 235 | for direc in ('left','right','up','down'): |
---|
| 236 | wx.EVT_TOOL(self,self.arrows[direc],self.OnArrow) |
---|
| 237 | icon = os.path.join(os.path.split(__file__)[0],direc[0]+'arrow.ico') |
---|
| 238 | self.AddSimpleTool(self.arrows[direc],_load_bitmap(icon), |
---|
| 239 | 'Shift '+direc,'Shift plot '+direc) |
---|
[1585] | 240 | for direc in ('Expand X','Shrink X','Expand Y','Shrink Y'): |
---|
[1583] | 241 | fil = ''.join([i[0].lower() for i in direc.split()]+['arrow.ico']) |
---|
| 242 | wx.EVT_TOOL(self,self.arrows[direc],self.OnArrow) |
---|
| 243 | icon = os.path.join(os.path.split(__file__)[0],fil) |
---|
| 244 | self.AddSimpleTool(self.arrows[direc],_load_bitmap(icon), |
---|
| 245 | direc,'Zoom: '+direc) |
---|
| 246 | def OnArrow(self,event): |
---|
| 247 | 'reposition limits to scan or zoom by button press' |
---|
| 248 | ax = self.plotCanvas.figure.get_axes()[0] |
---|
| 249 | xmin,xmax,ymin,ymax = ax.axis() |
---|
| 250 | #print xmin,xmax,ymin,ymax |
---|
| 251 | if event.Id == self.arrows['right']: |
---|
| 252 | delta = (xmax-xmin)/10. |
---|
| 253 | xmin -= delta |
---|
| 254 | xmax -= delta |
---|
| 255 | elif event.Id == self.arrows['left']: |
---|
| 256 | delta = (xmax-xmin)/10. |
---|
| 257 | xmin += delta |
---|
| 258 | xmax += delta |
---|
| 259 | elif event.Id == self.arrows['up']: |
---|
| 260 | delta = (ymax-ymin)/10. |
---|
| 261 | ymin -= delta |
---|
| 262 | ymax -= delta |
---|
| 263 | elif event.Id == self.arrows['down']: |
---|
| 264 | delta = (ymax-ymin)/10. |
---|
| 265 | ymin += delta |
---|
| 266 | ymax += delta |
---|
| 267 | elif event.Id == self.arrows['Expand X']: |
---|
| 268 | delta = (xmax-xmin)/10. |
---|
[1585] | 269 | xmin += delta |
---|
[1583] | 270 | xmax -= delta |
---|
| 271 | elif event.Id == self.arrows['Expand Y']: |
---|
| 272 | delta = (ymax-ymin)/10. |
---|
[1585] | 273 | ymin += delta |
---|
[1583] | 274 | ymax -= delta |
---|
| 275 | elif event.Id == self.arrows['Shrink X']: |
---|
| 276 | delta = (xmax-xmin)/10. |
---|
[1585] | 277 | xmin -= delta |
---|
[1583] | 278 | xmax += delta |
---|
| 279 | elif event.Id == self.arrows['Shrink Y']: |
---|
| 280 | delta = (ymax-ymin)/10. |
---|
[1585] | 281 | ymin -= delta |
---|
[1583] | 282 | ymax += delta |
---|
| 283 | else: |
---|
| 284 | # should not happen! |
---|
| 285 | GSASIIpath.IPyBreak() |
---|
[1585] | 286 | self.parent.toolbar.push_current() |
---|
[1583] | 287 | ax.axis((xmin,xmax,ymin,ymax)) |
---|
| 288 | #print xmin,xmax,ymin,ymax |
---|
| 289 | self.plotCanvas.figure.canvas.draw() |
---|
[1585] | 290 | self.parent.toolbar.draw() |
---|
| 291 | # self.parent.toolbar.push_current() |
---|
[1583] | 292 | |
---|
[762] | 293 | def OnHelp(self,event): |
---|
[1583] | 294 | 'Respond to press of help button on plot toolbar' |
---|
[762] | 295 | Page = self.GetParent().GetParent() |
---|
| 296 | pageNo = Page.GetSelection() |
---|
| 297 | bookmark = Page.GetPageText(pageNo) |
---|
| 298 | bookmark = bookmark.strip(')').replace('(','_') |
---|
[1657] | 299 | G2G.ShowHelp(bookmark,self.TopLevelParent) |
---|
[796] | 300 | def OnKey(self,event): |
---|
[1583] | 301 | '''Provide user with list of keystrokes defined for plot as well as an |
---|
| 302 | alternate way to access the same functionality |
---|
| 303 | ''' |
---|
[796] | 304 | parent = self.GetParent() |
---|
| 305 | if parent.Choice: |
---|
| 306 | dlg = wx.SingleChoiceDialog(parent,'Select','Key press',list(parent.Choice)) |
---|
| 307 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 308 | sel = dlg.GetSelection() |
---|
| 309 | event.key = parent.Choice[sel][0] |
---|
| 310 | parent.keyPress(event) |
---|
| 311 | dlg.Destroy() |
---|
[978] | 312 | |
---|
[762] | 313 | ################################################################################ |
---|
| 314 | ##### PlotSngl |
---|
| 315 | ################################################################################ |
---|
| 316 | |
---|
[1286] | 317 | def PlotSngl(G2frame,newPlot=False,Data=None,hklRef=None,Title=''): |
---|
[1442] | 318 | '''Structure factor plotting package - displays zone of reflections as rings proportional |
---|
[762] | 319 | to F, F**2, etc. as requested |
---|
| 320 | ''' |
---|
[1134] | 321 | from matplotlib.patches import Circle,CirclePolygon |
---|
[1978] | 322 | HKLref = hklRef |
---|
| 323 | global HKL,HKLF,HKLref |
---|
[1288] | 324 | |
---|
[1286] | 325 | def OnSCKeyPress(event): |
---|
| 326 | i = zones.index(Data['Zone']) |
---|
[1285] | 327 | newPlot = False |
---|
[1442] | 328 | pwdrChoice = {'f':'Fo','s':'Fosq','u':'Unit Fc'} |
---|
[1441] | 329 | hklfChoice = {'1':'|DFsq|>sig','3':'|DFsq|>3sig','w':'|DFsq|/sig','f':'Fo','s':'Fosq','i':'Unit Fc'} |
---|
[1285] | 330 | if event.key == 'h': |
---|
| 331 | Data['Zone'] = '100' |
---|
[1288] | 332 | newPlot = True |
---|
[1285] | 333 | elif event.key == 'k': |
---|
| 334 | Data['Zone'] = '010' |
---|
[1288] | 335 | newPlot = True |
---|
[1285] | 336 | elif event.key == 'l': |
---|
| 337 | Data['Zone'] = '001' |
---|
[1288] | 338 | newPlot = True |
---|
[1442] | 339 | elif event.key == 'i': |
---|
[1285] | 340 | Data['Scale'] *= 1.1 |
---|
| 341 | elif event.key == 'd': |
---|
| 342 | Data['Scale'] /= 1.1 |
---|
[1694] | 343 | elif event.key in ['+','=']: |
---|
[1286] | 344 | Data['Layer'] = min(Data['Layer']+1,HKLmax[i]) |
---|
[1285] | 345 | elif event.key == '-': |
---|
[1286] | 346 | Data['Layer'] = max(Data['Layer']-1,HKLmin[i]) |
---|
[1285] | 347 | elif event.key == '0': |
---|
| 348 | Data['Layer'] = 0 |
---|
[1441] | 349 | Data['Scale'] = 1.0 |
---|
| 350 | elif event.key in hklfChoice and 'HKLF' in Name: |
---|
| 351 | Data['Type'] = hklfChoice[event.key] |
---|
[1288] | 352 | newPlot = True |
---|
[1441] | 353 | elif event.key in pwdrChoice and 'PWDR' in Name: |
---|
| 354 | Data['Type'] = pwdrChoice[event.key] |
---|
| 355 | newPlot = True |
---|
[1978] | 356 | PlotSngl(G2frame,newPlot,Data,HKLref,Title) |
---|
[1285] | 357 | |
---|
[762] | 358 | def OnSCMotion(event): |
---|
| 359 | xpos = event.xdata |
---|
| 360 | if xpos: |
---|
| 361 | xpos = round(xpos) #avoid out of frame mouse position |
---|
| 362 | ypos = round(event.ydata) |
---|
| 363 | zpos = Data['Layer'] |
---|
| 364 | if '100' in Data['Zone']: |
---|
| 365 | HKLtxt = '(%3d,%3d,%3d)'%(zpos,xpos,ypos) |
---|
| 366 | elif '010' in Data['Zone']: |
---|
| 367 | HKLtxt = '(%3d,%3d,%3d)'%(xpos,zpos,ypos) |
---|
| 368 | elif '001' in Data['Zone']: |
---|
| 369 | HKLtxt = '(%3d,%3d,%3d)'%(xpos,ypos,zpos) |
---|
| 370 | Page.canvas.SetToolTipString(HKLtxt) |
---|
[1286] | 371 | G2frame.G2plotNB.status.SetStatusText('HKL = '+HKLtxt,0) |
---|
| 372 | G2frame.G2plotNB.status.SetStatusText('Use K-box to set plot controls',1) |
---|
[762] | 373 | |
---|
[1288] | 374 | def OnSCPress(event): |
---|
[762] | 375 | zpos = Data['Layer'] |
---|
[1288] | 376 | xpos = event.xdata |
---|
| 377 | if xpos: |
---|
| 378 | pos = int(round(event.xdata)),int(round(event.ydata)) |
---|
| 379 | if '100' in Data['Zone']: |
---|
| 380 | Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(zpos,pos[0],pos[1])) |
---|
| 381 | hkl = np.array([zpos,pos[0],pos[1]]) |
---|
| 382 | elif '010' in Data['Zone']: |
---|
| 383 | Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],zpos,pos[1])) |
---|
| 384 | hkl = np.array([pos[0],zpos,pos[1]]) |
---|
| 385 | elif '001' in Data['Zone']: |
---|
| 386 | Page.canvas.SetToolTipString('(picked:(%3d,%3d,%3d))'%(pos[0],pos[1],zpos)) |
---|
| 387 | hkl = np.array([pos[0],pos[1],zpos]) |
---|
| 388 | h,k,l = hkl |
---|
| 389 | hklf = HKLF[np.where(np.all(HKL-hkl == [0,0,0],axis=1))] |
---|
| 390 | if len(hklf): |
---|
| 391 | Fosq,sig,Fcsq = hklf[0] |
---|
| 392 | HKLtxt = '( %.2f %.3f %.2f %.2f)'%(Fosq,sig,Fcsq,(Fosq-Fcsq)/(scale*sig)) |
---|
| 393 | G2frame.G2plotNB.status.SetStatusText('Fosq, sig, Fcsq, delFsq/sig = '+HKLtxt,1) |
---|
[762] | 394 | |
---|
[1288] | 395 | Name = G2frame.PatternTree.GetItemText(G2frame.PatternId) |
---|
| 396 | if not Title: |
---|
| 397 | Title = Name |
---|
[762] | 398 | try: |
---|
[1286] | 399 | plotNum = G2frame.G2plotNB.plotList.index('Structure Factors') |
---|
| 400 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[762] | 401 | if not newPlot: |
---|
| 402 | Plot = Page.figure.gca() #get previous powder plot & get limits |
---|
| 403 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
| 404 | Page.figure.clf() |
---|
| 405 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
| 406 | except ValueError: |
---|
[1286] | 407 | Plot = G2frame.G2plotNB.addMpl('Structure Factors').gca() |
---|
| 408 | plotNum = G2frame.G2plotNB.plotList.index('Structure Factors') |
---|
| 409 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[1288] | 410 | Page.canvas.mpl_connect('button_press_event', OnSCPress) |
---|
[762] | 411 | Page.canvas.mpl_connect('motion_notify_event', OnSCMotion) |
---|
[1286] | 412 | Page.canvas.mpl_connect('key_press_event', OnSCKeyPress) |
---|
| 413 | Page.keyPress = OnSCKeyPress |
---|
[1442] | 414 | Page.Choice = (' key press','i: increase scale','d: decrease scale', |
---|
[1441] | 415 | 'h: select 100 zone','k: select 010 zone','l: select 001 zone', |
---|
[1442] | 416 | 'f: select Fo','s: select Fosq','u: select unit Fc', |
---|
[1441] | 417 | '+: increase index','-: decrease index','0: zero layer',) |
---|
[1288] | 418 | if 'HKLF' in Name: |
---|
[1441] | 419 | Page.Choice += ('w: select |DFsq|/sig','1: select |DFsq|>sig','3: select |DFsq|>3sig',) |
---|
[762] | 420 | Page.SetFocus() |
---|
| 421 | |
---|
[1286] | 422 | G2frame.G2plotNB.status.SetStatusText('Use K-box to set plot controls',1) |
---|
[762] | 423 | Plot.set_aspect(aspect='equal') |
---|
[1285] | 424 | |
---|
[762] | 425 | Type = Data['Type'] |
---|
| 426 | scale = Data['Scale'] |
---|
| 427 | HKLmax = Data['HKLmax'] |
---|
| 428 | HKLmin = Data['HKLmin'] |
---|
| 429 | FosqMax = Data['FoMax'] |
---|
[1506] | 430 | Super = Data['Super'] |
---|
| 431 | SuperVec = [] |
---|
[1599] | 432 | if Super: |
---|
| 433 | SuperVec = np.array(Data['SuperVec'][0]) |
---|
[762] | 434 | FoMax = math.sqrt(FosqMax) |
---|
| 435 | xlabel = ['k, h=','h, k=','h, l='] |
---|
| 436 | ylabel = ['l','l','k'] |
---|
| 437 | zones = ['100','010','001'] |
---|
| 438 | pzone = [[1,2],[0,2],[0,1]] |
---|
| 439 | izone = zones.index(Data['Zone']) |
---|
[1441] | 440 | Plot.set_title(Data['Type']+' for '+Title) |
---|
[762] | 441 | HKL = [] |
---|
| 442 | HKLF = [] |
---|
[1134] | 443 | time0 = time.time() |
---|
[1978] | 444 | for refl in HKLref: |
---|
[1506] | 445 | H = refl[:3] |
---|
[1286] | 446 | if 'HKLF' in Name: |
---|
[1504] | 447 | Fosq,sig,Fcsq = refl[5+Super:8+Super] |
---|
[1285] | 448 | else: |
---|
[1504] | 449 | Fosq,sig,Fcsq = refl[8+Super],1.0,refl[9+Super] |
---|
[1599] | 450 | if Super: |
---|
| 451 | HKL.append(H+SuperVec*refl[3]) |
---|
| 452 | else: |
---|
| 453 | HKL.append(H) |
---|
[762] | 454 | HKLF.append([Fosq,sig,Fcsq]) |
---|
| 455 | if H[izone] == Data['Layer']: |
---|
[837] | 456 | A = 0 |
---|
[762] | 457 | B = 0 |
---|
| 458 | if Type == 'Fosq': |
---|
| 459 | A = scale*Fosq/FosqMax |
---|
| 460 | B = scale*Fcsq/FosqMax |
---|
| 461 | C = abs(A-B) |
---|
| 462 | elif Type == 'Fo': |
---|
| 463 | A = scale*math.sqrt(max(0,Fosq))/FoMax |
---|
| 464 | B = scale*math.sqrt(max(0,Fcsq))/FoMax |
---|
| 465 | C = abs(A-B) |
---|
[1441] | 466 | elif Type == 'Unit Fc': |
---|
| 467 | A = scale/2 |
---|
| 468 | B = scale/2 |
---|
| 469 | C = 0.0 |
---|
| 470 | if Fcsq and Fosq > 0: |
---|
| 471 | A *= min(1.0,Fosq/Fcsq) |
---|
| 472 | C = abs(A-B) |
---|
[762] | 473 | elif Type == '|DFsq|/sig': |
---|
[837] | 474 | if sig > 0.: |
---|
[1288] | 475 | A = (Fosq-Fcsq)/(3*sig) |
---|
[837] | 476 | B = 0 |
---|
[762] | 477 | elif Type == '|DFsq|>sig': |
---|
[837] | 478 | if sig > 0.: |
---|
[1288] | 479 | A = (Fosq-Fcsq)/(3*sig) |
---|
[840] | 480 | if abs(A) < 1.0: A = 0 |
---|
[837] | 481 | B = 0 |
---|
[762] | 482 | elif Type == '|DFsq|>3sig': |
---|
[837] | 483 | if sig > 0.: |
---|
[1288] | 484 | A = (Fosq-Fcsq)/(3*sig) |
---|
[840] | 485 | if abs(A) < 3.0: A = 0 |
---|
[1599] | 486 | B = 0 |
---|
| 487 | if Super: |
---|
| 488 | h = H+SuperVec*refl[3] |
---|
| 489 | else: |
---|
| 490 | h = H |
---|
[1506] | 491 | xy = (h[pzone[izone][0]],h[pzone[izone][1]]) |
---|
[840] | 492 | if Type in ['|DFsq|/sig','|DFsq|>sig','|DFsq|>3sig']: |
---|
| 493 | if A > 0.0: |
---|
[1288] | 494 | Plot.add_artist(Circle(xy,radius=A,ec='g',fc='w')) |
---|
[840] | 495 | else: |
---|
[1288] | 496 | Plot.add_artist(Circle(xy,radius=-A,ec='r',fc='w')) |
---|
[840] | 497 | else: |
---|
[843] | 498 | if A > 0.0 and A > B: |
---|
[1288] | 499 | Plot.add_artist(Circle(xy,radius=A,ec='g',fc='w')) |
---|
[840] | 500 | if B: |
---|
| 501 | Plot.add_artist(Circle(xy,radius=B,ec='b',fc='w')) |
---|
[843] | 502 | if A < B: |
---|
[1288] | 503 | Plot.add_artist(Circle(xy,radius=A,ec='g',fc='w')) |
---|
[840] | 504 | radius = C |
---|
| 505 | if radius > 0: |
---|
| 506 | if A > B: |
---|
| 507 | Plot.add_artist(Circle(xy,radius=radius,ec='g',fc='g')) |
---|
| 508 | else: |
---|
| 509 | Plot.add_artist(Circle(xy,radius=radius,ec='r',fc='r')) |
---|
[1134] | 510 | # print 'plot time: %.3f'%(time.time()-time0) |
---|
[1506] | 511 | HKL = np.array(HKL) |
---|
[762] | 512 | HKLF = np.array(HKLF) |
---|
| 513 | Plot.set_xlabel(xlabel[izone]+str(Data['Layer']),fontsize=12) |
---|
| 514 | Plot.set_ylabel(ylabel[izone],fontsize=12) |
---|
[1286] | 515 | if not newPlot: |
---|
| 516 | Page.toolbar.push_current() |
---|
| 517 | Plot.set_xlim(xylim[0]) |
---|
| 518 | Plot.set_ylim(xylim[1]) |
---|
[837] | 519 | # xylim = [] |
---|
[1286] | 520 | Page.toolbar.push_current() |
---|
| 521 | Page.toolbar.draw() |
---|
| 522 | else: |
---|
| 523 | Plot.set_xlim((HKLmin[pzone[izone][0]],HKLmax[pzone[izone][0]])) |
---|
| 524 | Plot.set_ylim((HKLmin[pzone[izone][1]],HKLmax[pzone[izone][1]])) |
---|
| 525 | Page.canvas.draw() |
---|
[1442] | 526 | |
---|
| 527 | ################################################################################ |
---|
| 528 | ##### Plot3DSngl |
---|
| 529 | ################################################################################ |
---|
| 530 | |
---|
[1643] | 531 | def Plot3DSngl(G2frame,newPlot=False,Data=None,hklRef=None,Title=False): |
---|
[1442] | 532 | '''3D Structure factor plotting package - displays reflections as rings proportional |
---|
| 533 | to F, F**2, etc. as requested as 3D array |
---|
| 534 | ''' |
---|
| 535 | |
---|
[1598] | 536 | global ifBox |
---|
| 537 | ifBox = False |
---|
[1442] | 538 | def OnKeyBox(event): |
---|
| 539 | mode = cb.GetValue() |
---|
| 540 | if mode in ['jpeg','bmp','tiff',]: |
---|
| 541 | try: |
---|
| 542 | import Image as Im |
---|
| 543 | except ImportError: |
---|
| 544 | try: |
---|
| 545 | from PIL import Image as Im |
---|
| 546 | except ImportError: |
---|
| 547 | print "PIL/pillow Image module not present. Cannot save images without this" |
---|
| 548 | raise Exception("PIL/pillow Image module not found") |
---|
[1643] | 549 | try: |
---|
| 550 | Fname = os.path.join(Mydir,generalData['Name']+'.'+mode) |
---|
| 551 | except NameError: #for when generalData doesn't exist! |
---|
| 552 | Fname = os.path.join(Mydir,'unknown'+'.'+mode) |
---|
| 553 | print Fname+' saved' |
---|
[1442] | 554 | size = Page.canvas.GetSize() |
---|
| 555 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1) |
---|
| 556 | if mode in ['jpeg',]: |
---|
| 557 | Pix = glReadPixels(0,0,size[0],size[1],GL_RGBA, GL_UNSIGNED_BYTE) |
---|
[1608] | 558 | im = Im.new("RGBA", (size[0],size[1])) |
---|
[1442] | 559 | else: |
---|
| 560 | Pix = glReadPixels(0,0,size[0],size[1],GL_RGB, GL_UNSIGNED_BYTE) |
---|
[1608] | 561 | im = Im.new("RGB", (size[0],size[1])) |
---|
[1442] | 562 | im.fromstring(Pix) |
---|
| 563 | im.save(Fname,mode) |
---|
| 564 | cb.SetValue(' save as/key:') |
---|
| 565 | G2frame.G2plotNB.status.SetStatusText('Drawing saved to: '+Fname,1) |
---|
| 566 | else: |
---|
| 567 | event.key = cb.GetValue()[0] |
---|
| 568 | cb.SetValue(' save as/key:') |
---|
| 569 | wx.CallAfter(OnKey,event) |
---|
| 570 | Page.canvas.SetFocus() # redirect the Focus from the button back to the plot |
---|
| 571 | |
---|
| 572 | def OnKey(event): #on key UP!! |
---|
[1598] | 573 | global ifBox |
---|
[1442] | 574 | Choice = {'F':'Fo','S':'Fosq','U':'Unit','D':'dFsq','W':'dFsq/sig'} |
---|
[1969] | 575 | viewChoice = {'L':[[0,0,1],[1,0,0],[0,1,0]],'K':[[0,1,0],[0,0,1],[1,0,0]],'H':[[1,0,0],[0,0,1],[0,1,0]]} |
---|
[1442] | 576 | try: |
---|
| 577 | keyCode = event.GetKeyCode() |
---|
| 578 | if keyCode > 255: |
---|
| 579 | keyCode = 0 |
---|
| 580 | key = chr(keyCode) |
---|
| 581 | except AttributeError: #if from OnKeyBox above |
---|
| 582 | key = str(event.key).upper() |
---|
[1966] | 583 | if key in ['C','H','K','L']: |
---|
| 584 | if key == 'C': |
---|
| 585 | Data['Zone'] = False |
---|
| 586 | key = 'L' |
---|
[1969] | 587 | Data['viewKey'] = key |
---|
[1442] | 588 | drawingData['viewPoint'][0] = drawingData['default'] |
---|
[1969] | 589 | drawingData['viewDir'] = np.array(viewChoice[key][0]) |
---|
| 590 | drawingData['viewUp'] = np.array(viewChoice[key][1]) |
---|
[1442] | 591 | drawingData['oldxy'] = [] |
---|
[1969] | 592 | if Data['Zone']: |
---|
| 593 | if key == 'L': |
---|
| 594 | Q = [-1,0,0,0] |
---|
| 595 | else: |
---|
| 596 | V0 = np.array(viewChoice[key][0]) |
---|
| 597 | V1 = np.array(viewChoice[key][1]) |
---|
| 598 | V0 = np.inner(Amat,V0) |
---|
| 599 | V1 = np.inner(Amat,V1) |
---|
| 600 | V0 /= nl.norm(V0) |
---|
| 601 | V1 /= nl.norm(V1) |
---|
| 602 | A = np.arccos(np.sum(V1*V0)) |
---|
| 603 | Q = G2mth.AV2Q(-A,viewChoice[key][2]) |
---|
[1976] | 604 | G2frame.G2plotNB.status.SetStatusText('zone = %s'%(str(viewChoice[key][0])),1) |
---|
[1969] | 605 | else: |
---|
| 606 | V0 = np.array(viewChoice[key][0]) |
---|
| 607 | V = np.inner(Bmat,V0) |
---|
| 608 | V /= np.sqrt(np.sum(V**2)) |
---|
| 609 | V *= np.array([0,0,1]) |
---|
| 610 | A = np.arccos(np.sum(V*V0)) |
---|
| 611 | Q = G2mth.AV2Q(-A,viewChoice[key][2]) |
---|
[1967] | 612 | drawingData['Quaternion'] = Q |
---|
[1966] | 613 | elif key in 'Z': |
---|
| 614 | Data['Zone'] = not Data['Zone'] |
---|
[1598] | 615 | elif key in 'B': |
---|
| 616 | ifBox = not ifBox |
---|
[1694] | 617 | elif key in ['+','=']: |
---|
[1442] | 618 | Data['Scale'] *= 1.25 |
---|
| 619 | elif key == '-': |
---|
| 620 | Data['Scale'] /= 1.25 |
---|
[1969] | 621 | elif key == 'P': |
---|
| 622 | vec = viewChoice[Data['viewKey']][0] |
---|
| 623 | drawingData['viewPoint'][0] -= vec |
---|
| 624 | elif key == 'N': |
---|
| 625 | vec = viewChoice[Data['viewKey']][0] |
---|
| 626 | drawingData['viewPoint'][0] += vec |
---|
[1442] | 627 | elif key == '0': |
---|
[1656] | 628 | drawingData['viewPoint'][0] = [0,0,0] |
---|
[1442] | 629 | Data['Scale'] = 1.0 |
---|
| 630 | elif key == 'I': |
---|
| 631 | Data['Iscale'] = not Data['Iscale'] |
---|
| 632 | elif key in Choice: |
---|
[1466] | 633 | Data['Type'] = Choice[key] |
---|
[1442] | 634 | Draw('key') |
---|
| 635 | |
---|
| 636 | Name = G2frame.PatternTree.GetItemText(G2frame.PatternId) |
---|
[1909] | 637 | if Title and Title in G2frame.GetPhaseData(): #NB: save image as e.g. jpeg will fail if False; MyDir is unknown |
---|
[1442] | 638 | generalData = G2frame.GetPhaseData()[Title]['General'] |
---|
| 639 | cell = generalData['Cell'][1:7] |
---|
[1607] | 640 | Mydir = generalData['Mydir'] |
---|
[1442] | 641 | else: |
---|
[1909] | 642 | Title = 'Unknown' |
---|
[1442] | 643 | cell = [10,10,10,90,90,90] |
---|
[1607] | 644 | Mydir = G2frame.dirname |
---|
[1442] | 645 | drawingData = Data['Drawing'] |
---|
[1506] | 646 | Super = Data['Super'] |
---|
| 647 | SuperVec = [] |
---|
[1598] | 648 | if Super: |
---|
| 649 | SuperVec = np.array(Data['SuperVec'][0]) |
---|
[1442] | 650 | defaultViewPt = copy.copy(drawingData['viewPoint']) |
---|
| 651 | Amat,Bmat = G2lat.cell2AB(cell) #Amat - crystal to cartesian, Bmat - inverse |
---|
| 652 | Gmat,gmat = G2lat.cell2Gmat(cell) |
---|
| 653 | invcell = G2lat.Gmat2cell(Gmat) |
---|
| 654 | A4mat = np.concatenate((np.concatenate((Amat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
| 655 | B4mat = np.concatenate((np.concatenate((Bmat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
| 656 | drawingData['Quaternion'] = G2mth.AV2Q(2*np.pi,np.inner(Bmat,[0,0,1])) |
---|
| 657 | Wt = np.array([255,255,255]) |
---|
| 658 | Rd = np.array([255,0,0]) |
---|
| 659 | Gr = np.array([0,255,0]) |
---|
| 660 | wxGreen = wx.Colour(0,255,0) |
---|
| 661 | Bl = np.array([0,0,255]) |
---|
| 662 | Or = np.array([255,128,0]) |
---|
| 663 | wxOrange = wx.Colour(255,128,0) |
---|
| 664 | 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]]) |
---|
| 665 | uEdges = np.array([ |
---|
[1598] | 666 | [uBox[0],uBox[1]],[uBox[0],uBox[3]],[uBox[0],uBox[4]],[uBox[1],uBox[2]], |
---|
| 667 | [uBox[2],uBox[3]],[uBox[1],uBox[5]],[uBox[2],uBox[6]],[uBox[3],uBox[7]], |
---|
| 668 | [uBox[4],uBox[5]],[uBox[5],uBox[6]],[uBox[6],uBox[7]],[uBox[7],uBox[4]]]) |
---|
| 669 | uColors = [Rd,Gr,Bl, Wt,Wt,Wt, Wt,Wt,Wt, Wt,Wt,Wt] |
---|
[1442] | 670 | def FillHKLRC(): |
---|
| 671 | R = np.zeros(len(hklRef)) |
---|
| 672 | C = [] |
---|
| 673 | HKL = [] |
---|
| 674 | RC = [] |
---|
| 675 | for i,refl in enumerate(hklRef): |
---|
[1506] | 676 | H = refl[:3] |
---|
[1442] | 677 | if 'HKLF' in Name: |
---|
[1504] | 678 | Fosq,sig,Fcsq = refl[5+Super:8+Super] |
---|
[1786] | 679 | if refl[3+Super] < 0: |
---|
| 680 | Fosq,sig,Fcsq = [0,1,0] |
---|
[1442] | 681 | else: |
---|
[1504] | 682 | Fosq,sig,Fcsq = refl[8+Super],1.0,refl[9+Super] |
---|
[1598] | 683 | if Super: |
---|
| 684 | HKL.append(H+SuperVec*refl[3]) |
---|
| 685 | else: |
---|
| 686 | HKL.append(H) |
---|
[1442] | 687 | if Data['Type'] == 'Unit': |
---|
| 688 | R[i] = 0.1 |
---|
| 689 | C.append(Gr) |
---|
| 690 | elif Data['Type'] == 'Fosq': |
---|
| 691 | if Fosq > 0: |
---|
| 692 | R[i] = Fosq |
---|
| 693 | C.append(Gr) |
---|
| 694 | else: |
---|
| 695 | R[i] = -Fosq |
---|
| 696 | C.append(Rd) |
---|
| 697 | elif Data['Type'] == 'Fo': |
---|
| 698 | if Fosq > 0: |
---|
| 699 | R[i] = np.sqrt(Fosq) |
---|
| 700 | C.append(Gr) |
---|
| 701 | else: |
---|
| 702 | R[i] = np.sqrt(-Fosq) |
---|
| 703 | C.append(Rd) |
---|
| 704 | elif Data['Type'] == 'dFsq/sig': |
---|
| 705 | dFsig = (Fosq-Fcsq)/sig |
---|
| 706 | if dFsig > 0: |
---|
| 707 | R[i] = dFsig |
---|
| 708 | C.append(Gr) |
---|
| 709 | else: |
---|
| 710 | R[i] = -dFsig |
---|
| 711 | C.append(Rd) |
---|
| 712 | elif Data['Type'] == 'dFsq': |
---|
| 713 | dF = Fosq-Fcsq |
---|
| 714 | if dF > 0: |
---|
| 715 | R[i] = dF |
---|
| 716 | C.append(Gr) |
---|
| 717 | else: |
---|
| 718 | R[i] = -dF |
---|
| 719 | C.append(Rd) |
---|
| 720 | R /= np.max(R) |
---|
| 721 | R *= Data['Scale'] |
---|
[1506] | 722 | R = np.where(R<1.e-5,1.e-5,R) |
---|
[1442] | 723 | if Data['Iscale']: |
---|
| 724 | R = np.where(R<=1.,R,1.) |
---|
| 725 | C = np.array(C) |
---|
| 726 | C = (C.T*R).T |
---|
[1506] | 727 | R = np.ones_like(R)*0.05 |
---|
[1442] | 728 | return HKL,zip(list(R),C) |
---|
| 729 | |
---|
[1786] | 730 | def GetTruePosition(xy): |
---|
| 731 | View = glGetIntegerv(GL_VIEWPORT) |
---|
| 732 | Proj = glGetDoublev(GL_PROJECTION_MATRIX) |
---|
| 733 | Model = glGetDoublev(GL_MODELVIEW_MATRIX) |
---|
| 734 | Zmax = 1. |
---|
[1787] | 735 | xy = [int(xy[0]),int(View[3]-xy[1])] |
---|
[1786] | 736 | for i,ref in enumerate(hklRef): |
---|
[1787] | 737 | h,k,l = ref[:3] |
---|
[1786] | 738 | X,Y,Z = gluProject(h,k,l,Model,Proj,View) |
---|
| 739 | XY = [int(X),int(Y)] |
---|
[1787] | 740 | if np.allclose(xy,XY,atol=10) and Z < Zmax: |
---|
[1786] | 741 | Zmax = Z |
---|
[1787] | 742 | return [int(h),int(k),int(l)] |
---|
[1786] | 743 | |
---|
[1442] | 744 | def SetTranslation(newxy): |
---|
| 745 | #first get translation vector in screen coords. |
---|
| 746 | oldxy = drawingData['oldxy'] |
---|
| 747 | if not len(oldxy): oldxy = list(newxy) |
---|
| 748 | dxy = newxy-oldxy |
---|
| 749 | drawingData['oldxy'] = list(newxy) |
---|
| 750 | V = np.array([-dxy[0],dxy[1],0.]) |
---|
| 751 | #then transform to rotated crystal coordinates & apply to view point |
---|
| 752 | Q = drawingData['Quaternion'] |
---|
| 753 | V = np.inner(Bmat,G2mth.prodQVQ(G2mth.invQ(Q),V)) |
---|
| 754 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
| 755 | Tx += V[0]*0.1 |
---|
| 756 | Ty += V[1]*0.1 |
---|
| 757 | Tz += V[2]*0.1 |
---|
| 758 | drawingData['viewPoint'][0] = Tx,Ty,Tz |
---|
| 759 | |
---|
| 760 | def SetRotation(newxy): |
---|
| 761 | 'Perform a rotation in x-y space due to a left-mouse drag' |
---|
| 762 | #first get rotation vector in screen coords. & angle increment |
---|
| 763 | oldxy = drawingData['oldxy'] |
---|
| 764 | if not len(oldxy): oldxy = list(newxy) |
---|
| 765 | dxy = newxy-oldxy |
---|
| 766 | drawingData['oldxy'] = list(newxy) |
---|
| 767 | V = np.array([dxy[1],dxy[0],0.]) |
---|
| 768 | A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2) |
---|
| 769 | if not A: return # nothing changed, nothing to do |
---|
| 770 | # next transform vector back to xtal coordinates via inverse quaternion |
---|
| 771 | # & make new quaternion |
---|
| 772 | Q = drawingData['Quaternion'] |
---|
| 773 | V = G2mth.prodQVQ(G2mth.invQ(Q),np.inner(Bmat,V)) |
---|
| 774 | DQ = G2mth.AVdeg2Q(A,V) |
---|
| 775 | Q = G2mth.prodQQ(Q,DQ) |
---|
| 776 | drawingData['Quaternion'] = Q |
---|
| 777 | # finally get new view vector - last row of rotation matrix |
---|
| 778 | VD = np.inner(Bmat,G2mth.Q2Mat(Q)[2]) |
---|
| 779 | VD /= np.sqrt(np.sum(VD**2)) |
---|
| 780 | drawingData['viewDir'] = VD |
---|
| 781 | |
---|
| 782 | def SetRotationZ(newxy): |
---|
| 783 | #first get rotation vector (= view vector) in screen coords. & angle increment |
---|
| 784 | View = glGetIntegerv(GL_VIEWPORT) |
---|
| 785 | cent = [View[2]/2,View[3]/2] |
---|
| 786 | oldxy = drawingData['oldxy'] |
---|
| 787 | if not len(oldxy): oldxy = list(newxy) |
---|
| 788 | dxy = newxy-oldxy |
---|
| 789 | drawingData['oldxy'] = list(newxy) |
---|
| 790 | V = drawingData['viewDir'] |
---|
| 791 | A = [0,0] |
---|
| 792 | A[0] = dxy[1]*.25 |
---|
| 793 | A[1] = dxy[0]*.25 |
---|
| 794 | if newxy[0] > cent[0]: |
---|
| 795 | A[0] *= -1 |
---|
| 796 | if newxy[1] < cent[1]: |
---|
| 797 | A[1] *= -1 |
---|
| 798 | # next transform vector back to xtal coordinates & make new quaternion |
---|
| 799 | Q = drawingData['Quaternion'] |
---|
| 800 | V = np.inner(Amat,V) |
---|
| 801 | Qx = G2mth.AVdeg2Q(A[0],V) |
---|
| 802 | Qy = G2mth.AVdeg2Q(A[1],V) |
---|
| 803 | Q = G2mth.prodQQ(Q,Qx) |
---|
| 804 | Q = G2mth.prodQQ(Q,Qy) |
---|
| 805 | drawingData['Quaternion'] = Q |
---|
| 806 | |
---|
| 807 | def OnMouseDown(event): |
---|
| 808 | xy = event.GetPosition() |
---|
| 809 | drawingData['oldxy'] = list(xy) |
---|
| 810 | |
---|
| 811 | def OnMouseMove(event): |
---|
| 812 | if event.ShiftDown(): #don't want any inadvertant moves when picking |
---|
| 813 | return |
---|
| 814 | newxy = event.GetPosition() |
---|
| 815 | |
---|
| 816 | if event.Dragging(): |
---|
| 817 | if event.LeftIsDown(): |
---|
| 818 | SetRotation(newxy) |
---|
| 819 | Q = drawingData['Quaternion'] |
---|
| 820 | elif event.RightIsDown(): |
---|
| 821 | SetTranslation(newxy) |
---|
| 822 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
| 823 | elif event.MiddleIsDown(): |
---|
| 824 | SetRotationZ(newxy) |
---|
| 825 | Q = drawingData['Quaternion'] |
---|
| 826 | Draw('move') |
---|
[1787] | 827 | else: |
---|
| 828 | hkl = GetTruePosition(newxy) |
---|
| 829 | if hkl: |
---|
| 830 | h,k,l = hkl |
---|
[1969] | 831 | Page.canvas.SetToolTipString('%d,%d,%d'%(h,k,l)) |
---|
| 832 | G2frame.G2plotNB.status.SetStatusText('hkl = %d,%d,%d'%(h,k,l),1) |
---|
[1442] | 833 | |
---|
| 834 | def OnMouseWheel(event): |
---|
| 835 | if event.ShiftDown(): |
---|
| 836 | return |
---|
| 837 | drawingData['cameraPos'] += event.GetWheelRotation()/120. |
---|
| 838 | drawingData['cameraPos'] = max(0.1,min(20.00,drawingData['cameraPos'])) |
---|
| 839 | Draw('wheel') |
---|
| 840 | |
---|
| 841 | def SetBackground(): |
---|
| 842 | R,G,B,A = Page.camera['backColor'] |
---|
| 843 | glClearColor(R,G,B,A) |
---|
| 844 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
---|
| 845 | |
---|
| 846 | def SetLights(): |
---|
| 847 | glEnable(GL_DEPTH_TEST) |
---|
| 848 | glShadeModel(GL_SMOOTH) |
---|
| 849 | glEnable(GL_LIGHTING) |
---|
| 850 | glEnable(GL_LIGHT0) |
---|
| 851 | glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0) |
---|
| 852 | glLightfv(GL_LIGHT0,GL_AMBIENT,[1,1,1,.8]) |
---|
| 853 | glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1]) |
---|
| 854 | |
---|
[1598] | 855 | def RenderBox(x,y,z): |
---|
[1442] | 856 | xyz = np.array([x,y,z]) |
---|
| 857 | glEnable(GL_COLOR_MATERIAL) |
---|
| 858 | glLineWidth(1) |
---|
| 859 | glPushMatrix() |
---|
| 860 | glTranslate(x,y,z) |
---|
[1598] | 861 | glColor4ubv([0,0,0,0]) |
---|
[1442] | 862 | glBegin(GL_LINES) |
---|
| 863 | for line,color in zip(uEdges,uColors): |
---|
| 864 | glColor3ubv(color) |
---|
[1598] | 865 | glVertex3fv(line[0]) |
---|
| 866 | glVertex3fv(line[1]) |
---|
| 867 | glEnd() |
---|
| 868 | glPopMatrix() |
---|
| 869 | glColor4ubv([0,0,0,0]) |
---|
| 870 | glDisable(GL_COLOR_MATERIAL) |
---|
| 871 | |
---|
| 872 | def RenderUnitVectors(x,y,z): |
---|
| 873 | xyz = np.array([x,y,z]) |
---|
| 874 | glEnable(GL_COLOR_MATERIAL) |
---|
| 875 | glLineWidth(1) |
---|
| 876 | glPushMatrix() |
---|
| 877 | glTranslate(x,y,z) |
---|
| 878 | glBegin(GL_LINES) |
---|
| 879 | for line,color in zip(uEdges,uColors)[:3]: |
---|
| 880 | glColor3ubv(color) |
---|
[1969] | 881 | glVertex3fv([0,0,0]) |
---|
| 882 | # glVertex3fv(-line[1]) |
---|
[1442] | 883 | glVertex3fv(line[1]) |
---|
| 884 | glEnd() |
---|
| 885 | glPopMatrix() |
---|
| 886 | glColor4ubv([0,0,0,0]) |
---|
| 887 | glDisable(GL_COLOR_MATERIAL) |
---|
| 888 | |
---|
| 889 | def RenderDots(XYZ,RC): |
---|
| 890 | glEnable(GL_COLOR_MATERIAL) |
---|
| 891 | XYZ = np.array(XYZ) |
---|
| 892 | glPushMatrix() |
---|
| 893 | for xyz,rc in zip(XYZ,RC): |
---|
| 894 | x,y,z = xyz |
---|
| 895 | r,c = rc |
---|
[1969] | 896 | glColor3ubv(c) |
---|
[1442] | 897 | glPointSize(r*50) |
---|
| 898 | glBegin(GL_POINTS) |
---|
| 899 | glVertex3fv(xyz) |
---|
| 900 | glEnd() |
---|
| 901 | glPopMatrix() |
---|
| 902 | glColor4ubv([0,0,0,0]) |
---|
| 903 | glDisable(GL_COLOR_MATERIAL) |
---|
| 904 | |
---|
| 905 | def Draw(caller=''): |
---|
| 906 | #useful debug? |
---|
| 907 | # if caller: |
---|
| 908 | # print caller |
---|
| 909 | # end of useful debug |
---|
| 910 | G2frame.G2plotNB.status.SetStatusText('Plot type = %s for %s'%(Data['Type'],Name),1) |
---|
| 911 | VS = np.array(Page.canvas.GetSize()) |
---|
| 912 | aspect = float(VS[0])/float(VS[1]) |
---|
| 913 | cPos = drawingData['cameraPos'] |
---|
| 914 | Zclip = drawingData['Zclip']*cPos/20. |
---|
[1966] | 915 | if Data['Zone']: |
---|
| 916 | Zclip = 0.1 |
---|
[1442] | 917 | Q = drawingData['Quaternion'] |
---|
[1976] | 918 | Tx,Ty,Tz = drawingData['viewPoint'][0][:3] |
---|
[1442] | 919 | G,g = G2lat.cell2Gmat(cell) |
---|
| 920 | GS = G |
---|
| 921 | GS[0][1] = GS[1][0] = math.sqrt(GS[0][0]*GS[1][1]) |
---|
| 922 | GS[0][2] = GS[2][0] = math.sqrt(GS[0][0]*GS[2][2]) |
---|
| 923 | GS[1][2] = GS[2][1] = math.sqrt(GS[1][1]*GS[2][2]) |
---|
| 924 | |
---|
| 925 | HKL,RC = FillHKLRC() |
---|
| 926 | |
---|
| 927 | SetBackground() |
---|
| 928 | glInitNames() |
---|
| 929 | glPushName(0) |
---|
| 930 | |
---|
| 931 | glMatrixMode(GL_PROJECTION) |
---|
| 932 | glLoadIdentity() |
---|
| 933 | glViewport(0,0,VS[0],VS[1]) |
---|
| 934 | gluPerspective(20.,aspect,cPos-Zclip,cPos+Zclip) |
---|
[1967] | 935 | gluLookAt(0,0,cPos,0,0,0,0,1,0) |
---|
[1442] | 936 | SetLights() |
---|
| 937 | |
---|
| 938 | glMatrixMode(GL_MODELVIEW) |
---|
| 939 | glLoadIdentity() |
---|
| 940 | matRot = G2mth.Q2Mat(Q) |
---|
| 941 | matRot = np.concatenate((np.concatenate((matRot,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
| 942 | glMultMatrixf(matRot.T) |
---|
| 943 | glMultMatrixf(B4mat.T) |
---|
| 944 | glTranslate(-Tx,-Ty,-Tz) |
---|
| 945 | x,y,z = drawingData['viewPoint'][0] |
---|
[1598] | 946 | if ifBox: |
---|
| 947 | RenderBox(x,y,z) |
---|
| 948 | else: |
---|
| 949 | RenderUnitVectors(x,y,z) |
---|
[1442] | 950 | RenderUnitVectors(0,0,0) |
---|
| 951 | RenderDots(HKL,RC) |
---|
| 952 | time0 = time.time() |
---|
| 953 | if Page.context: Page.canvas.SetCurrent(Page.context) # wx 2.9 fix |
---|
| 954 | Page.canvas.SwapBuffers() |
---|
| 955 | |
---|
| 956 | # PlotStructure execution starts here (N.B. initialization above) |
---|
| 957 | try: |
---|
| 958 | plotNum = G2frame.G2plotNB.plotList.index('3D Structure Factors') |
---|
| 959 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 960 | except ValueError: |
---|
| 961 | Plot = G2frame.G2plotNB.addOgl('3D Structure Factors') |
---|
| 962 | plotNum = G2frame.G2plotNB.plotList.index('3D Structure Factors') |
---|
| 963 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 964 | Page.views = False |
---|
| 965 | view = False |
---|
| 966 | altDown = False |
---|
| 967 | Font = Page.GetFont() |
---|
| 968 | Page.SetFocus() |
---|
| 969 | Page.Choice = None |
---|
[1966] | 970 | choice = [' save as/key:','jpeg','tiff','bmp','h: view down h','k: view down k','l: view down l', |
---|
| 971 | 'z: zero zone toggle','c: reset to default','b: toggle box ','+: increase scale','-: decrease scale', |
---|
| 972 | 'f: Fobs','s: Fobs**2','u: unit','d: Fo-Fc','w: DF/sig','i: toggle intensity scaling'] |
---|
[1442] | 973 | cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,choices=choice) |
---|
| 974 | cb.Bind(wx.EVT_COMBOBOX, OnKeyBox) |
---|
| 975 | cb.SetValue(' save as/key:') |
---|
| 976 | Page.canvas.Bind(wx.EVT_MOUSEWHEEL, OnMouseWheel) |
---|
| 977 | Page.canvas.Bind(wx.EVT_LEFT_DOWN, OnMouseDown) |
---|
| 978 | Page.canvas.Bind(wx.EVT_RIGHT_DOWN, OnMouseDown) |
---|
| 979 | Page.canvas.Bind(wx.EVT_MIDDLE_DOWN, OnMouseDown) |
---|
| 980 | Page.canvas.Bind(wx.EVT_KEY_UP, OnKey) |
---|
| 981 | Page.canvas.Bind(wx.EVT_MOTION, OnMouseMove) |
---|
| 982 | # Page.canvas.Bind(wx.EVT_SIZE, OnSize) |
---|
| 983 | Page.camera['position'] = drawingData['cameraPos'] |
---|
| 984 | Page.camera['viewPoint'] = np.inner(Amat,drawingData['viewPoint'][0]) |
---|
| 985 | Page.camera['backColor'] = np.array(list(drawingData['backColor'])+[0,])/255. |
---|
[1656] | 986 | Page.controls = Data |
---|
[1442] | 987 | try: |
---|
| 988 | Page.canvas.SetCurrent() |
---|
| 989 | except: |
---|
| 990 | pass |
---|
| 991 | Draw('main') |
---|
| 992 | # if firstCall: Draw('main') # draw twice the first time that graphics are displayed |
---|
| 993 | |
---|
[762] | 994 | |
---|
| 995 | ################################################################################ |
---|
| 996 | ##### PlotPatterns |
---|
| 997 | ################################################################################ |
---|
| 998 | |
---|
[1199] | 999 | def PlotPatterns(G2frame,newPlot=False,plotType='PWDR'): |
---|
[762] | 1000 | '''Powder pattern plotting package - displays single or multiple powder patterns as intensity vs |
---|
[796] | 1001 | 2-theta, q or TOF. Can display multiple patterns as "waterfall plots" or contour plots. Log I |
---|
[762] | 1002 | plotting available. |
---|
| 1003 | ''' |
---|
[1017] | 1004 | global exclLines |
---|
[1382] | 1005 | global DifLine |
---|
| 1006 | global Ymax |
---|
[1199] | 1007 | plottype = plotType |
---|
[1672] | 1008 | #patch |
---|
| 1009 | data = G2frame.PatternTree.GetItemPyData(G2frame.PatternId) |
---|
| 1010 | if 'Offset' not in data[0] and plotType in ['PWDR','SASD']: #plot offset data |
---|
| 1011 | data[0].update({'Offset':[0.0,0.0],'delOffset':0.02,'refOffset':-1.0, |
---|
[1715] | 1012 | 'refDelt':0.01,}) |
---|
[1672] | 1013 | G2frame.PatternTree.SetItemPyData(G2frame.PickId,data) |
---|
| 1014 | #end patch |
---|
[762] | 1015 | def OnPlotKeyPress(event): |
---|
[1401] | 1016 | try: #one way to check if key stroke will work on plot |
---|
| 1017 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
| 1018 | except TypeError: |
---|
| 1019 | G2frame.G2plotNB.status.SetStatusText('Select '+plottype+' pattern first',1) |
---|
| 1020 | return |
---|
[762] | 1021 | newPlot = False |
---|
[1341] | 1022 | if event.key == 'w': |
---|
[1339] | 1023 | G2frame.Weight = not G2frame.Weight |
---|
[1341] | 1024 | if not G2frame.Weight and 'PWDR' in plottype: |
---|
[762] | 1025 | G2frame.SinglePlot = True |
---|
| 1026 | newPlot = True |
---|
[1205] | 1027 | elif event.key == 'e' and 'SASD' in plottype: |
---|
| 1028 | G2frame.ErrorBars = not G2frame.ErrorBars |
---|
[1300] | 1029 | elif event.key == 'b': |
---|
[1205] | 1030 | G2frame.SubBack = not G2frame.SubBack |
---|
| 1031 | if not G2frame.SubBack: |
---|
[792] | 1032 | G2frame.SinglePlot = True |
---|
[762] | 1033 | elif event.key == 'n': |
---|
| 1034 | if G2frame.Contour: |
---|
| 1035 | pass |
---|
| 1036 | else: |
---|
[1205] | 1037 | G2frame.logPlot = not G2frame.logPlot |
---|
| 1038 | if not G2frame.logPlot: |
---|
[1672] | 1039 | Pattern[0]['Offset'][0] = 0 |
---|
[762] | 1040 | newPlot = True |
---|
[1368] | 1041 | elif event.key == 's' and 'PWDR' in plottype: |
---|
| 1042 | if G2frame.Contour: |
---|
| 1043 | choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] |
---|
| 1044 | choice.sort() |
---|
| 1045 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice) |
---|
| 1046 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 1047 | sel = dlg.GetSelection() |
---|
| 1048 | G2frame.ContourColor = choice[sel] |
---|
| 1049 | else: |
---|
| 1050 | G2frame.ContourColor = 'Paired' |
---|
| 1051 | dlg.Destroy() |
---|
| 1052 | elif G2frame.SinglePlot: |
---|
[1715] | 1053 | G2frame.plotStyle['sqrtPlot'] = not G2frame.plotStyle['sqrtPlot'] |
---|
| 1054 | if G2frame.plotStyle['sqrtPlot']: |
---|
[1672] | 1055 | Pattern[0]['delOffset'] = .002 |
---|
| 1056 | Pattern[0]['refOffset'] = -1.0 |
---|
| 1057 | Pattern[0]['refDelt'] = .001 |
---|
[1368] | 1058 | else: |
---|
[1672] | 1059 | Pattern[0]['delOffset'] = .02 |
---|
| 1060 | Pattern[0]['refOffset'] = -1.0 |
---|
| 1061 | Pattern[0]['refDelt'] = .01 |
---|
[1368] | 1062 | newPlot = True |
---|
[1366] | 1063 | elif event.key == 'u' and (G2frame.Contour or not G2frame.SinglePlot): |
---|
[762] | 1064 | if G2frame.Contour: |
---|
| 1065 | G2frame.Cmax = min(1.0,G2frame.Cmax*1.2) |
---|
[1672] | 1066 | elif Pattern[0]['Offset'][0] < 100.: |
---|
| 1067 | Pattern[0]['Offset'][0] += 1. |
---|
[1369] | 1068 | elif event.key == 'd' and (G2frame.Contour or not G2frame.SinglePlot): |
---|
[762] | 1069 | if G2frame.Contour: |
---|
| 1070 | G2frame.Cmax = max(0.0,G2frame.Cmax*0.8) |
---|
[1672] | 1071 | elif Pattern[0]['Offset'][0] > 0.: |
---|
| 1072 | Pattern[0]['Offset'][0] -= 1. |
---|
[1366] | 1073 | elif event.key == 'l' and not G2frame.SinglePlot: |
---|
[1672] | 1074 | Pattern[0]['Offset'][1] -= 1. |
---|
[1366] | 1075 | elif event.key == 'r' and not G2frame.SinglePlot: |
---|
[1672] | 1076 | Pattern[0]['Offset'][1] += 1. |
---|
[1366] | 1077 | elif event.key == 'o' and not G2frame.SinglePlot: |
---|
[1205] | 1078 | G2frame.Cmax = 1.0 |
---|
[1672] | 1079 | Pattern[0]['Offset'] = [0,0] |
---|
[1300] | 1080 | elif event.key == 'c' and 'PWDR' in plottype: |
---|
[762] | 1081 | newPlot = True |
---|
[1205] | 1082 | if not G2frame.Contour: |
---|
[762] | 1083 | G2frame.SinglePlot = False |
---|
[1672] | 1084 | Pattern[0]['Offset'] = [0.,0.] |
---|
[1341] | 1085 | else: |
---|
| 1086 | G2frame.SinglePlot = True |
---|
| 1087 | G2frame.Contour = not G2frame.Contour |
---|
[1205] | 1088 | elif event.key == 'q': |
---|
| 1089 | if 'PWDR' in plottype: |
---|
| 1090 | newPlot = True |
---|
[1715] | 1091 | G2frame.plotStyle['qPlot'] = not G2frame.plotStyle['qPlot'] |
---|
| 1092 | G2frame.plotStyle['dPlot'] = False |
---|
[1205] | 1093 | elif 'SASD' in plottype: |
---|
| 1094 | newPlot = True |
---|
[1715] | 1095 | G2frame.plotStyle['sqPlot'] = not G2frame.plotStyle['sqPlot'] |
---|
[1462] | 1096 | elif event.key == 't' and 'PWDR' in plottype: |
---|
[1715] | 1097 | G2frame.plotStyle['dPlot'] = not G2frame.plotStyle['dPlot'] |
---|
| 1098 | G2frame.plotStyle['qPlot'] = False |
---|
[1462] | 1099 | newPlot = True |
---|
[1366] | 1100 | elif event.key == 'm': |
---|
[1715] | 1101 | G2frame.plotStyle['sqrtPlot'] = False |
---|
[1368] | 1102 | G2frame.SinglePlot = not G2frame.SinglePlot |
---|
[762] | 1103 | newPlot = True |
---|
[1694] | 1104 | elif event.key in ['+','=']: |
---|
[762] | 1105 | if G2frame.PickId: |
---|
| 1106 | G2frame.PickId = False |
---|
[1205] | 1107 | elif event.key == 'i' and G2frame.Contour: #for smoothing contour plot |
---|
[762] | 1108 | choice = ['nearest','bilinear','bicubic','spline16','spline36','hanning', |
---|
| 1109 | 'hamming','hermite','kaiser','quadric','catrom','gaussian','bessel', |
---|
| 1110 | 'mitchell','sinc','lanczos'] |
---|
| 1111 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Interpolation',choice) |
---|
| 1112 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 1113 | sel = dlg.GetSelection() |
---|
| 1114 | G2frame.Interpolate = choice[sel] |
---|
| 1115 | else: |
---|
| 1116 | G2frame.Interpolate = 'nearest' |
---|
| 1117 | dlg.Destroy() |
---|
[1583] | 1118 | else: |
---|
[1652] | 1119 | # print 'no binding for key',event.key |
---|
[1583] | 1120 | #GSASIIpath.IPyBreak() |
---|
| 1121 | return |
---|
[1204] | 1122 | wx.CallAfter(PlotPatterns,G2frame,newPlot=newPlot,plotType=plottype) |
---|
[762] | 1123 | |
---|
| 1124 | def OnMotion(event): |
---|
| 1125 | xpos = event.xdata |
---|
| 1126 | if xpos: #avoid out of frame mouse position |
---|
| 1127 | ypos = event.ydata |
---|
| 1128 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 1129 | try: |
---|
[796] | 1130 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
[1715] | 1131 | if G2frame.plotStyle['qPlot'] and 'PWDR' in plottype: |
---|
[1475] | 1132 | q = xpos |
---|
| 1133 | dsp = 2.*np.pi/q |
---|
| 1134 | try: |
---|
| 1135 | xpos = G2lat.Dsp2pos(Parms,2.0*np.pi/xpos) |
---|
| 1136 | except ValueError: #avoid bad value in asin beyond upper limit |
---|
| 1137 | pass |
---|
| 1138 | elif 'SASD' in plottype: |
---|
| 1139 | q = xpos |
---|
| 1140 | dsp = 2.*np.pi/q |
---|
[1715] | 1141 | elif G2frame.plotStyle['dPlot']: |
---|
[1475] | 1142 | dsp = xpos |
---|
| 1143 | q = 2.*np.pi/dsp |
---|
| 1144 | xpos = G2lat.Dsp2pos(Parms,xpos) |
---|
[1519] | 1145 | elif G2frame.Contour and 'T' in Parms['Type'][0]: |
---|
| 1146 | xpos = X[xpos] |
---|
| 1147 | dsp = G2lat.Pos2dsp(Parms,xpos) |
---|
| 1148 | q = 2.*np.pi/dsp |
---|
[1475] | 1149 | else: |
---|
| 1150 | dsp = G2lat.Pos2dsp(Parms,xpos) |
---|
| 1151 | q = 2.*np.pi/dsp |
---|
| 1152 | if G2frame.Contour: #PWDR only |
---|
| 1153 | if 'C' in Parms['Type'][0]: |
---|
| 1154 | G2frame.G2plotNB.status.SetStatusText('2-theta =%9.3f d =%9.5f q = %9.5f pattern ID =%5d'%(xpos,dsp,q,int(ypos)),1) |
---|
[792] | 1155 | else: |
---|
[1475] | 1156 | G2frame.G2plotNB.status.SetStatusText('TOF =%9.3f d =%9.5f q = %9.5f pattern ID =%5d'%(xpos,dsp,q,int(ypos)),1) |
---|
| 1157 | else: |
---|
| 1158 | if 'C' in Parms['Type'][0]: |
---|
[1204] | 1159 | if 'PWDR' in plottype: |
---|
[1715] | 1160 | if G2frame.plotStyle['sqrtPlot']: |
---|
[1370] | 1161 | G2frame.G2plotNB.status.SetStatusText('2-theta =%9.3f d =%9.5f q = %9.5f sqrt(Intensity) =%9.2f'%(xpos,dsp,q,ypos),1) |
---|
| 1162 | else: |
---|
| 1163 | G2frame.G2plotNB.status.SetStatusText('2-theta =%9.3f d =%9.5f q = %9.5f Intensity =%9.2f'%(xpos,dsp,q,ypos),1) |
---|
[1204] | 1164 | elif 'SASD' in plottype: |
---|
[1475] | 1165 | G2frame.G2plotNB.status.SetStatusText('q =%12.5g Intensity =%12.5g d =%9.1f'%(q,ypos,dsp),1) |
---|
[1463] | 1166 | else: |
---|
[1715] | 1167 | if G2frame.plotStyle['sqrtPlot']: |
---|
[1475] | 1168 | G2frame.G2plotNB.status.SetStatusText('TOF =%9.3f d =%9.5f q =%9.5f sqrt(Intensity) =%9.2f'%(xpos,dsp,q,ypos),1) |
---|
[1370] | 1169 | else: |
---|
[1475] | 1170 | G2frame.G2plotNB.status.SetStatusText('TOF =%9.3f d =%9.5f q =%9.5f Intensity =%9.2f'%(xpos,dsp,q,ypos),1) |
---|
[762] | 1171 | if G2frame.itemPicked: |
---|
[1237] | 1172 | Page.canvas.SetToolTipString('%9.5f'%(xpos)) |
---|
[762] | 1173 | if G2frame.PickId: |
---|
| 1174 | found = [] |
---|
[1582] | 1175 | pickIdText = G2frame.PatternTree.GetItemText(G2frame.PickId) |
---|
| 1176 | if pickIdText in ['Index Peak List','Unit Cells List','Reflection Lists'] or \ |
---|
[1592] | 1177 | 'PWDR' in pickIdText: |
---|
[1582] | 1178 | indx = -1 |
---|
| 1179 | if pickIdText in ['Index Peak List','Unit Cells List',]: |
---|
| 1180 | indx = -2 |
---|
[1933] | 1181 | if len(G2frame.HKL): |
---|
[762] | 1182 | view = Page.toolbar._views.forward()[0][:2] |
---|
| 1183 | wid = view[1]-view[0] |
---|
[1933] | 1184 | found = G2frame.HKL[np.where(np.fabs(G2frame.HKL.T[indx]-xpos) < 0.002*wid)] |
---|
[762] | 1185 | if len(found): |
---|
[1571] | 1186 | if len(found[0]) > 6: #SS reflections |
---|
| 1187 | h,k,l,m = found[0][:4] |
---|
| 1188 | Page.canvas.SetToolTipString('%d,%d,%d,%d'%(int(h),int(k),int(l),int(m))) |
---|
| 1189 | else: |
---|
| 1190 | h,k,l = found[0][:3] |
---|
| 1191 | Page.canvas.SetToolTipString('%d,%d,%d'%(int(h),int(k),int(l))) |
---|
[762] | 1192 | else: |
---|
| 1193 | Page.canvas.SetToolTipString('') |
---|
| 1194 | |
---|
| 1195 | except TypeError: |
---|
[1401] | 1196 | G2frame.G2plotNB.status.SetStatusText('Select '+plottype+' pattern first',1) |
---|
[1237] | 1197 | |
---|
| 1198 | def OnPress(event): #ugh - this removes a matplotlib error for mouse clicks in log plots |
---|
| 1199 | olderr = np.seterr(invalid='ignore') |
---|
[762] | 1200 | |
---|
| 1201 | def OnPick(event): |
---|
[1889] | 1202 | '''Respond to an item being picked. This usually means that the item |
---|
| 1203 | will be dragged with the mouse. |
---|
| 1204 | ''' |
---|
| 1205 | def OnDragMarker(event): |
---|
| 1206 | '''Respond to dragging of a plot Marker |
---|
| 1207 | ''' |
---|
| 1208 | Page.canvas.restore_region(savedplot) |
---|
| 1209 | G2frame.itemPicked.set_data([event.xdata], [event.ydata]) |
---|
| 1210 | Page.figure.gca().draw_artist(G2frame.itemPicked) |
---|
| 1211 | Page.canvas.blit(Page.figure.gca().bbox) |
---|
| 1212 | def OnDragLine(event): |
---|
| 1213 | '''Respond to dragging of a plot line |
---|
| 1214 | ''' |
---|
| 1215 | Page.canvas.restore_region(savedplot) |
---|
| 1216 | coords = G2frame.itemPicked.get_data() |
---|
| 1217 | coords[0][0] = coords[0][1] = event.xdata |
---|
| 1218 | coords = G2frame.itemPicked.set_data(coords) |
---|
| 1219 | Page.figure.gca().draw_artist(G2frame.itemPicked) |
---|
| 1220 | Page.canvas.blit(Page.figure.gca().bbox) |
---|
| 1221 | |
---|
[762] | 1222 | if G2frame.itemPicked is not None: return |
---|
| 1223 | PatternId = G2frame.PatternId |
---|
| 1224 | try: |
---|
[796] | 1225 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
[762] | 1226 | except TypeError: |
---|
| 1227 | return |
---|
| 1228 | PickId = G2frame.PickId |
---|
| 1229 | pick = event.artist |
---|
[1237] | 1230 | mouse = event.mouseevent |
---|
[762] | 1231 | xpos = pick.get_xdata() |
---|
| 1232 | ypos = pick.get_ydata() |
---|
| 1233 | ind = event.ind |
---|
| 1234 | xy = list(zip(np.take(xpos,ind),np.take(ypos,ind))[0]) |
---|
[1889] | 1235 | # convert from plot units |
---|
| 1236 | if G2frame.plotStyle['qPlot']: #qplot - convert back to 2-theta |
---|
| 1237 | xy[0] = G2lat.Dsp2pos(Parms,2*np.pi/xy[0]) |
---|
| 1238 | elif G2frame.plotStyle['dPlot']: #dplot - convert back to 2-theta |
---|
| 1239 | xy[0] = G2lat.Dsp2pos(Parms,xy[0]) |
---|
| 1240 | if G2frame.plotStyle['sqrtPlot']: |
---|
| 1241 | xy[1] = xy[1]**2 |
---|
[762] | 1242 | if G2frame.PatternTree.GetItemText(PickId) == 'Peak List': |
---|
[1343] | 1243 | if ind.all() != [0] and ObsLine[0].get_label() in str(pick): #picked a data point |
---|
[792] | 1244 | data = G2frame.PatternTree.GetItemPyData(G2frame.PickId) |
---|
[1190] | 1245 | XY = G2mth.setPeakparms(Parms,Parms2,xy[0],xy[1]) |
---|
[1445] | 1246 | data['peaks'].append(XY) |
---|
| 1247 | data['sigDict'] = {} #now invalid |
---|
[762] | 1248 | G2pdG.UpdatePeakGrid(G2frame,data) |
---|
[1199] | 1249 | PlotPatterns(G2frame,plotType=plottype) |
---|
[762] | 1250 | else: #picked a peak list line |
---|
| 1251 | G2frame.itemPicked = pick |
---|
| 1252 | elif G2frame.PatternTree.GetItemText(PickId) == 'Limits': |
---|
| 1253 | if ind.all() != [0]: #picked a data point |
---|
| 1254 | LimitId = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits') |
---|
| 1255 | data = G2frame.PatternTree.GetItemPyData(LimitId) |
---|
[1715] | 1256 | if G2frame.plotStyle['qPlot']: #qplot - convert back to 2-theta |
---|
[1475] | 1257 | xy[0] = G2lat.Dsp2pos(Parms,2*np.pi/xy[0]) |
---|
[1715] | 1258 | elif G2frame.plotStyle['dPlot']: #dplot - convert back to 2-theta |
---|
[1475] | 1259 | xy[0] = G2lat.Dsp2pos(Parms,xy[0]) |
---|
[1017] | 1260 | if G2frame.ifGetExclude: |
---|
| 1261 | excl = [0,0] |
---|
| 1262 | excl[0] = max(data[1][0],min(xy[0],data[1][1])) |
---|
| 1263 | excl[1] = excl[0]+0.1 |
---|
| 1264 | data.append(excl) |
---|
| 1265 | G2frame.ifGetExclude = False |
---|
| 1266 | else: |
---|
| 1267 | if mouse.button==1: |
---|
| 1268 | data[1][0] = min(xy[0],data[1][1]) |
---|
| 1269 | if mouse.button==3: |
---|
| 1270 | data[1][1] = max(xy[0],data[1][0]) |
---|
[762] | 1271 | G2frame.PatternTree.SetItemPyData(LimitId,data) |
---|
[1221] | 1272 | G2pdG.UpdateLimitsGrid(G2frame,data,plottype) |
---|
[1199] | 1273 | wx.CallAfter(PlotPatterns,G2frame,plotType=plottype) |
---|
[762] | 1274 | else: #picked a limit line |
---|
[1889] | 1275 | # prepare to animate move of line |
---|
[762] | 1276 | G2frame.itemPicked = pick |
---|
[1889] | 1277 | pick.set_linestyle(':') # set line as dotted |
---|
| 1278 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 1279 | Plot = Page.figure.gca() |
---|
| 1280 | Page.canvas.draw() # refresh without dotted line & save bitmap |
---|
| 1281 | savedplot = Page.canvas.copy_from_bbox(Page.figure.gca().bbox) |
---|
| 1282 | G2frame.cid = Page.canvas.mpl_connect('motion_notify_event', OnDragLine) |
---|
| 1283 | pick.set_linestyle('--') # back to dashed |
---|
| 1284 | |
---|
[1237] | 1285 | elif G2frame.PatternTree.GetItemText(PickId) == 'Models': |
---|
| 1286 | if ind.all() != [0]: #picked a data point |
---|
| 1287 | LimitId = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits') |
---|
| 1288 | data = G2frame.PatternTree.GetItemPyData(LimitId) |
---|
| 1289 | if mouse.button==1: |
---|
| 1290 | data[1][0] = min(xy[0],data[1][1]) |
---|
| 1291 | if mouse.button==3: |
---|
| 1292 | data[1][1] = max(xy[0],data[1][0]) |
---|
| 1293 | G2frame.PatternTree.SetItemPyData(LimitId,data) |
---|
| 1294 | wx.CallAfter(PlotPatterns,G2frame,plotType=plottype) |
---|
| 1295 | else: #picked a limit line |
---|
| 1296 | G2frame.itemPicked = pick |
---|
[1889] | 1297 | elif (G2frame.PatternTree.GetItemText(PickId) == 'Reflection Lists' or |
---|
| 1298 | 'PWDR' in G2frame.PatternTree.GetItemText(PickId) |
---|
| 1299 | ): |
---|
[762] | 1300 | G2frame.itemPicked = pick |
---|
| 1301 | pick = str(pick) |
---|
[1889] | 1302 | elif G2frame.PatternTree.GetItemText(PickId) == 'Background': |
---|
[1894] | 1303 | # selected a fixed background point. Can move it or delete it. |
---|
[1889] | 1304 | for mode,id in G2frame.dataFrame.wxID_BackPts.iteritems(): # what menu is selected? |
---|
| 1305 | if G2frame.dataFrame.BackMenu.FindItemById(id).IsChecked(): |
---|
| 1306 | break |
---|
| 1307 | # mode will be 'Add' or 'Move' or 'Del' |
---|
| 1308 | if pick.get_marker() == 'D': |
---|
| 1309 | # find the closest point |
---|
| 1310 | backDict = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Background'))[1] |
---|
| 1311 | d2 = [(x-xy[0])**2+(y-xy[1])**2 for x,y in backDict['FixedPoints']] |
---|
| 1312 | G2frame.fixPtMarker = d2.index(min(d2)) |
---|
| 1313 | if mode == 'Move': |
---|
| 1314 | # animate move of FixedBkg marker |
---|
| 1315 | G2frame.itemPicked = pick |
---|
| 1316 | pick.set_marker('|') # change the point appearance |
---|
| 1317 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 1318 | Plot = Page.figure.gca() |
---|
| 1319 | Page.canvas.draw() # refresh with changed point & save bitmap |
---|
| 1320 | savedplot = Page.canvas.copy_from_bbox(Page.figure.gca().bbox) |
---|
| 1321 | G2frame.cid = Page.canvas.mpl_connect('motion_notify_event', OnDragMarker) |
---|
| 1322 | pick.set_marker('D') # put it back |
---|
| 1323 | elif mode == 'Del': |
---|
| 1324 | del backDict['FixedPoints'][G2frame.fixPtMarker] |
---|
| 1325 | wx.CallAfter(PlotPatterns,G2frame,plotType=plottype) |
---|
| 1326 | return |
---|
| 1327 | def OnRelease(event): # mouse release from item pick or background pt add/move/del |
---|
| 1328 | plotNum = G2frame.G2plotNB.plotList.index('Powder Patterns') |
---|
| 1329 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 1330 | if G2frame.cid is not None: # if there is a drag connection, delete it |
---|
| 1331 | Page.canvas.mpl_disconnect(G2frame.cid) |
---|
| 1332 | G2frame.cid = None |
---|
| 1333 | PickId = G2frame.PickId # points to item in tree |
---|
| 1334 | if G2frame.PatternTree.GetItemText(PickId) == 'Background' and event.xdata: |
---|
[1894] | 1335 | if Page.toolbar._active: # prevent ops. if a toolbar zoom button pressed |
---|
| 1336 | return |
---|
[1889] | 1337 | # Background page, deal with fixed background points |
---|
| 1338 | if G2frame.SubBack or G2frame.Weight or G2frame.Contour or not G2frame.SinglePlot: |
---|
| 1339 | return |
---|
| 1340 | backDict = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Background'))[1] |
---|
| 1341 | if 'FixedPoints' not in backDict: backDict['FixedPoints'] = [] |
---|
| 1342 | try: |
---|
| 1343 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
| 1344 | except TypeError: |
---|
| 1345 | return |
---|
| 1346 | # unit conversions |
---|
| 1347 | xy = [event.xdata,event.ydata] |
---|
| 1348 | if G2frame.plotStyle['qPlot']: #qplot - convert back to 2-theta |
---|
| 1349 | xy[0] = G2lat.Dsp2pos(Parms,2*np.pi/xy[0]) |
---|
| 1350 | elif G2frame.plotStyle['dPlot']: #dplot - convert back to 2-theta |
---|
| 1351 | xy[0] = G2lat.Dsp2pos(Parms,xy[0]) |
---|
| 1352 | if G2frame.plotStyle['sqrtPlot']: |
---|
| 1353 | xy[1] = xy[1]**2 |
---|
| 1354 | for mode,id in G2frame.dataFrame.wxID_BackPts.iteritems(): # what menu item is selected? |
---|
| 1355 | if G2frame.dataFrame.BackMenu.FindItemById(id).IsChecked(): |
---|
| 1356 | break |
---|
| 1357 | if mode == 'Add': |
---|
| 1358 | backDict['FixedPoints'].append(xy) |
---|
| 1359 | Plot = Page.figure.gca() |
---|
| 1360 | Plot.plot(event.xdata,event.ydata,'rD',clip_on=False,picker=3.) |
---|
| 1361 | Page.canvas.draw() |
---|
| 1362 | return |
---|
| 1363 | elif G2frame.itemPicked is not None: # end of drag in move |
---|
| 1364 | backDict['FixedPoints'][G2frame.fixPtMarker] = xy |
---|
| 1365 | G2frame.itemPicked = None |
---|
| 1366 | wx.CallAfter(PlotPatterns,G2frame,plotType=plottype) |
---|
| 1367 | return |
---|
[762] | 1368 | |
---|
| 1369 | if G2frame.itemPicked is None: return |
---|
[1463] | 1370 | if str(DifLine[0]) == str(G2frame.itemPicked): |
---|
[1672] | 1371 | data = G2frame.PatternTree.GetItemPyData(PickId) |
---|
[1343] | 1372 | ypos = event.ydata |
---|
[1815] | 1373 | Pattern[0]['delOffset'] = -ypos/Ymax |
---|
[1343] | 1374 | G2frame.itemPicked = None |
---|
[1889] | 1375 | wx.CallAfter(PlotPatterns,G2frame,plotType=plottype) |
---|
[1343] | 1376 | return |
---|
[796] | 1377 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
[762] | 1378 | xpos = event.xdata |
---|
| 1379 | if G2frame.PatternTree.GetItemText(PickId) in ['Peak List','Limits'] and xpos: |
---|
| 1380 | lines = [] |
---|
| 1381 | for line in G2frame.Lines: |
---|
| 1382 | lines.append(line.get_xdata()[0]) |
---|
[1204] | 1383 | try: |
---|
| 1384 | lineNo = lines.index(G2frame.itemPicked.get_xdata()[0]) |
---|
| 1385 | except ValueError: |
---|
| 1386 | lineNo = -1 |
---|
[1017] | 1387 | if lineNo in [0,1] or lineNo in exclLines: |
---|
[762] | 1388 | LimitId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Limits') |
---|
[1743] | 1389 | limits = G2frame.PatternTree.GetItemPyData(LimitId) |
---|
[1017] | 1390 | id = lineNo/2+1 |
---|
| 1391 | id2 = lineNo%2 |
---|
[1715] | 1392 | if G2frame.plotStyle['qPlot'] and 'PWDR' in plottype: |
---|
[1743] | 1393 | limits[id][id2] = G2lat.Dsp2pos(Parms,2.*np.pi/xpos) |
---|
[1715] | 1394 | elif G2frame.plotStyle['dPlot'] and 'PWDR' in plottype: |
---|
[1743] | 1395 | limits[id][id2] = G2lat.Dsp2pos(Parms,xpos) |
---|
[762] | 1396 | else: |
---|
[1743] | 1397 | limits[id][id2] = xpos |
---|
| 1398 | if id > 1 and limits[id][0] > limits[id][1]: |
---|
| 1399 | limits[id].reverse() |
---|
| 1400 | limits[1][0] = min(max(limits[0][0],limits[1][0]),limits[1][1]) |
---|
| 1401 | limits[1][1] = max(min(limits[0][1],limits[1][1]),limits[1][0]) |
---|
[762] | 1402 | if G2frame.PatternTree.GetItemText(G2frame.PickId) == 'Limits': |
---|
[1744] | 1403 | G2pdG.UpdateLimitsGrid(G2frame,limits,plottype) |
---|
[1204] | 1404 | elif lineNo > 1: |
---|
[762] | 1405 | PeakId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Peak List') |
---|
[1743] | 1406 | peaks = G2frame.PatternTree.GetItemPyData(PeakId) |
---|
[762] | 1407 | if event.button == 3: |
---|
[1743] | 1408 | del peaks['peaks'][lineNo-2] |
---|
[762] | 1409 | else: |
---|
[1715] | 1410 | if G2frame.plotStyle['qPlot']: |
---|
[1743] | 1411 | peaks['peaks'][lineNo-2][0] = G2lat.Dsp2pos(Parms,2.*np.pi/xpos) |
---|
[1715] | 1412 | elif G2frame.plotStyle['dPlot']: |
---|
[1743] | 1413 | peaks['peaks'][lineNo-2][0] = G2lat.Dsp2pos(Parms,xpos) |
---|
[762] | 1414 | else: |
---|
[1743] | 1415 | peaks['peaks'][lineNo-2][0] = xpos |
---|
| 1416 | peaks['sigDict'] = {} #no longer valid |
---|
| 1417 | G2pdG.UpdatePeakGrid(G2frame,peaks) |
---|
[1237] | 1418 | elif G2frame.PatternTree.GetItemText(PickId) in ['Models',] and xpos: |
---|
| 1419 | lines = [] |
---|
| 1420 | for line in G2frame.Lines: |
---|
| 1421 | lines.append(line.get_xdata()[0]) |
---|
| 1422 | try: |
---|
| 1423 | lineNo = lines.index(G2frame.itemPicked.get_xdata()[0]) |
---|
| 1424 | except ValueError: |
---|
| 1425 | lineNo = -1 |
---|
| 1426 | if lineNo in [0,1]: |
---|
| 1427 | LimitId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Limits') |
---|
| 1428 | data = G2frame.PatternTree.GetItemPyData(LimitId) |
---|
| 1429 | data[1][lineNo] = xpos |
---|
| 1430 | data[1][0] = min(max(data[0][0],data[1][0]),data[1][1]) |
---|
| 1431 | data[1][1] = max(min(data[0][1],data[1][1]),data[1][0]) |
---|
[762] | 1432 | elif (G2frame.PatternTree.GetItemText(PickId) == 'Reflection Lists' or \ |
---|
| 1433 | 'PWDR' in G2frame.PatternTree.GetItemText(PickId)) and xpos: |
---|
[1973] | 1434 | Id = G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists') |
---|
| 1435 | # GSASIIpath.IPyBreak() |
---|
| 1436 | if Id: |
---|
| 1437 | Phases = G2frame.PatternTree.GetItemPyData(Id) |
---|
| 1438 | pick = str(G2frame.itemPicked).split('(')[1].strip(')') |
---|
| 1439 | if 'line' not in pick: #avoid data points, etc. |
---|
| 1440 | data = G2frame.PatternTree.GetItemPyData(PatternId) |
---|
| 1441 | num = Phases.keys().index(pick) |
---|
| 1442 | if num: |
---|
| 1443 | data[0]['refDelt'] = -(event.ydata-Pattern[0]['refOffset'])/(num*Ymax) |
---|
| 1444 | else: #1st row of refl ticks |
---|
| 1445 | data[0]['refOffset'] = event.ydata |
---|
[1199] | 1446 | PlotPatterns(G2frame,plotType=plottype) |
---|
[762] | 1447 | G2frame.itemPicked = None |
---|
| 1448 | |
---|
[1889] | 1449 | # beginning PlotPatterns execution |
---|
[762] | 1450 | try: |
---|
| 1451 | plotNum = G2frame.G2plotNB.plotList.index('Powder Patterns') |
---|
| 1452 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[1907] | 1453 | Plot = Page.figure.gca() #get previous powder plot & get limits |
---|
| 1454 | G2frame.xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
[762] | 1455 | Page.figure.clf() |
---|
| 1456 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
| 1457 | except ValueError: |
---|
[1245] | 1458 | if plottype == 'SASD': |
---|
| 1459 | G2frame.logPlot = True |
---|
| 1460 | G2frame.ErrorBars = True |
---|
[762] | 1461 | newPlot = True |
---|
| 1462 | G2frame.Cmax = 1.0 |
---|
| 1463 | Plot = G2frame.G2plotNB.addMpl('Powder Patterns').gca() |
---|
| 1464 | plotNum = G2frame.G2plotNB.plotList.index('Powder Patterns') |
---|
| 1465 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 1466 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
| 1467 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 1468 | Page.canvas.mpl_connect('pick_event', OnPick) |
---|
| 1469 | Page.canvas.mpl_connect('button_release_event', OnRelease) |
---|
[1237] | 1470 | Page.canvas.mpl_connect('button_press_event',OnPress) |
---|
[1281] | 1471 | if plottype == 'PWDR': # avoids a very nasty clash with KILL_FOCUS in SASD TextCtrl? |
---|
| 1472 | Page.SetFocus() |
---|
[762] | 1473 | G2frame.G2plotNB.status.DestroyChildren() |
---|
| 1474 | if G2frame.Contour: |
---|
[1205] | 1475 | Page.Choice = (' key press','d: lower contour max','u: raise contour max','o: reset contour max', |
---|
[762] | 1476 | 'i: interpolation method','s: color scheme','c: contour off') |
---|
| 1477 | else: |
---|
| 1478 | if G2frame.logPlot: |
---|
[1205] | 1479 | if 'PWDR' in plottype: |
---|
[1366] | 1480 | if G2frame.SinglePlot: |
---|
| 1481 | Page.Choice = (' key press','n: log(I) off', |
---|
[1462] | 1482 | 'c: contour on','q: toggle q plot','t: toggle d-spacing plot', |
---|
| 1483 | 'm: toggle multidata plot','w: toggle divide by sig','+: no selection') |
---|
[1366] | 1484 | else: |
---|
| 1485 | Page.Choice = (' key press','n: log(I) off', |
---|
| 1486 | 'd: offset down','l: offset left','r: offset right','u: offset up','o: reset offset', |
---|
[1462] | 1487 | 'c: contour on','q: toggle q plot','t: toggle d-spacing plot', |
---|
| 1488 | 'm: toggle multidata plot','w: toggle divide by sig','+: no selection') |
---|
[1205] | 1489 | elif 'SASD' in plottype: |
---|
[1366] | 1490 | if G2frame.SinglePlot: |
---|
| 1491 | Page.Choice = (' key press','b: toggle subtract background file','n: semilog on', |
---|
| 1492 | 'q: toggle S(q) plot','m: toggle multidata plot','w: toggle (Io-Ic)/sig plot','+: no selection') |
---|
| 1493 | else: |
---|
| 1494 | Page.Choice = (' key press','b: toggle subtract background file','n: semilog on', |
---|
| 1495 | 'd: offset down','l: offset left','r: offset right','u: offset up','o: reset offset', |
---|
| 1496 | 'q: toggle S(q) plot','m: toggle multidata plot','w: toggle (Io-Ic)/sig plot','+: no selection') |
---|
[762] | 1497 | else: |
---|
[1201] | 1498 | if 'PWDR' in plottype: |
---|
[1366] | 1499 | if G2frame.SinglePlot: |
---|
| 1500 | Page.Choice = (' key press', |
---|
[1368] | 1501 | 'b: toggle subtract background','n: log(I) on','s: toggle sqrt plot','c: contour on', |
---|
[1462] | 1502 | 'q: toggle q plot','t: toggle d-spacing plot','m: toggle multidata plot', |
---|
| 1503 | 'w: toggle divide by sig','+: no selection') |
---|
[1366] | 1504 | else: |
---|
| 1505 | Page.Choice = (' key press','l: offset left','r: offset right','d: offset down', |
---|
| 1506 | 'u: offset up','o: reset offset','b: toggle subtract background','n: log(I) on','c: contour on', |
---|
[1462] | 1507 | 'q: toggle q plot','t: toggle d-spacing plot','m: toggle multidata plot', |
---|
| 1508 | 'w: toggle divide by sig','+: no selection') |
---|
[1201] | 1509 | elif 'SASD' in plottype: |
---|
[1366] | 1510 | if G2frame.SinglePlot: |
---|
| 1511 | Page.Choice = (' key press','b: toggle subtract background file','n: loglog on','e: toggle error bars', |
---|
| 1512 | 'q: toggle S(q) plot','m: toggle multidata plot','w: toggle (Io-Ic)/sig plot','+: no selection') |
---|
| 1513 | else: |
---|
| 1514 | Page.Choice = (' key press','b: toggle subtract background file','n: loglog on','e: toggle error bars', |
---|
| 1515 | 'd: offset down','l: offset left','r: offset right','u: offset up','o: reset offset', |
---|
| 1516 | 'q: toggle S(q) plot','m: toggle multidata plot','w: toggle (Io-Ic)/sig plot','+: no selection') |
---|
[1889] | 1517 | G2frame.cid = None |
---|
[1237] | 1518 | Page.keyPress = OnPlotKeyPress |
---|
[762] | 1519 | PickId = G2frame.PickId |
---|
| 1520 | PatternId = G2frame.PatternId |
---|
| 1521 | colors=['b','g','r','c','m','k'] |
---|
| 1522 | Lines = [] |
---|
[1017] | 1523 | exclLines = [] |
---|
[1621] | 1524 | if G2frame.SinglePlot and PatternId: |
---|
[762] | 1525 | Pattern = G2frame.PatternTree.GetItemPyData(PatternId) |
---|
| 1526 | Pattern.append(G2frame.PatternTree.GetItemText(PatternId)) |
---|
| 1527 | PlotList = [Pattern,] |
---|
[796] | 1528 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, |
---|
[792] | 1529 | G2frame.PatternId, 'Instrument Parameters')) |
---|
[1201] | 1530 | Sample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Sample Parameters')) |
---|
[792] | 1531 | ParmList = [Parms,] |
---|
[1203] | 1532 | SampleList = [Sample,] |
---|
[828] | 1533 | Title = Pattern[-1] |
---|
[762] | 1534 | else: |
---|
[828] | 1535 | Title = os.path.split(G2frame.GSASprojectfile)[1] |
---|
[762] | 1536 | PlotList = [] |
---|
| 1537 | ParmList = [] |
---|
[1201] | 1538 | SampleList = [] |
---|
[762] | 1539 | item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root) |
---|
| 1540 | while item: |
---|
[1201] | 1541 | if plottype in G2frame.PatternTree.GetItemText(item): |
---|
[762] | 1542 | Pattern = G2frame.PatternTree.GetItemPyData(item) |
---|
| 1543 | if len(Pattern) < 3: # put name on end if needed |
---|
| 1544 | Pattern.append(G2frame.PatternTree.GetItemText(item)) |
---|
[1774] | 1545 | if 'Offset' not in Pattern[0]: #plot offset data |
---|
| 1546 | Pattern[0].update({'Offset':[0.0,0.0],'delOffset':0.02,'refOffset':-1.0,'refDelt':0.01,}) |
---|
[762] | 1547 | PlotList.append(Pattern) |
---|
| 1548 | ParmList.append(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, |
---|
[796] | 1549 | item,'Instrument Parameters'))[0]) |
---|
[1201] | 1550 | SampleList.append(G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, |
---|
| 1551 | item, 'Sample Parameters'))) |
---|
[762] | 1552 | item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie) |
---|
| 1553 | lenX = 0 |
---|
[1084] | 1554 | Ymax = None |
---|
[762] | 1555 | for Pattern in PlotList: |
---|
| 1556 | xye = Pattern[1] |
---|
[1086] | 1557 | if xye[1] is None: continue |
---|
[1084] | 1558 | if Ymax is None: Ymax = max(xye[1]) |
---|
[762] | 1559 | Ymax = max(Ymax,max(xye[1])) |
---|
[1084] | 1560 | if Ymax is None: return # nothing to plot |
---|
[1694] | 1561 | offsetX = Pattern[0]['Offset'][1] |
---|
| 1562 | offsetY = Pattern[0]['Offset'][0] |
---|
[762] | 1563 | if G2frame.logPlot: |
---|
| 1564 | Title = 'log('+Title+')' |
---|
| 1565 | Plot.set_title(Title) |
---|
[1715] | 1566 | if G2frame.plotStyle['qPlot'] or 'SASD' in plottype and not G2frame.Contour: |
---|
[1203] | 1567 | Plot.set_xlabel(r'$Q, \AA^{-1}$',fontsize=16) |
---|
[1715] | 1568 | elif G2frame.plotStyle['dPlot'] and 'PWDR' in plottype and not G2frame.Contour: |
---|
[1462] | 1569 | Plot.set_xlabel(r'$d, \AA$',fontsize=16) |
---|
[792] | 1570 | else: |
---|
| 1571 | if 'C' in ParmList[0]['Type'][0]: |
---|
[1203] | 1572 | Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=16) |
---|
[792] | 1573 | else: |
---|
[1519] | 1574 | if G2frame.Contour: |
---|
| 1575 | Plot.set_xlabel(r'Channel no.',fontsize=16) |
---|
| 1576 | else: |
---|
| 1577 | Plot.set_xlabel(r'$TOF, \mathsf{\mu}$s',fontsize=16) |
---|
[762] | 1578 | if G2frame.Weight: |
---|
[1341] | 1579 | if 'PWDR' in plottype: |
---|
| 1580 | Plot.set_ylabel(r'$\mathsf{I/\sigma(I)}$',fontsize=16) |
---|
| 1581 | elif 'SASD' in plottype: |
---|
| 1582 | Plot.set_ylabel(r'$\mathsf{\Delta(I)/\sigma(I)}$',fontsize=16) |
---|
[762] | 1583 | else: |
---|
[792] | 1584 | if 'C' in ParmList[0]['Type'][0]: |
---|
[1201] | 1585 | if 'PWDR' in plottype: |
---|
[1715] | 1586 | if G2frame.plotStyle['sqrtPlot']: |
---|
[1368] | 1587 | Plot.set_ylabel(r'$\sqrt{Intensity}$',fontsize=16) |
---|
| 1588 | else: |
---|
[1370] | 1589 | Plot.set_ylabel(r'$Intensity$',fontsize=16) |
---|
[1201] | 1590 | elif 'SASD' in plottype: |
---|
[1205] | 1591 | if G2frame.sqPlot: |
---|
[1370] | 1592 | Plot.set_ylabel(r'$S(Q)=I*Q^{4}$',fontsize=16) |
---|
[1205] | 1593 | else: |
---|
[1370] | 1594 | Plot.set_ylabel(r'$Intensity, cm^{-1}$',fontsize=16) |
---|
[792] | 1595 | else: |
---|
[1715] | 1596 | if G2frame.plotStyle['sqrtPlot']: |
---|
[1370] | 1597 | Plot.set_ylabel(r'$\sqrt{Normalized\ intensity}$',fontsize=16) |
---|
| 1598 | else: |
---|
| 1599 | Plot.set_ylabel(r'$Normalized\ intensity$',fontsize=16) |
---|
[762] | 1600 | if G2frame.Contour: |
---|
| 1601 | ContourZ = [] |
---|
| 1602 | ContourY = [] |
---|
| 1603 | Nseq = 0 |
---|
| 1604 | for N,Pattern in enumerate(PlotList): |
---|
| 1605 | Parms = ParmList[N] |
---|
[1201] | 1606 | Sample = SampleList[N] |
---|
[792] | 1607 | if 'C' in Parms['Type'][0]: |
---|
[795] | 1608 | wave = G2mth.getWave(Parms) |
---|
[792] | 1609 | else: |
---|
| 1610 | difC = Parms['difC'][1] |
---|
[762] | 1611 | ifpicked = False |
---|
| 1612 | LimitId = 0 |
---|
[1084] | 1613 | if Pattern[1] is None: continue # skip over uncomputed simulations |
---|
[1025] | 1614 | xye = ma.array(ma.getdata(Pattern[1])) |
---|
[1199] | 1615 | Zero = Parms.get('Zero',[0.,0.])[1] |
---|
[1774] | 1616 | if PickId: |
---|
| 1617 | ifpicked = Pattern[2] == G2frame.PatternTree.GetItemText(PatternId) |
---|
| 1618 | LimitId = G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId,'Limits') |
---|
| 1619 | limits = G2frame.PatternTree.GetItemPyData(LimitId) |
---|
| 1620 | excls = limits[2:] |
---|
| 1621 | for excl in excls: |
---|
| 1622 | xye[0] = ma.masked_inside(xye[0],excl[0],excl[1]) |
---|
[1715] | 1623 | if G2frame.plotStyle['qPlot'] and 'PWDR' in plottype: |
---|
[762] | 1624 | Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, Pattern[2]) |
---|
[1475] | 1625 | X = 2.*np.pi/G2lat.Pos2dsp(Parms,xye[0]) |
---|
[1715] | 1626 | elif G2frame.plotStyle['dPlot'] and 'PWDR' in plottype: |
---|
[1462] | 1627 | Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, Pattern[2]) |
---|
[1475] | 1628 | X = G2lat.Pos2dsp(Parms,xye[0]) |
---|
[762] | 1629 | else: |
---|
[1475] | 1630 | X = xye[0] |
---|
[762] | 1631 | if not lenX: |
---|
[1087] | 1632 | lenX = len(X) |
---|
[1201] | 1633 | if 'PWDR' in plottype: |
---|
[1715] | 1634 | if G2frame.plotStyle['sqrtPlot']: |
---|
[1420] | 1635 | olderr = np.seterr(invalid='ignore') #get around sqrt(-ve) error |
---|
[1368] | 1636 | Y = np.where(xye[1]>=0.,np.sqrt(xye[1]),-np.sqrt(-xye[1])) |
---|
[1420] | 1637 | np.seterr(invalid=olderr['invalid']) |
---|
[1368] | 1638 | else: |
---|
[1694] | 1639 | Y = xye[1]+offsetY*N*Ymax/100.0 |
---|
[1201] | 1640 | elif 'SASD' in plottype: |
---|
[1300] | 1641 | B = xye[5] |
---|
[1217] | 1642 | if G2frame.sqPlot: |
---|
[1694] | 1643 | Y = xye[1]*Sample['Scale'][0]*(1.05)**(offsetY*N)*X**4 |
---|
[1205] | 1644 | else: |
---|
[1694] | 1645 | Y = xye[1]*Sample['Scale'][0]*(1.05)**(offsetY*N) |
---|
[1204] | 1646 | if LimitId and ifpicked: |
---|
[762] | 1647 | limits = np.array(G2frame.PatternTree.GetItemPyData(LimitId)) |
---|
[1475] | 1648 | lims = limits[1] |
---|
[1715] | 1649 | if G2frame.plotStyle['qPlot'] and 'PWDR' in plottype: |
---|
[1475] | 1650 | lims = 2.*np.pi/G2lat.Pos2dsp(Parms,lims) |
---|
[1715] | 1651 | elif G2frame.plotStyle['dPlot'] and 'PWDR' in plottype: |
---|
[1475] | 1652 | lims = G2lat.Pos2dsp(Parms,lims) |
---|
| 1653 | Lines.append(Plot.axvline(lims[0],color='g',dashes=(5,5),picker=3.)) |
---|
| 1654 | Lines.append(Plot.axvline(lims[1],color='r',dashes=(5,5),picker=3.)) |
---|
[1017] | 1655 | for i,item in enumerate(limits[2:]): |
---|
| 1656 | Lines.append(Plot.axvline(item[0],color='m',dashes=(5,5),picker=3.)) |
---|
| 1657 | Lines.append(Plot.axvline(item[1],color='m',dashes=(5,5),picker=3.)) |
---|
| 1658 | exclLines += [2*i+2,2*i+3] |
---|
[1519] | 1659 | if G2frame.Contour: |
---|
[762] | 1660 | if lenX == len(X): |
---|
| 1661 | ContourY.append(N) |
---|
| 1662 | ContourZ.append(Y) |
---|
[1519] | 1663 | if 'C' in ParmList[0]['Type'][0]: |
---|
| 1664 | ContourX = X |
---|
| 1665 | else: #'T'OF |
---|
| 1666 | ContourX = range(lenX) |
---|
[762] | 1667 | Nseq += 1 |
---|
| 1668 | Plot.set_ylabel('Data sequence',fontsize=12) |
---|
| 1669 | else: |
---|
[1205] | 1670 | if 'SASD' in plottype and G2frame.logPlot: |
---|
[1694] | 1671 | X *= (1.01)**(offsetX*N) |
---|
[1205] | 1672 | else: |
---|
[1694] | 1673 | X += offsetX*.005*N |
---|
[1017] | 1674 | Xum = ma.getdata(X) |
---|
[1349] | 1675 | DifLine = [''] |
---|
[762] | 1676 | if ifpicked: |
---|
[1715] | 1677 | if G2frame.plotStyle['sqrtPlot']: |
---|
[1582] | 1678 | olderr = np.seterr(invalid='ignore') #get around sqrt(-ve) error |
---|
[1368] | 1679 | Z = np.where(xye[3]>=0.,np.sqrt(xye[3]),-np.sqrt(-xye[3])) |
---|
[1582] | 1680 | np.seterr(invalid=olderr['invalid']) |
---|
[1368] | 1681 | else: |
---|
[1694] | 1682 | Z = xye[3]+offsetY*N*Ymax/100.0 |
---|
[1339] | 1683 | if 'PWDR' in plottype: |
---|
[1715] | 1684 | if G2frame.plotStyle['sqrtPlot']: |
---|
[1586] | 1685 | olderr = np.seterr(invalid='ignore') #get around sqrt(-ve) error |
---|
[1368] | 1686 | W = np.where(xye[4]>=0.,np.sqrt(xye[4]),-np.sqrt(-xye[4])) |
---|
[1586] | 1687 | np.seterr(invalid=olderr['invalid']) |
---|
[1672] | 1688 | D = np.where(xye[5],(Y-Z),0.)-Ymax*Pattern[0]['delOffset'] |
---|
[1368] | 1689 | else: |
---|
[1694] | 1690 | W = xye[4]+offsetY*N*Ymax/100.0 |
---|
[1672] | 1691 | D = xye[5]-Ymax*Pattern[0]['delOffset'] #powder background |
---|
[1201] | 1692 | elif 'SASD' in plottype: |
---|
[1264] | 1693 | if G2frame.sqPlot: |
---|
[1300] | 1694 | W = xye[4]*X**4 |
---|
[1264] | 1695 | Z = xye[3]*X**4 |
---|
[1300] | 1696 | B = B*X**4 |
---|
[1264] | 1697 | else: |
---|
[1300] | 1698 | W = xye[4] |
---|
| 1699 | if G2frame.SubBack: |
---|
| 1700 | YB = Y-B |
---|
| 1701 | ZB = Z |
---|
| 1702 | else: |
---|
| 1703 | YB = Y |
---|
| 1704 | ZB = Z+B |
---|
[1232] | 1705 | Plot.set_yscale("log",nonposy='mask') |
---|
[1341] | 1706 | if np.any(W>0.): |
---|
| 1707 | Plot.set_ylim(bottom=np.min(np.trim_zeros(W))/2.,top=np.max(Y)*2.) |
---|
| 1708 | else: |
---|
| 1709 | Plot.set_ylim(bottom=np.min(np.trim_zeros(YB))/2.,top=np.max(Y)*2.) |
---|
[762] | 1710 | if G2frame.logPlot: |
---|
[1201] | 1711 | if 'PWDR' in plottype: |
---|
[1205] | 1712 | Plot.set_yscale("log",nonposy='mask') |
---|
| 1713 | Plot.plot(X,Y,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
| 1714 | Plot.plot(X,Z,colors[(N+1)%6],picker=False) |
---|
[1341] | 1715 | Plot.plot(X,W,colors[(N+2)%6],picker=False) #background |
---|
[1201] | 1716 | elif 'SASD' in plottype: |
---|
[1205] | 1717 | Plot.set_xscale("log",nonposx='mask') |
---|
[1343] | 1718 | Ibeg = np.searchsorted(X,limits[1][0]) |
---|
| 1719 | Ifin = np.searchsorted(X,limits[1][1]) |
---|
| 1720 | if G2frame.Weight: |
---|
| 1721 | Plot.set_yscale("linear") |
---|
| 1722 | DS = (YB-ZB)*np.sqrt(xye[2]) |
---|
| 1723 | Plot.plot(X[Ibeg:Ifin],DS[Ibeg:Ifin],colors[(N+3)%6],picker=False) |
---|
| 1724 | Plot.axhline(0.,color=wx.BLACK) |
---|
| 1725 | Plot.set_ylim(bottom=np.min(DS[Ibeg:Ifin])*1.2,top=np.max(DS[Ibeg:Ifin])*1.2) |
---|
| 1726 | else: |
---|
| 1727 | Plot.set_yscale("log",nonposy='mask') |
---|
| 1728 | if G2frame.ErrorBars: |
---|
| 1729 | if G2frame.sqPlot: |
---|
| 1730 | Plot.errorbar(X,YB,yerr=X**4*Sample['Scale'][0]*np.sqrt(1./(Pattern[0]['wtFactor']*xye[2])), |
---|
| 1731 | ecolor=colors[N%6],picker=3.,clip_on=False) |
---|
| 1732 | else: |
---|
| 1733 | Plot.errorbar(X,YB,yerr=Sample['Scale'][0]*np.sqrt(1./(Pattern[0]['wtFactor']*xye[2])), |
---|
| 1734 | ecolor=colors[N%6],picker=3.,clip_on=False) |
---|
[1264] | 1735 | else: |
---|
[1343] | 1736 | Plot.plot(X,YB,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
| 1737 | Plot.plot(X,W,colors[(N+2)%6],picker=False) #const. background |
---|
| 1738 | Plot.plot(X,ZB,colors[(N+1)%6],picker=False) |
---|
[1205] | 1739 | elif G2frame.Weight and 'PWDR' in plottype: |
---|
[762] | 1740 | DY = xye[1]*np.sqrt(xye[2]) |
---|
[1343] | 1741 | Ymax = max(DY) |
---|
[762] | 1742 | DZ = xye[3]*np.sqrt(xye[2]) |
---|
[1672] | 1743 | DS = xye[5]*np.sqrt(xye[2])-Ymax*Pattern[0]['delOffset'] |
---|
[1343] | 1744 | ObsLine = Plot.plot(X,DY,colors[N%6]+'+',picker=3.,clip_on=False) #Io/sig(Io) |
---|
| 1745 | Plot.plot(X,DZ,colors[(N+1)%6],picker=False) #Ic/sig(Io) |
---|
| 1746 | DifLine = Plot.plot(X,DS,colors[(N+3)%6],picker=1.) #(Io-Ic)/sig(Io) |
---|
[762] | 1747 | Plot.axhline(0.,color=wx.BLACK) |
---|
| 1748 | else: |
---|
[1300] | 1749 | if G2frame.SubBack: |
---|
[1344] | 1750 | if 'PWDR' in plottype: |
---|
| 1751 | Plot.plot(Xum,Y-W,colors[N%6]+'+',picker=False,clip_on=False) #Io-Ib |
---|
| 1752 | Plot.plot(X,Z-W,colors[(N+1)%6],picker=False) #Ic-Ib |
---|
| 1753 | else: |
---|
| 1754 | Plot.plot(X,YB,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
| 1755 | Plot.plot(X,ZB,colors[(N+1)%6],picker=False) |
---|
[792] | 1756 | else: |
---|
[1344] | 1757 | if 'PWDR' in plottype: |
---|
| 1758 | ObsLine = Plot.plot(Xum,Y,colors[N%6]+'+',picker=3.,clip_on=False) #Io |
---|
| 1759 | Plot.plot(X,Z,colors[(N+1)%6],picker=False) #Ic |
---|
| 1760 | else: |
---|
| 1761 | Plot.plot(X,YB,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
| 1762 | Plot.plot(X,ZB,colors[(N+1)%6],picker=False) |
---|
[1201] | 1763 | if 'PWDR' in plottype: |
---|
[1343] | 1764 | Plot.plot(X,W,colors[(N+2)%6],picker=False) #Ib |
---|
| 1765 | DifLine = Plot.plot(X,D,colors[(N+3)%6],picker=1.) #Io-Ic |
---|
[762] | 1766 | Plot.axhline(0.,color=wx.BLACK) |
---|
| 1767 | Page.canvas.SetToolTipString('') |
---|
[1774] | 1768 | if PickId: |
---|
| 1769 | if G2frame.PatternTree.GetItemText(PickId) == 'Peak List': |
---|
| 1770 | tip = 'On data point: Pick peak - L or R MB. On line: L-move, R-delete' |
---|
| 1771 | Page.canvas.SetToolTipString(tip) |
---|
| 1772 | data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List')) |
---|
| 1773 | for item in data['peaks']: |
---|
| 1774 | if G2frame.plotStyle['qPlot']: |
---|
| 1775 | Lines.append(Plot.axvline(2.*np.pi/G2lat.Pos2dsp(Parms,item[0]),color=colors[N%6],picker=2.)) |
---|
| 1776 | elif G2frame.plotStyle['dPlot']: |
---|
| 1777 | Lines.append(Plot.axvline(G2lat.Pos2dsp(Parms,item[0]),color=colors[N%6],picker=2.)) |
---|
| 1778 | else: |
---|
| 1779 | Lines.append(Plot.axvline(item[0],color=colors[N%6],picker=2.)) |
---|
| 1780 | if G2frame.PatternTree.GetItemText(PickId) == 'Limits': |
---|
| 1781 | tip = 'On data point: Lower limit - L MB; Upper limit - R MB. On limit: MB down to move' |
---|
| 1782 | Page.canvas.SetToolTipString(tip) |
---|
| 1783 | data = G2frame.LimitsTable.GetData() |
---|
| 1784 | |
---|
[1339] | 1785 | else: #not picked |
---|
[762] | 1786 | if G2frame.logPlot: |
---|
[1201] | 1787 | if 'PWDR' in plottype: |
---|
[1199] | 1788 | Plot.semilogy(X,Y,colors[N%6],picker=False,nonposy='mask') |
---|
[1201] | 1789 | elif 'SASD' in plottype: |
---|
[1244] | 1790 | Plot.semilogy(X,Y,colors[N%6],picker=False,nonposy='mask') |
---|
[762] | 1791 | else: |
---|
[1217] | 1792 | if 'PWDR' in plottype: |
---|
| 1793 | Plot.plot(X,Y,colors[N%6],picker=False) |
---|
| 1794 | elif 'SASD' in plottype: |
---|
[1244] | 1795 | Plot.loglog(X,Y,colors[N%6],picker=False,nonposy='mask') |
---|
[1232] | 1796 | Plot.set_ylim(bottom=np.min(np.trim_zeros(Y))/2.,top=np.max(Y)*2.) |
---|
[1343] | 1797 | |
---|
| 1798 | if G2frame.logPlot and 'PWDR' in plottype: |
---|
| 1799 | Plot.set_ylim(bottom=np.min(np.trim_zeros(Y))/2.,top=np.max(Y)*2.) |
---|
[762] | 1800 | if PickId and not G2frame.Contour: |
---|
[796] | 1801 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters')) |
---|
[762] | 1802 | if G2frame.PatternTree.GetItemText(PickId) in ['Index Peak List','Unit Cells List']: |
---|
[1882] | 1803 | peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List')) |
---|
[1618] | 1804 | if not len(peaks): return # are there any peaks? |
---|
[1607] | 1805 | for peak in peaks[0]: |
---|
[1586] | 1806 | if peak[2]: |
---|
[1715] | 1807 | if G2frame.plotStyle['qPlot']: |
---|
[1586] | 1808 | Plot.axvline(2.*np.pi/G2lat.Pos2dsp(Parms,peak[0]),color='b') |
---|
[1715] | 1809 | if G2frame.plotStyle['dPlot']: |
---|
[1586] | 1810 | Plot.axvline(G2lat.Pos2dsp(Parms,peak[0]),color='b') |
---|
| 1811 | else: |
---|
| 1812 | Plot.axvline(peak[0],color='b') |
---|
[762] | 1813 | for hkl in G2frame.HKL: |
---|
[1571] | 1814 | clr = 'r' |
---|
| 1815 | if len(hkl) > 6 and hkl[3]: |
---|
| 1816 | clr = 'g' |
---|
[1715] | 1817 | if G2frame.plotStyle['qPlot']: |
---|
[1578] | 1818 | Plot.axvline(2.*np.pi/G2lat.Pos2dsp(Parms,hkl[-2]),color=clr,dashes=(5,5)) |
---|
[1715] | 1819 | if G2frame.plotStyle['dPlot']: |
---|
[1578] | 1820 | Plot.axvline(G2lat.Pos2dsp(Parms,hkl[-2]),color=clr,dashes=(5,5)) |
---|
[762] | 1821 | else: |
---|
[1578] | 1822 | Plot.axvline(hkl[-2],color=clr,dashes=(5,5)) |
---|
[762] | 1823 | elif G2frame.PatternTree.GetItemText(PickId) in ['Reflection Lists'] or \ |
---|
| 1824 | 'PWDR' in G2frame.PatternTree.GetItemText(PickId): |
---|
[808] | 1825 | refColors=['b','r','c','g','m','k'] |
---|
[762] | 1826 | Phases = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists')) |
---|
| 1827 | for pId,phase in enumerate(Phases): |
---|
[1944] | 1828 | peaks = Phases[phase].get('RefList',[]) |
---|
[1107] | 1829 | if not len(peaks): |
---|
[762] | 1830 | continue |
---|
[1660] | 1831 | if Phases[phase].get('Super',False): |
---|
[1596] | 1832 | peak = np.array([[peak[5],peak[6]] for peak in peaks]) |
---|
| 1833 | else: |
---|
| 1834 | peak = np.array([[peak[4],peak[5]] for peak in peaks]) |
---|
[1672] | 1835 | pos = Pattern[0]['refOffset']-pId*Ymax*Pattern[0]['refDelt']*np.ones_like(peak) |
---|
[1715] | 1836 | if G2frame.plotStyle['qPlot']: |
---|
[808] | 1837 | Plot.plot(2*np.pi/peak.T[0],pos,refColors[pId%6]+'|',mew=1,ms=8,picker=3.,label=phase) |
---|
[1715] | 1838 | elif G2frame.plotStyle['dPlot']: |
---|
[1462] | 1839 | Plot.plot(peak.T[0],pos,refColors[pId%6]+'|',mew=1,ms=8,picker=3.,label=phase) |
---|
[762] | 1840 | else: |
---|
[808] | 1841 | Plot.plot(peak.T[1],pos,refColors[pId%6]+'|',mew=1,ms=8,picker=3.,label=phase) |
---|
[762] | 1842 | if len(Phases): |
---|
| 1843 | handles,legends = Plot.get_legend_handles_labels() #got double entries in the legends for some reason |
---|
| 1844 | if handles: |
---|
| 1845 | Plot.legend(handles[::2],legends[::2],title='Phases',loc='best') #skip every other one |
---|
| 1846 | |
---|
| 1847 | if G2frame.Contour: |
---|
| 1848 | acolor = mpl.cm.get_cmap(G2frame.ContourColor) |
---|
| 1849 | Img = Plot.imshow(ContourZ,cmap=acolor,vmin=0,vmax=Ymax*G2frame.Cmax,interpolation=G2frame.Interpolate, |
---|
| 1850 | extent=[ContourX[0],ContourX[-1],ContourY[0],ContourY[-1]],aspect='auto',origin='lower') |
---|
| 1851 | Page.figure.colorbar(Img) |
---|
| 1852 | else: |
---|
| 1853 | G2frame.Lines = Lines |
---|
[1889] | 1854 | if G2frame.PatternTree.GetItemText(PickId) == 'Background': |
---|
| 1855 | # plot fixed background points |
---|
| 1856 | backDict = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Background'))[1] |
---|
| 1857 | try: |
---|
| 1858 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.PatternId, 'Instrument Parameters')) |
---|
| 1859 | except TypeError: |
---|
| 1860 | Parms = None |
---|
| 1861 | for x,y in backDict.get('FixedPoints',[]): |
---|
| 1862 | # "normal" intensity modes only! |
---|
| 1863 | if G2frame.SubBack or G2frame.Weight or G2frame.Contour or not G2frame.SinglePlot: |
---|
| 1864 | break |
---|
| 1865 | if y < 0 and (G2frame.plotStyle['sqrtPlot'] or G2frame.logPlot): |
---|
| 1866 | y = Page.figure.gca().get_ylim()[0] # put out of range point at bottom of plot |
---|
| 1867 | elif G2frame.plotStyle['sqrtPlot']: |
---|
| 1868 | y = math.sqrt(y) |
---|
| 1869 | if G2frame.plotStyle['qPlot']: #Q - convert from 2-theta |
---|
| 1870 | if Parms: |
---|
| 1871 | x = 2*np.pi/G2lat.Pos2dsp(Parms,x) |
---|
| 1872 | else: |
---|
| 1873 | break |
---|
| 1874 | elif G2frame.plotStyle['dPlot']: #d - convert from 2-theta |
---|
| 1875 | if Parms: |
---|
| 1876 | x = G2lat.Dsp2pos(Parms,x) |
---|
| 1877 | else: |
---|
| 1878 | break |
---|
| 1879 | Plot.plot(x,y,'rD',clip_on=False,picker=3.) |
---|
[762] | 1880 | if not newPlot: |
---|
| 1881 | Page.toolbar.push_current() |
---|
[1907] | 1882 | Plot.set_xlim(G2frame.xylim[0]) |
---|
| 1883 | Plot.set_ylim(G2frame.xylim[1]) |
---|
[1281] | 1884 | # xylim = [] |
---|
[762] | 1885 | Page.toolbar.push_current() |
---|
| 1886 | Page.toolbar.draw() |
---|
| 1887 | else: |
---|
[1907] | 1888 | G2frame.xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
[762] | 1889 | Page.canvas.draw() |
---|
[1369] | 1890 | olderr = np.seterr(invalid='ignore') #ugh - this removes a matplotlib error for mouse clicks in log plots |
---|
| 1891 | # and sqrt(-ve) in np.where usage |
---|
[762] | 1892 | # G2frame.Pwdr = True |
---|
| 1893 | |
---|
| 1894 | ################################################################################ |
---|
| 1895 | ##### PlotDeltSig |
---|
| 1896 | ################################################################################ |
---|
| 1897 | |
---|
| 1898 | def PlotDeltSig(G2frame,kind): |
---|
[939] | 1899 | 'needs a doc string' |
---|
[762] | 1900 | try: |
---|
| 1901 | plotNum = G2frame.G2plotNB.plotList.index('Error analysis') |
---|
| 1902 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 1903 | Page.figure.clf() |
---|
| 1904 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
| 1905 | except ValueError: |
---|
| 1906 | newPlot = True |
---|
| 1907 | G2frame.Cmax = 1.0 |
---|
| 1908 | Plot = G2frame.G2plotNB.addMpl('Error analysis').gca() |
---|
| 1909 | plotNum = G2frame.G2plotNB.plotList.index('Error analysis') |
---|
| 1910 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[796] | 1911 | Page.Choice = None |
---|
[762] | 1912 | PatternId = G2frame.PatternId |
---|
| 1913 | Pattern = G2frame.PatternTree.GetItemPyData(PatternId) |
---|
| 1914 | Pattern.append(G2frame.PatternTree.GetItemText(PatternId)) |
---|
| 1915 | wtFactor = Pattern[0]['wtFactor'] |
---|
| 1916 | if kind == 'PWDR': |
---|
| 1917 | limits = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits'))[1] |
---|
| 1918 | xye = np.array(Pattern[1]) |
---|
| 1919 | xmin = np.searchsorted(xye[0],limits[0]) |
---|
| 1920 | xmax = np.searchsorted(xye[0],limits[1]) |
---|
| 1921 | DS = xye[5][xmin:xmax]*np.sqrt(wtFactor*xye[2][xmin:xmax]) |
---|
| 1922 | elif kind == 'HKLF': |
---|
[1788] | 1923 | refl = Pattern[1]['RefList'] |
---|
| 1924 | im = 0 |
---|
| 1925 | if Pattern[1]['Super']: |
---|
| 1926 | im = 1 |
---|
[762] | 1927 | DS = [] |
---|
| 1928 | for ref in refl: |
---|
[1788] | 1929 | if ref[6+im] > 0.: |
---|
| 1930 | DS.append((ref[5+im]-ref[7+im])/ref[6+im]) |
---|
[762] | 1931 | Page.SetFocus() |
---|
| 1932 | G2frame.G2plotNB.status.DestroyChildren() |
---|
| 1933 | DS.sort() |
---|
| 1934 | EDS = np.zeros_like(DS) |
---|
| 1935 | DX = np.linspace(0.,1.,num=len(DS),endpoint=True) |
---|
| 1936 | oldErr = np.seterr(invalid='ignore') #avoid problem at DX==0 |
---|
| 1937 | T = np.sqrt(np.log(1.0/DX**2)) |
---|
| 1938 | top = 2.515517+0.802853*T+0.010328*T**2 |
---|
| 1939 | bot = 1.0+1.432788*T+0.189269*T**2+0.001308*T**3 |
---|
| 1940 | EDS = np.where(DX>0,-(T-top/bot),(T-top/bot)) |
---|
| 1941 | low1 = np.searchsorted(EDS,-1.) |
---|
| 1942 | hi1 = np.searchsorted(EDS,1.) |
---|
| 1943 | slp,intcp = np.polyfit(EDS[low1:hi1],DS[low1:hi1],deg=1) |
---|
| 1944 | frac = 100.*(hi1-low1)/len(DS) |
---|
| 1945 | G2frame.G2plotNB.status.SetStatusText( \ |
---|
| 1946 | 'Over range -1. to 1. :'+' slope = %.3f, intercept = %.3f for %.2f%% of the fitted data'%(slp,intcp,frac),1) |
---|
| 1947 | Plot.set_title('Normal probability for '+Pattern[-1]) |
---|
| 1948 | Plot.set_xlabel(r'expected $\mathsf{\Delta/\sigma}$',fontsize=14) |
---|
| 1949 | Plot.set_ylabel(r'observed $\mathsf{\Delta/\sigma}$',fontsize=14) |
---|
| 1950 | Plot.plot(EDS,DS,'r+',label='result') |
---|
| 1951 | Plot.plot([-2,2],[-2,2],'k',dashes=(5,5),label='ideal') |
---|
| 1952 | Plot.legend(loc='upper left') |
---|
| 1953 | np.seterr(invalid='warn') |
---|
| 1954 | Page.canvas.draw() |
---|
| 1955 | |
---|
| 1956 | ################################################################################ |
---|
| 1957 | ##### PlotISFG |
---|
| 1958 | ################################################################################ |
---|
| 1959 | |
---|
| 1960 | def PlotISFG(G2frame,newPlot=False,type=''): |
---|
[1201] | 1961 | ''' Plotting package for PDF analysis; displays I(q), S(q), F(q) and G(r) as single |
---|
[762] | 1962 | or multiple plots with waterfall and contour plots as options |
---|
| 1963 | ''' |
---|
| 1964 | if not type: |
---|
| 1965 | type = G2frame.G2plotNB.plotList[G2frame.G2plotNB.nb.GetSelection()] |
---|
| 1966 | if type not in ['I(Q)','S(Q)','F(Q)','G(R)']: |
---|
| 1967 | return |
---|
| 1968 | superMinusOne = unichr(0xaf)+unichr(0xb9) |
---|
| 1969 | |
---|
| 1970 | def OnPlotKeyPress(event): |
---|
| 1971 | newPlot = False |
---|
| 1972 | if event.key == 'u': |
---|
| 1973 | if G2frame.Contour: |
---|
| 1974 | G2frame.Cmax = min(1.0,G2frame.Cmax*1.2) |
---|
[1672] | 1975 | elif Pattern[0]['Offset'][0] < 100.: |
---|
| 1976 | Pattern[0]['Offset'][0] += 1. |
---|
[762] | 1977 | elif event.key == 'd': |
---|
| 1978 | if G2frame.Contour: |
---|
| 1979 | G2frame.Cmax = max(0.0,G2frame.Cmax*0.8) |
---|
[1672] | 1980 | elif Pattern[0]['Offset'][0] > 0.: |
---|
| 1981 | Pattern[0]['Offset'][0] -= 1. |
---|
[762] | 1982 | elif event.key == 'l': |
---|
[1672] | 1983 | Pattern[0]['Offset'][1] -= 1. |
---|
[762] | 1984 | elif event.key == 'r': |
---|
[1672] | 1985 | Pattern[0]['Offset'][1] += 1. |
---|
[762] | 1986 | elif event.key == 'o': |
---|
[1672] | 1987 | Pattern[0]['Offset'] = [0,0] |
---|
[762] | 1988 | elif event.key == 'c': |
---|
| 1989 | newPlot = True |
---|
[1205] | 1990 | G2frame.Contour = not G2frame.Contour |
---|
| 1991 | if not G2frame.Contour: |
---|
[762] | 1992 | G2frame.SinglePlot = False |
---|
[1672] | 1993 | Pattern[0]['Offset'] = [0.,0.] |
---|
[762] | 1994 | elif event.key == 's': |
---|
| 1995 | if G2frame.Contour: |
---|
| 1996 | choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] |
---|
| 1997 | choice.sort() |
---|
| 1998 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice) |
---|
| 1999 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 2000 | sel = dlg.GetSelection() |
---|
| 2001 | G2frame.ContourColor = choice[sel] |
---|
| 2002 | else: |
---|
| 2003 | G2frame.ContourColor = 'Paired' |
---|
| 2004 | dlg.Destroy() |
---|
[1205] | 2005 | else: |
---|
| 2006 | G2frame.SinglePlot = not G2frame.SinglePlot |
---|
[762] | 2007 | elif event.key == 'i': #for smoothing contour plot |
---|
| 2008 | choice = ['nearest','bilinear','bicubic','spline16','spline36','hanning', |
---|
| 2009 | 'hamming','hermite','kaiser','quadric','catrom','gaussian','bessel', |
---|
| 2010 | 'mitchell','sinc','lanczos'] |
---|
| 2011 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Interpolation',choice) |
---|
| 2012 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 2013 | sel = dlg.GetSelection() |
---|
| 2014 | G2frame.Interpolate = choice[sel] |
---|
| 2015 | else: |
---|
| 2016 | G2frame.Interpolate = 'nearest' |
---|
| 2017 | dlg.Destroy() |
---|
| 2018 | elif event.key == 't' and not G2frame.Contour: |
---|
[1205] | 2019 | G2frame.Legend = not G2frame.Legend |
---|
[762] | 2020 | PlotISFG(G2frame,newPlot=newPlot,type=type) |
---|
| 2021 | |
---|
| 2022 | def OnKeyBox(event): |
---|
| 2023 | if G2frame.G2plotNB.nb.GetSelection() == G2frame.G2plotNB.plotList.index(type): |
---|
| 2024 | event.key = cb.GetValue()[0] |
---|
| 2025 | cb.SetValue(' key press') |
---|
| 2026 | wx.CallAfter(OnPlotKeyPress,event) |
---|
[1005] | 2027 | Page.canvas.SetFocus() # redirect the Focus from the button back to the plot |
---|
[762] | 2028 | |
---|
| 2029 | def OnMotion(event): |
---|
| 2030 | xpos = event.xdata |
---|
| 2031 | if xpos: #avoid out of frame mouse position |
---|
| 2032 | ypos = event.ydata |
---|
| 2033 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 2034 | try: |
---|
| 2035 | if G2frame.Contour: |
---|
| 2036 | G2frame.G2plotNB.status.SetStatusText('R =%.3fA pattern ID =%5d'%(xpos,int(ypos)),1) |
---|
| 2037 | else: |
---|
| 2038 | G2frame.G2plotNB.status.SetStatusText('R =%.3fA %s =%.2f'%(xpos,type,ypos),1) |
---|
| 2039 | except TypeError: |
---|
| 2040 | G2frame.G2plotNB.status.SetStatusText('Select '+type+' pattern first',1) |
---|
| 2041 | |
---|
| 2042 | xylim = [] |
---|
| 2043 | try: |
---|
| 2044 | plotNum = G2frame.G2plotNB.plotList.index(type) |
---|
| 2045 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2046 | if not newPlot: |
---|
| 2047 | Plot = Page.figure.gca() #get previous plot & get limits |
---|
| 2048 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
| 2049 | Page.figure.clf() |
---|
| 2050 | Plot = Page.figure.gca() |
---|
| 2051 | except ValueError: |
---|
| 2052 | newPlot = True |
---|
| 2053 | G2frame.Cmax = 1.0 |
---|
| 2054 | Plot = G2frame.G2plotNB.addMpl(type).gca() |
---|
| 2055 | plotNum = G2frame.G2plotNB.plotList.index(type) |
---|
| 2056 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2057 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
| 2058 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 2059 | |
---|
| 2060 | Page.SetFocus() |
---|
| 2061 | G2frame.G2plotNB.status.DestroyChildren() |
---|
| 2062 | if G2frame.Contour: |
---|
[796] | 2063 | Page.Choice = (' key press','d: lower contour max','u: raise contour max', |
---|
[762] | 2064 | 'i: interpolation method','s: color scheme','c: contour off') |
---|
| 2065 | else: |
---|
[796] | 2066 | Page.Choice = (' key press','l: offset left','r: offset right','d: offset down','u: offset up', |
---|
[762] | 2067 | 'o: reset offset','t: toggle legend','c: contour on','s: toggle single plot') |
---|
[796] | 2068 | Page.keyPress = OnPlotKeyPress |
---|
[762] | 2069 | PatternId = G2frame.PatternId |
---|
| 2070 | PickId = G2frame.PickId |
---|
| 2071 | Plot.set_title(type) |
---|
| 2072 | if type == 'G(R)': |
---|
| 2073 | Plot.set_xlabel(r'$R,\AA$',fontsize=14) |
---|
| 2074 | else: |
---|
| 2075 | Plot.set_xlabel(r'$Q,\AA$'+superMinusOne,fontsize=14) |
---|
| 2076 | Plot.set_ylabel(r''+type,fontsize=14) |
---|
| 2077 | colors=['b','g','r','c','m','k'] |
---|
| 2078 | name = G2frame.PatternTree.GetItemText(PatternId)[4:] |
---|
| 2079 | Pattern = [] |
---|
| 2080 | if G2frame.SinglePlot: |
---|
| 2081 | name = G2frame.PatternTree.GetItemText(PatternId) |
---|
| 2082 | name = type+name[4:] |
---|
| 2083 | Id = G2gd.GetPatternTreeItemId(G2frame,PatternId,name) |
---|
| 2084 | Pattern = G2frame.PatternTree.GetItemPyData(Id) |
---|
| 2085 | if Pattern: |
---|
| 2086 | Pattern.append(name) |
---|
| 2087 | PlotList = [Pattern,] |
---|
| 2088 | else: |
---|
| 2089 | PlotList = [] |
---|
| 2090 | item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root) |
---|
| 2091 | while item: |
---|
| 2092 | if 'PDF' in G2frame.PatternTree.GetItemText(item): |
---|
| 2093 | name = type+G2frame.PatternTree.GetItemText(item)[4:] |
---|
| 2094 | Id = G2gd.GetPatternTreeItemId(G2frame,item,name) |
---|
| 2095 | Pattern = G2frame.PatternTree.GetItemPyData(Id) |
---|
| 2096 | if Pattern: |
---|
| 2097 | Pattern.append(name) |
---|
| 2098 | PlotList.append(Pattern) |
---|
| 2099 | item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie) |
---|
| 2100 | PDFdata = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'PDF Controls')) |
---|
| 2101 | numbDen = G2pwd.GetNumDensity(PDFdata['ElList'],PDFdata['Form Vol']) |
---|
| 2102 | Xb = [0.,10.] |
---|
| 2103 | Yb = [0.,-40.*np.pi*numbDen] |
---|
[1835] | 2104 | Ymax = 0.01 |
---|
[762] | 2105 | lenX = 0 |
---|
| 2106 | for Pattern in PlotList: |
---|
[1613] | 2107 | try: |
---|
| 2108 | xye = Pattern[1] |
---|
| 2109 | except IndexError: |
---|
| 2110 | return |
---|
[762] | 2111 | Ymax = max(Ymax,max(xye[1])) |
---|
[1672] | 2112 | offset = Pattern[0]['Offset'][0]*Ymax/100.0 |
---|
[762] | 2113 | if G2frame.Contour: |
---|
| 2114 | ContourZ = [] |
---|
| 2115 | ContourY = [] |
---|
| 2116 | Nseq = 0 |
---|
| 2117 | for N,Pattern in enumerate(PlotList): |
---|
| 2118 | xye = Pattern[1] |
---|
| 2119 | if PickId: |
---|
| 2120 | ifpicked = Pattern[2] == G2frame.PatternTree.GetItemText(PatternId) |
---|
| 2121 | X = xye[0] |
---|
| 2122 | if not lenX: |
---|
| 2123 | lenX = len(X) |
---|
| 2124 | Y = xye[1]+offset*N |
---|
| 2125 | if G2frame.Contour: |
---|
| 2126 | if lenX == len(X): |
---|
| 2127 | ContourY.append(N) |
---|
| 2128 | ContourZ.append(Y) |
---|
| 2129 | ContourX = X |
---|
| 2130 | Nseq += 1 |
---|
| 2131 | Plot.set_ylabel('Data sequence',fontsize=12) |
---|
| 2132 | else: |
---|
[1672] | 2133 | X = xye[0]+Pattern[0]['Offset'][1]*.005*N |
---|
[762] | 2134 | if ifpicked: |
---|
| 2135 | Plot.plot(X,Y,colors[N%6]+'+',picker=3.,clip_on=False) |
---|
| 2136 | Page.canvas.SetToolTipString('') |
---|
| 2137 | else: |
---|
| 2138 | if G2frame.Legend: |
---|
| 2139 | Plot.plot(X,Y,colors[N%6],picker=False,label='Azm:'+Pattern[2].split('=')[1]) |
---|
| 2140 | else: |
---|
| 2141 | Plot.plot(X,Y,colors[N%6],picker=False) |
---|
| 2142 | if type == 'G(R)': |
---|
| 2143 | Plot.plot(Xb,Yb,color='k',dashes=(5,5)) |
---|
| 2144 | elif type == 'F(Q)': |
---|
| 2145 | Plot.axhline(0.,color=wx.BLACK) |
---|
| 2146 | elif type == 'S(Q)': |
---|
| 2147 | Plot.axhline(1.,color=wx.BLACK) |
---|
| 2148 | if G2frame.Contour: |
---|
| 2149 | acolor = mpl.cm.get_cmap(G2frame.ContourColor) |
---|
| 2150 | Img = Plot.imshow(ContourZ,cmap=acolor,vmin=0,vmax=Ymax*G2frame.Cmax,interpolation=G2frame.Interpolate, |
---|
| 2151 | extent=[ContourX[0],ContourX[-1],ContourY[0],ContourY[-1]],aspect='auto',origin='lower') |
---|
| 2152 | Page.figure.colorbar(Img) |
---|
| 2153 | elif G2frame.Legend: |
---|
| 2154 | Plot.legend(loc='best') |
---|
| 2155 | if not newPlot: |
---|
| 2156 | Page.toolbar.push_current() |
---|
| 2157 | Plot.set_xlim(xylim[0]) |
---|
| 2158 | Plot.set_ylim(xylim[1]) |
---|
| 2159 | xylim = [] |
---|
| 2160 | Page.toolbar.push_current() |
---|
| 2161 | Page.toolbar.draw() |
---|
| 2162 | else: |
---|
| 2163 | Page.canvas.draw() |
---|
| 2164 | |
---|
| 2165 | ################################################################################ |
---|
[1443] | 2166 | ##### PlotCalib |
---|
| 2167 | ################################################################################ |
---|
| 2168 | |
---|
[1445] | 2169 | def PlotCalib(G2frame,Inst,XY,Sigs,newPlot=False): |
---|
[1443] | 2170 | '''plot of CW or TOF peak calibration |
---|
| 2171 | ''' |
---|
| 2172 | def OnMotion(event): |
---|
| 2173 | xpos = event.xdata |
---|
| 2174 | if xpos: #avoid out of frame mouse position |
---|
| 2175 | ypos = event.ydata |
---|
| 2176 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 2177 | try: |
---|
[1493] | 2178 | G2frame.G2plotNB.status.SetStatusText('X =%9.3f %s =%9.3g'%(xpos,Title,ypos),1) |
---|
[1443] | 2179 | except TypeError: |
---|
| 2180 | G2frame.G2plotNB.status.SetStatusText('Select '+Title+' pattern first',1) |
---|
[1445] | 2181 | found = [] |
---|
| 2182 | wid = 1 |
---|
| 2183 | view = Page.toolbar._views.forward() |
---|
| 2184 | if view: |
---|
| 2185 | view = view[0][:2] |
---|
| 2186 | wid = view[1]-view[0] |
---|
| 2187 | found = XY[np.where(np.fabs(XY.T[0]-xpos) < 0.005*wid)] |
---|
| 2188 | if len(found): |
---|
| 2189 | pos = found[0][1] |
---|
| 2190 | if 'C' in Inst['Type'][0]: |
---|
| 2191 | Page.canvas.SetToolTipString('position=%.4f'%(pos)) |
---|
| 2192 | else: |
---|
| 2193 | Page.canvas.SetToolTipString('position=%.2f'%(pos)) |
---|
| 2194 | else: |
---|
| 2195 | Page.canvas.SetToolTipString('') |
---|
[1443] | 2196 | |
---|
| 2197 | Title = 'Position calibration' |
---|
| 2198 | try: |
---|
| 2199 | plotNum = G2frame.G2plotNB.plotList.index(Title) |
---|
| 2200 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2201 | if not newPlot: |
---|
| 2202 | Plot = Page.figure.gca() |
---|
| 2203 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
| 2204 | Page.figure.clf() |
---|
| 2205 | Plot = Page.figure.gca() |
---|
| 2206 | except ValueError: |
---|
| 2207 | newPlot = True |
---|
| 2208 | Plot = G2frame.G2plotNB.addMpl(Title).gca() |
---|
| 2209 | plotNum = G2frame.G2plotNB.plotList.index(Title) |
---|
| 2210 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2211 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 2212 | |
---|
| 2213 | Page.Choice = None |
---|
| 2214 | Page.SetFocus() |
---|
| 2215 | G2frame.G2plotNB.status.DestroyChildren() |
---|
| 2216 | Plot.set_title(Title) |
---|
| 2217 | Plot.set_xlabel(r'd-spacing',fontsize=14) |
---|
| 2218 | if 'C' in Inst['Type'][0]: |
---|
| 2219 | Plot.set_ylabel(r'$\mathsf{\Delta(2\theta)}$',fontsize=14) |
---|
| 2220 | else: |
---|
| 2221 | Plot.set_ylabel(r'$\mathsf{\Delta}T/T$',fontsize=14) |
---|
[1493] | 2222 | for ixy,xyw in enumerate(XY): |
---|
| 2223 | if len(xyw) > 2: |
---|
| 2224 | X,Y,W = xyw |
---|
| 2225 | else: |
---|
| 2226 | X,Y = xyw |
---|
| 2227 | W = 0. |
---|
[1443] | 2228 | Yc = G2lat.Dsp2pos(Inst,X) |
---|
| 2229 | if 'C' in Inst['Type'][0]: |
---|
| 2230 | Y = Y-Yc |
---|
[1445] | 2231 | E = Sigs[ixy] |
---|
[1493] | 2232 | bin = W/2. |
---|
[1443] | 2233 | else: |
---|
| 2234 | Y = (Y-Yc)/Yc |
---|
[1445] | 2235 | E = Sigs[ixy]/Yc |
---|
[1493] | 2236 | bin = W/(2.*Yc) |
---|
[1445] | 2237 | if E: |
---|
| 2238 | Plot.errorbar(X,Y,ecolor='k',yerr=E) |
---|
[1493] | 2239 | if ixy: |
---|
| 2240 | Plot.plot(X,Y,'kx',picker=3) |
---|
| 2241 | else: |
---|
| 2242 | Plot.plot(X,Y,'kx',label='peak') |
---|
| 2243 | if W: |
---|
| 2244 | if ixy: |
---|
| 2245 | Plot.plot(X,bin,'b+') |
---|
| 2246 | else: |
---|
| 2247 | Plot.plot(X,bin,'b+',label='bin width') |
---|
| 2248 | Plot.plot(X,-bin,'b+') |
---|
[1459] | 2249 | Plot.axhline(0.,color='r',linestyle='--') |
---|
[1493] | 2250 | Plot.legend(loc='best') |
---|
[1443] | 2251 | if not newPlot: |
---|
| 2252 | Page.toolbar.push_current() |
---|
| 2253 | Plot.set_xlim(xylim[0]) |
---|
| 2254 | Plot.set_ylim(xylim[1]) |
---|
[1445] | 2255 | # xylim = [] |
---|
[1443] | 2256 | Page.toolbar.push_current() |
---|
| 2257 | Page.toolbar.draw() |
---|
| 2258 | else: |
---|
| 2259 | Page.canvas.draw() |
---|
| 2260 | |
---|
| 2261 | ################################################################################ |
---|
[762] | 2262 | ##### PlotXY |
---|
| 2263 | ################################################################################ |
---|
| 2264 | |
---|
[1402] | 2265 | def PlotXY(G2frame,XY,XY2=None,labelX=None,labelY=None,newPlot=False,Title=''): |
---|
[762] | 2266 | '''simple plot of xy data, used for diagnostic purposes |
---|
| 2267 | ''' |
---|
| 2268 | def OnMotion(event): |
---|
| 2269 | xpos = event.xdata |
---|
| 2270 | if xpos: #avoid out of frame mouse position |
---|
| 2271 | ypos = event.ydata |
---|
| 2272 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 2273 | try: |
---|
[1402] | 2274 | G2frame.G2plotNB.status.SetStatusText('X =%9.3f %s =%9.3f'%(xpos,Title,ypos),1) |
---|
[762] | 2275 | except TypeError: |
---|
[1402] | 2276 | G2frame.G2plotNB.status.SetStatusText('Select '+Title+' pattern first',1) |
---|
[762] | 2277 | |
---|
| 2278 | try: |
---|
[1402] | 2279 | plotNum = G2frame.G2plotNB.plotList.index(Title) |
---|
[762] | 2280 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2281 | if not newPlot: |
---|
| 2282 | Plot = Page.figure.gca() |
---|
| 2283 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
| 2284 | Page.figure.clf() |
---|
| 2285 | Plot = Page.figure.gca() |
---|
| 2286 | except ValueError: |
---|
| 2287 | newPlot = True |
---|
[1402] | 2288 | Plot = G2frame.G2plotNB.addMpl(Title).gca() |
---|
| 2289 | plotNum = G2frame.G2plotNB.plotList.index(Title) |
---|
[762] | 2290 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2291 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 2292 | |
---|
[796] | 2293 | Page.Choice = None |
---|
[762] | 2294 | Page.SetFocus() |
---|
| 2295 | G2frame.G2plotNB.status.DestroyChildren() |
---|
[1402] | 2296 | Plot.set_title(Title) |
---|
| 2297 | if labelX: |
---|
| 2298 | Plot.set_xlabel(r''+labelX,fontsize=14) |
---|
[1180] | 2299 | else: |
---|
| 2300 | Plot.set_xlabel(r'X',fontsize=14) |
---|
[1402] | 2301 | if labelY: |
---|
| 2302 | Plot.set_ylabel(r''+labelY,fontsize=14) |
---|
[1180] | 2303 | else: |
---|
| 2304 | Plot.set_ylabel(r'Y',fontsize=14) |
---|
[762] | 2305 | colors=['b','g','r','c','m','k'] |
---|
[1180] | 2306 | for ixy,xy in enumerate(XY): |
---|
| 2307 | X,Y = xy |
---|
[1402] | 2308 | Plot.plot(X,Y,colors[ixy%6]+'+',picker=False) |
---|
[1180] | 2309 | if len(XY2): |
---|
| 2310 | for ixy,xy in enumerate(XY2): |
---|
| 2311 | X,Y = xy |
---|
[1402] | 2312 | Plot.plot(X,Y,colors[ixy%6],picker=False) |
---|
[762] | 2313 | if not newPlot: |
---|
| 2314 | Page.toolbar.push_current() |
---|
| 2315 | Plot.set_xlim(xylim[0]) |
---|
| 2316 | Plot.set_ylim(xylim[1]) |
---|
| 2317 | xylim = [] |
---|
| 2318 | Page.toolbar.push_current() |
---|
| 2319 | Page.toolbar.draw() |
---|
| 2320 | else: |
---|
| 2321 | Page.canvas.draw() |
---|
| 2322 | |
---|
| 2323 | ################################################################################ |
---|
[1180] | 2324 | ##### PlotStrain |
---|
| 2325 | ################################################################################ |
---|
| 2326 | |
---|
[1184] | 2327 | def PlotStrain(G2frame,data,newPlot=False): |
---|
[1180] | 2328 | '''plot of strain data, used for diagnostic purposes |
---|
| 2329 | ''' |
---|
| 2330 | def OnMotion(event): |
---|
| 2331 | xpos = event.xdata |
---|
| 2332 | if xpos: #avoid out of frame mouse position |
---|
| 2333 | ypos = event.ydata |
---|
| 2334 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 2335 | try: |
---|
[1185] | 2336 | G2frame.G2plotNB.status.SetStatusText('d-spacing =%9.5f Azimuth =%9.3f'%(ypos,xpos),1) |
---|
[1180] | 2337 | except TypeError: |
---|
[1184] | 2338 | G2frame.G2plotNB.status.SetStatusText('Select Strain pattern first',1) |
---|
[1180] | 2339 | |
---|
| 2340 | try: |
---|
[1184] | 2341 | plotNum = G2frame.G2plotNB.plotList.index('Strain') |
---|
[1180] | 2342 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2343 | if not newPlot: |
---|
| 2344 | Plot = Page.figure.gca() |
---|
| 2345 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
| 2346 | Page.figure.clf() |
---|
| 2347 | Plot = Page.figure.gca() |
---|
| 2348 | except ValueError: |
---|
| 2349 | newPlot = True |
---|
[1184] | 2350 | Plot = G2frame.G2plotNB.addMpl('Strain').gca() |
---|
| 2351 | plotNum = G2frame.G2plotNB.plotList.index('Strain') |
---|
[1180] | 2352 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2353 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 2354 | |
---|
| 2355 | Page.Choice = None |
---|
| 2356 | Page.SetFocus() |
---|
| 2357 | G2frame.G2plotNB.status.DestroyChildren() |
---|
[1184] | 2358 | Plot.set_title('Strain') |
---|
[1185] | 2359 | Plot.set_ylabel(r'd-spacing',fontsize=14) |
---|
| 2360 | Plot.set_xlabel(r'Azimuth',fontsize=14) |
---|
[1180] | 2361 | colors=['b','g','r','c','m','k'] |
---|
| 2362 | for N,item in enumerate(data['d-zero']): |
---|
[1185] | 2363 | Y,X = np.array(item['ImtaObs']) #plot azimuth as X & d-spacing as Y |
---|
[1180] | 2364 | Plot.plot(X,Y,colors[N%6]+'+',picker=False) |
---|
[1185] | 2365 | Y,X = np.array(item['ImtaCalc']) |
---|
[1180] | 2366 | Plot.plot(X,Y,colors[N%6],picker=False) |
---|
| 2367 | if not newPlot: |
---|
| 2368 | Page.toolbar.push_current() |
---|
| 2369 | Plot.set_xlim(xylim[0]) |
---|
| 2370 | Plot.set_ylim(xylim[1]) |
---|
| 2371 | xylim = [] |
---|
| 2372 | Page.toolbar.push_current() |
---|
| 2373 | Page.toolbar.draw() |
---|
| 2374 | else: |
---|
| 2375 | Page.canvas.draw() |
---|
[1244] | 2376 | |
---|
| 2377 | ################################################################################ |
---|
| 2378 | ##### PlotSASDSizeDist |
---|
| 2379 | ################################################################################ |
---|
| 2380 | |
---|
[1273] | 2381 | def PlotSASDSizeDist(G2frame): |
---|
[1244] | 2382 | |
---|
[1269] | 2383 | def OnPageChanged(event): |
---|
| 2384 | PlotText = G2frame.G2plotNB.nb.GetPageText(G2frame.G2plotNB.nb.GetSelection()) |
---|
| 2385 | if 'Powder' in PlotText: |
---|
| 2386 | PlotPatterns(G2frame,plotType='SASD',newPlot=True) |
---|
| 2387 | elif 'Size' in PlotText: |
---|
[1273] | 2388 | PlotSASDSizeDist(G2frame) |
---|
[1269] | 2389 | |
---|
[1244] | 2390 | def OnMotion(event): |
---|
| 2391 | xpos = event.xdata |
---|
| 2392 | if xpos: #avoid out of frame mouse position |
---|
| 2393 | ypos = event.ydata |
---|
| 2394 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 2395 | try: |
---|
[1250] | 2396 | G2frame.G2plotNB.status.SetStatusText('diameter =%9.3f f(D) =%9.3g'%(xpos,ypos),1) |
---|
[1244] | 2397 | except TypeError: |
---|
| 2398 | G2frame.G2plotNB.status.SetStatusText('Select Strain pattern first',1) |
---|
[1180] | 2399 | |
---|
[1244] | 2400 | try: |
---|
| 2401 | plotNum = G2frame.G2plotNB.plotList.index('Size Distribution') |
---|
| 2402 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2403 | Page.figure.clf() |
---|
| 2404 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
| 2405 | except ValueError: |
---|
| 2406 | newPlot = True |
---|
| 2407 | Plot = G2frame.G2plotNB.addMpl('Size Distribution').gca() |
---|
[1269] | 2408 | G2frame.G2plotNB.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED,OnPageChanged) |
---|
[1244] | 2409 | plotNum = G2frame.G2plotNB.plotList.index('Size Distribution') |
---|
| 2410 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2411 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 2412 | Page.Choice = None |
---|
| 2413 | Page.SetFocus() |
---|
| 2414 | PatternId = G2frame.PatternId |
---|
| 2415 | data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Models')) |
---|
| 2416 | Bins,Dbins,BinMag = data['Size']['Distribution'] |
---|
| 2417 | Plot.set_title('Size Distribution') |
---|
| 2418 | Plot.set_xlabel(r'$D, \AA$',fontsize=14) |
---|
[1246] | 2419 | Plot.set_ylabel(r'$Volume distribution f(D)$',fontsize=14) |
---|
[1244] | 2420 | if data['Size']['logBins']: |
---|
| 2421 | Plot.set_xscale("log",nonposy='mask') |
---|
| 2422 | Plot.set_xlim([np.min(2.*Bins)/2.,np.max(2.*Bins)*2.]) |
---|
[1269] | 2423 | Plot.bar(2.*Bins-Dbins,BinMag,2.*Dbins,facecolor='white') #plot diameters |
---|
[1272] | 2424 | if 'Size Calc' in data: |
---|
| 2425 | Rbins,Dist = data['Size Calc'] |
---|
[1269] | 2426 | for i in range(len(Rbins)): |
---|
[1274] | 2427 | if len(Rbins[i]): |
---|
| 2428 | Plot.plot(2.*Rbins[i],Dist[i]) #plot diameters |
---|
[1244] | 2429 | Page.canvas.draw() |
---|
| 2430 | |
---|
[1180] | 2431 | ################################################################################ |
---|
[762] | 2432 | ##### PlotPowderLines |
---|
| 2433 | ################################################################################ |
---|
| 2434 | |
---|
| 2435 | def PlotPowderLines(G2frame): |
---|
| 2436 | ''' plotting of powder lines (i.e. no powder pattern) as sticks |
---|
| 2437 | ''' |
---|
| 2438 | |
---|
| 2439 | def OnMotion(event): |
---|
| 2440 | xpos = event.xdata |
---|
| 2441 | if xpos: #avoid out of frame mouse position |
---|
| 2442 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 2443 | G2frame.G2plotNB.status.SetFields(['','2-theta =%9.3f '%(xpos,)]) |
---|
| 2444 | if G2frame.PickId and G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Index Peak List','Unit Cells List']: |
---|
| 2445 | found = [] |
---|
[1933] | 2446 | if len(G2frame.HKL): |
---|
[762] | 2447 | view = Page.toolbar._views.forward()[0][:2] |
---|
| 2448 | wid = view[1]-view[0] |
---|
[1933] | 2449 | found = G2frame.HKL[np.where(np.fabs(G2frame.HKL.T[-1]-xpos) < 0.002*wid)] |
---|
[762] | 2450 | if len(found): |
---|
| 2451 | h,k,l = found[0][:3] |
---|
| 2452 | Page.canvas.SetToolTipString('%d,%d,%d'%(int(h),int(k),int(l))) |
---|
| 2453 | else: |
---|
| 2454 | Page.canvas.SetToolTipString('') |
---|
| 2455 | |
---|
| 2456 | try: |
---|
| 2457 | plotNum = G2frame.G2plotNB.plotList.index('Powder Lines') |
---|
| 2458 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2459 | Page.figure.clf() |
---|
| 2460 | Plot = Page.figure.gca() |
---|
| 2461 | except ValueError: |
---|
| 2462 | Plot = G2frame.G2plotNB.addMpl('Powder Lines').gca() |
---|
| 2463 | plotNum = G2frame.G2plotNB.plotList.index('Powder Lines') |
---|
| 2464 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2465 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 2466 | |
---|
[796] | 2467 | Page.Choice = None |
---|
[762] | 2468 | Page.SetFocus() |
---|
| 2469 | Plot.set_title('Powder Pattern Lines') |
---|
| 2470 | Plot.set_xlabel(r'$\mathsf{2\theta}$',fontsize=14) |
---|
| 2471 | PickId = G2frame.PickId |
---|
| 2472 | PatternId = G2frame.PatternId |
---|
[1445] | 2473 | peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Index Peak List'))[0] |
---|
[762] | 2474 | for peak in peaks: |
---|
| 2475 | Plot.axvline(peak[0],color='b') |
---|
| 2476 | for hkl in G2frame.HKL: |
---|
[1571] | 2477 | Plot.axvline(hkl[-1],color='r',dashes=(5,5)) |
---|
[762] | 2478 | xmin = peaks[0][0] |
---|
| 2479 | xmax = peaks[-1][0] |
---|
| 2480 | delt = xmax-xmin |
---|
| 2481 | xlim = [max(0,xmin-delt/20.),min(180.,xmax+delt/20.)] |
---|
| 2482 | Plot.set_xlim(xlim) |
---|
| 2483 | Page.canvas.draw() |
---|
| 2484 | Page.toolbar.push_current() |
---|
| 2485 | |
---|
| 2486 | ################################################################################ |
---|
| 2487 | ##### PlotPeakWidths |
---|
| 2488 | ################################################################################ |
---|
| 2489 | |
---|
| 2490 | def PlotPeakWidths(G2frame): |
---|
[798] | 2491 | ''' Plotting of instrument broadening terms as function of 2-theta |
---|
[762] | 2492 | Seen when "Instrument Parameters" chosen from powder pattern data tree |
---|
| 2493 | ''' |
---|
[803] | 2494 | # sig = lambda Th,U,V,W: 1.17741*math.sqrt(U*tand(Th)**2+V*tand(Th)+W)*math.pi/18000. |
---|
| 2495 | # gam = lambda Th,X,Y: (X/cosd(Th)+Y*tand(Th))*math.pi/18000. |
---|
[1898] | 2496 | # 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] | 2497 | # gamFW2 = lambda s,g: math.sqrt(s**2+(0.4654996*g)**2)+.5345004*g #Ubaldo Bafile - private communication |
---|
[762] | 2498 | PatternId = G2frame.PatternId |
---|
| 2499 | limitID = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Limits') |
---|
| 2500 | if limitID: |
---|
[1017] | 2501 | limits = G2frame.PatternTree.GetItemPyData(limitID)[:2] |
---|
[762] | 2502 | else: |
---|
| 2503 | return |
---|
[796] | 2504 | Parms,Parms2 = G2frame.PatternTree.GetItemPyData( \ |
---|
[762] | 2505 | G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters')) |
---|
[792] | 2506 | if 'C' in Parms['Type'][0]: |
---|
[798] | 2507 | lam = G2mth.getWave(Parms) |
---|
[792] | 2508 | else: |
---|
| 2509 | difC = Parms['difC'][0] |
---|
[1451] | 2510 | try: # PATCH: deal with older peak lists, before changed to dict to implement TOF |
---|
| 2511 | peaks = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List'))['peaks'] |
---|
| 2512 | except TypeError: |
---|
| 2513 | print "Your peak list needs reformatting...", |
---|
| 2514 | item = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Peak List') |
---|
| 2515 | G2frame.PatternTree.SelectItem(item) |
---|
| 2516 | item = G2gd.GetPatternTreeItemId(G2frame,PatternId, 'Instrument Parameters') |
---|
| 2517 | G2frame.PatternTree.SelectItem(item) |
---|
| 2518 | print "done" |
---|
| 2519 | return |
---|
[762] | 2520 | try: |
---|
| 2521 | plotNum = G2frame.G2plotNB.plotList.index('Peak Widths') |
---|
| 2522 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2523 | Page.figure.clf() |
---|
| 2524 | Plot = Page.figure.gca() |
---|
| 2525 | except ValueError: |
---|
| 2526 | Plot = G2frame.G2plotNB.addMpl('Peak Widths').gca() |
---|
| 2527 | plotNum = G2frame.G2plotNB.plotList.index('Peak Widths') |
---|
| 2528 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[796] | 2529 | Page.Choice = None |
---|
[762] | 2530 | Page.SetFocus() |
---|
| 2531 | |
---|
| 2532 | Page.canvas.SetToolTipString('') |
---|
| 2533 | colors=['b','g','r','c','m','k'] |
---|
| 2534 | X = [] |
---|
| 2535 | Y = [] |
---|
| 2536 | Z = [] |
---|
| 2537 | W = [] |
---|
[792] | 2538 | if 'C' in Parms['Type'][0]: |
---|
[797] | 2539 | Plot.set_title('Instrument and sample peak widths') |
---|
[1032] | 2540 | Plot.set_xlabel(r'$Q, \AA^{-1}$',fontsize=14) |
---|
| 2541 | Plot.set_ylabel(r'$\Delta Q/Q, \Delta d/d$',fontsize=14) |
---|
[792] | 2542 | try: |
---|
[797] | 2543 | Xmin,Xmax = limits[1] |
---|
[798] | 2544 | X = np.linspace(Xmin,Xmax,num=101,endpoint=True) |
---|
| 2545 | Q = 4.*np.pi*npsind(X/2.)/lam |
---|
| 2546 | Z = np.ones_like(X) |
---|
| 2547 | data = G2mth.setPeakparms(Parms,Parms2,X,Z) |
---|
| 2548 | s = 1.17741*np.sqrt(data[4])*np.pi/18000. |
---|
| 2549 | g = data[6]*np.pi/18000. |
---|
[998] | 2550 | G = G2pwd.getgamFW(g,s) |
---|
[798] | 2551 | Y = s/nptand(X/2.) |
---|
| 2552 | Z = g/nptand(X/2.) |
---|
| 2553 | W = G/nptand(X/2.) |
---|
| 2554 | Plot.plot(Q,Y,color='r',label='Gaussian') |
---|
| 2555 | Plot.plot(Q,Z,color='g',label='Lorentzian') |
---|
| 2556 | Plot.plot(Q,W,color='b',label='G+L') |
---|
| 2557 | |
---|
[803] | 2558 | fit = G2mth.setPeakparms(Parms,Parms2,X,Z,useFit=True) |
---|
| 2559 | sf = 1.17741*np.sqrt(fit[4])*np.pi/18000. |
---|
| 2560 | gf = fit[6]*np.pi/18000. |
---|
[998] | 2561 | Gf = G2pwd.getgamFW(gf,sf) |
---|
[803] | 2562 | Yf = sf/nptand(X/2.) |
---|
| 2563 | Zf = gf/nptand(X/2.) |
---|
| 2564 | Wf = Gf/nptand(X/2.) |
---|
| 2565 | Plot.plot(Q,Yf,color='r',dashes=(5,5),label='Gaussian fit') |
---|
| 2566 | Plot.plot(Q,Zf,color='g',dashes=(5,5),label='Lorentzian fit') |
---|
| 2567 | Plot.plot(Q,Wf,color='b',dashes=(5,5),label='G+L fit') |
---|
| 2568 | |
---|
[792] | 2569 | X = [] |
---|
| 2570 | Y = [] |
---|
| 2571 | Z = [] |
---|
| 2572 | W = [] |
---|
| 2573 | V = [] |
---|
| 2574 | for peak in peaks: |
---|
| 2575 | X.append(4.0*math.pi*sind(peak[0]/2.0)/lam) |
---|
| 2576 | try: |
---|
| 2577 | s = 1.17741*math.sqrt(peak[4])*math.pi/18000. |
---|
| 2578 | except ValueError: |
---|
| 2579 | s = 0.01 |
---|
| 2580 | g = peak[6]*math.pi/18000. |
---|
[998] | 2581 | G = G2pwd.getgamFW(g,s) |
---|
[792] | 2582 | Y.append(s/tand(peak[0]/2.)) |
---|
| 2583 | Z.append(g/tand(peak[0]/2.)) |
---|
| 2584 | W.append(G/tand(peak[0]/2.)) |
---|
[803] | 2585 | if len(peaks): |
---|
| 2586 | Plot.plot(X,Y,'+',color='r',label='G peak') |
---|
| 2587 | Plot.plot(X,Z,'+',color='g',label='L peak') |
---|
| 2588 | Plot.plot(X,W,'+',color='b',label='G+L peak') |
---|
[792] | 2589 | Plot.legend(loc='best') |
---|
| 2590 | Page.canvas.draw() |
---|
| 2591 | except ValueError: |
---|
| 2592 | print '**** ERROR - default U,V,W profile coefficients yield sqrt of negative value at 2theta =', \ |
---|
| 2593 | '%.3f'%(2*theta) |
---|
| 2594 | G2frame.G2plotNB.Delete('Peak Widths') |
---|
[1462] | 2595 | else: #'T'OF |
---|
[797] | 2596 | Plot.set_title('Instrument and sample peak coefficients') |
---|
[1032] | 2597 | Plot.set_xlabel(r'$Q, \AA^{-1}$',fontsize=14) |
---|
| 2598 | Plot.set_ylabel(r'$\alpha, \beta, \Delta Q/Q, \Delta d/d$',fontsize=14) |
---|
[797] | 2599 | Xmin,Xmax = limits[1] |
---|
[798] | 2600 | T = np.linspace(Xmin,Xmax,num=101,endpoint=True) |
---|
| 2601 | Z = np.ones_like(T) |
---|
| 2602 | data = G2mth.setPeakparms(Parms,Parms2,T,Z) |
---|
| 2603 | ds = T/difC |
---|
| 2604 | Q = 2.*np.pi/ds |
---|
| 2605 | A = data[4] |
---|
| 2606 | B = data[6] |
---|
| 2607 | S = 1.17741*np.sqrt(data[8])/T |
---|
| 2608 | G = data[10]/T |
---|
| 2609 | Plot.plot(Q,A,color='r',label='Alpha') |
---|
| 2610 | Plot.plot(Q,B,color='g',label='Beta') |
---|
| 2611 | Plot.plot(Q,S,color='b',label='Gaussian') |
---|
| 2612 | Plot.plot(Q,G,color='m',label='Lorentzian') |
---|
[803] | 2613 | |
---|
| 2614 | fit = G2mth.setPeakparms(Parms,Parms2,T,Z) |
---|
| 2615 | ds = T/difC |
---|
| 2616 | Q = 2.*np.pi/ds |
---|
| 2617 | Af = fit[4] |
---|
| 2618 | Bf = fit[6] |
---|
| 2619 | Sf = 1.17741*np.sqrt(fit[8])/T |
---|
| 2620 | Gf = fit[10]/T |
---|
| 2621 | Plot.plot(Q,Af,color='r',dashes=(5,5),label='Alpha fit') |
---|
| 2622 | Plot.plot(Q,Bf,color='g',dashes=(5,5),label='Beta fit') |
---|
| 2623 | Plot.plot(Q,Sf,color='b',dashes=(5,5),label='Gaussian fit') |
---|
| 2624 | Plot.plot(Q,Gf,color='m',dashes=(5,5),label='Lorentzian fit') |
---|
| 2625 | |
---|
[797] | 2626 | T = [] |
---|
| 2627 | A = [] |
---|
| 2628 | B = [] |
---|
[798] | 2629 | S = [] |
---|
| 2630 | G = [] |
---|
[797] | 2631 | W = [] |
---|
[798] | 2632 | Q = [] |
---|
[797] | 2633 | V = [] |
---|
| 2634 | for peak in peaks: |
---|
| 2635 | T.append(peak[0]) |
---|
| 2636 | A.append(peak[4]) |
---|
| 2637 | B.append(peak[6]) |
---|
[798] | 2638 | Q.append(2.*np.pi*difC/peak[0]) |
---|
| 2639 | S.append(1.17741*np.sqrt(peak[8])/peak[0]) |
---|
| 2640 | G.append(peak[10]/peak[0]) |
---|
[797] | 2641 | |
---|
| 2642 | |
---|
[798] | 2643 | Plot.plot(Q,A,'+',color='r',label='Alpha peak') |
---|
| 2644 | Plot.plot(Q,B,'+',color='g',label='Beta peak') |
---|
| 2645 | Plot.plot(Q,S,'+',color='b',label='Gaussian peak') |
---|
| 2646 | Plot.plot(Q,G,'+',color='m',label='Lorentzian peak') |
---|
[797] | 2647 | Plot.legend(loc='best') |
---|
| 2648 | Page.canvas.draw() |
---|
[762] | 2649 | |
---|
| 2650 | |
---|
| 2651 | ################################################################################ |
---|
| 2652 | ##### PlotSizeStrainPO |
---|
| 2653 | ################################################################################ |
---|
| 2654 | |
---|
[1731] | 2655 | def PlotSizeStrainPO(G2frame,data,hist='',Start=False): |
---|
[762] | 2656 | '''Plot 3D mustrain/size/preferred orientation figure. In this instance data is for a phase |
---|
| 2657 | ''' |
---|
| 2658 | |
---|
| 2659 | PatternId = G2frame.PatternId |
---|
| 2660 | generalData = data['General'] |
---|
| 2661 | SGData = generalData['SGData'] |
---|
| 2662 | SGLaue = SGData['SGLaue'] |
---|
| 2663 | if Start: #initialize the spherical harmonics qlmn arrays |
---|
| 2664 | ptx.pyqlmninit() |
---|
| 2665 | Start = False |
---|
| 2666 | # MuStrKeys = G2spc.MustrainNames(SGData) |
---|
| 2667 | cell = generalData['Cell'][1:] |
---|
| 2668 | A,B = G2lat.cell2AB(cell[:6]) |
---|
| 2669 | Vol = cell[6] |
---|
| 2670 | useList = data['Histograms'] |
---|
| 2671 | phase = generalData['Name'] |
---|
| 2672 | plotType = generalData['Data plot type'] |
---|
| 2673 | plotDict = {'Mustrain':'Mustrain','Size':'Size','Preferred orientation':'Pref.Ori.'} |
---|
| 2674 | for ptype in plotDict: |
---|
| 2675 | G2frame.G2plotNB.Delete(ptype) |
---|
[1800] | 2676 | if plotType in ['None'] or not useList: |
---|
[762] | 2677 | return |
---|
[1731] | 2678 | if hist == '': |
---|
| 2679 | hist = useList.keys()[0] |
---|
[762] | 2680 | numPlots = len(useList) |
---|
| 2681 | |
---|
[1835] | 2682 | try: |
---|
| 2683 | plotNum = G2frame.G2plotNB.plotList.index(plotType) |
---|
| 2684 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2685 | Page.figure.clf() |
---|
| 2686 | Plot = Page.figure.gca() |
---|
| 2687 | if not Page.IsShown(): |
---|
| 2688 | Page.Show() |
---|
| 2689 | except ValueError: |
---|
| 2690 | if plotType in ['Mustrain','Size']: |
---|
| 2691 | Plot = mp3d.Axes3D(G2frame.G2plotNB.add3D(plotType)) |
---|
| 2692 | else: |
---|
| 2693 | Plot = G2frame.G2plotNB.addMpl(plotType).gca() |
---|
| 2694 | plotNum = G2frame.G2plotNB.plotList.index(plotType) |
---|
| 2695 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[796] | 2696 | Page.Choice = None |
---|
[762] | 2697 | G2frame.G2plotNB.status.SetStatusText('',1) |
---|
| 2698 | |
---|
[1731] | 2699 | PHI = np.linspace(0.,360.,30,True) |
---|
| 2700 | PSI = np.linspace(0.,180.,30,True) |
---|
| 2701 | X = np.outer(npsind(PHI),npsind(PSI)) |
---|
| 2702 | Y = np.outer(npcosd(PHI),npsind(PSI)) |
---|
| 2703 | Z = np.outer(np.ones(np.size(PHI)),npcosd(PSI)) |
---|
| 2704 | try: #temp patch instead of 'mustrain' for old files with 'microstrain' |
---|
| 2705 | coeff = useList[hist][plotDict[plotType]] |
---|
| 2706 | except KeyError: |
---|
| 2707 | return |
---|
| 2708 | if plotType in ['Mustrain','Size']: |
---|
| 2709 | if coeff[0] == 'isotropic': |
---|
| 2710 | X *= coeff[1][0] |
---|
| 2711 | Y *= coeff[1][0] |
---|
| 2712 | Z *= coeff[1][0] |
---|
| 2713 | elif coeff[0] == 'uniaxial': |
---|
| 2714 | |
---|
| 2715 | def uniaxCalc(xyz,iso,aniso,axes): |
---|
| 2716 | Z = np.array(axes) |
---|
| 2717 | cp = abs(np.dot(xyz,Z)) |
---|
| 2718 | sp = np.sqrt(1.-cp**2) |
---|
| 2719 | R = iso*aniso/np.sqrt((iso*cp)**2+(aniso*sp)**2) |
---|
| 2720 | return R*xyz |
---|
[762] | 2721 | |
---|
[1731] | 2722 | iso,aniso = coeff[1][:2] |
---|
| 2723 | axes = np.inner(A,np.array(coeff[3])) |
---|
| 2724 | axes /= nl.norm(axes) |
---|
| 2725 | Shkl = np.array(coeff[1]) |
---|
| 2726 | XYZ = np.dstack((X,Y,Z)) |
---|
| 2727 | XYZ = np.nan_to_num(np.apply_along_axis(uniaxCalc,2,XYZ,iso,aniso,axes)) |
---|
| 2728 | X,Y,Z = np.dsplit(XYZ,3) |
---|
| 2729 | X = X[:,:,0] |
---|
| 2730 | Y = Y[:,:,0] |
---|
| 2731 | Z = Z[:,:,0] |
---|
| 2732 | |
---|
| 2733 | elif coeff[0] == 'ellipsoidal': |
---|
| 2734 | |
---|
| 2735 | def ellipseCalc(xyz,E,R): |
---|
| 2736 | XYZ = xyz*E.T |
---|
| 2737 | return np.inner(XYZ.T,R) |
---|
| 2738 | |
---|
| 2739 | S6 = coeff[4] |
---|
| 2740 | Sij = G2lat.U6toUij(S6) |
---|
| 2741 | E,R = nl.eigh(Sij) |
---|
| 2742 | XYZ = np.dstack((X,Y,Z)) |
---|
| 2743 | XYZ = np.nan_to_num(np.apply_along_axis(ellipseCalc,2,XYZ,E,R)) |
---|
| 2744 | X,Y,Z = np.dsplit(XYZ,3) |
---|
| 2745 | X = X[:,:,0] |
---|
| 2746 | Y = Y[:,:,0] |
---|
| 2747 | Z = Z[:,:,0] |
---|
| 2748 | |
---|
| 2749 | elif coeff[0] == 'generalized': |
---|
| 2750 | |
---|
| 2751 | def genMustrain(xyz,SGData,A,Shkl): |
---|
| 2752 | uvw = np.inner(A.T,xyz) |
---|
| 2753 | Strm = np.array(G2spc.MustrainCoeff(uvw,SGData)) |
---|
| 2754 | Sum = np.sum(np.multiply(Shkl,Strm)) |
---|
| 2755 | Sum = np.where(Sum > 0.01,Sum,0.01) |
---|
| 2756 | Sum = np.sqrt(Sum) |
---|
| 2757 | return Sum*xyz |
---|
| 2758 | |
---|
| 2759 | Shkl = np.array(coeff[4]) |
---|
| 2760 | if np.any(Shkl): |
---|
| 2761 | XYZ = np.dstack((X,Y,Z)) |
---|
| 2762 | XYZ = np.nan_to_num(np.apply_along_axis(genMustrain,2,XYZ,SGData,A,Shkl)) |
---|
| 2763 | X,Y,Z = np.dsplit(XYZ,3) |
---|
| 2764 | X = X[:,:,0] |
---|
| 2765 | Y = Y[:,:,0] |
---|
| 2766 | Z = Z[:,:,0] |
---|
[762] | 2767 | |
---|
[1731] | 2768 | if np.any(X) and np.any(Y) and np.any(Z): |
---|
| 2769 | errFlags = np.seterr(all='ignore') |
---|
| 2770 | Plot.plot_surface(X,Y,Z,rstride=1,cstride=1,color='g',linewidth=1) |
---|
| 2771 | np.seterr(all='ignore') |
---|
| 2772 | xyzlim = np.array([Plot.get_xlim3d(),Plot.get_ylim3d(),Plot.get_zlim3d()]).T |
---|
| 2773 | XYZlim = [min(xyzlim[0]),max(xyzlim[1])] |
---|
| 2774 | Plot.set_xlim3d(XYZlim) |
---|
| 2775 | Plot.set_ylim3d(XYZlim) |
---|
| 2776 | Plot.set_zlim3d(XYZlim) |
---|
| 2777 | Plot.set_aspect('equal') |
---|
| 2778 | if plotType == 'Size': |
---|
| 2779 | Plot.set_title('Crystallite size for '+phase+'\n'+coeff[0]+' model') |
---|
| 2780 | Plot.set_xlabel(r'X, $\mu$m') |
---|
| 2781 | Plot.set_ylabel(r'Y, $\mu$m') |
---|
| 2782 | Plot.set_zlabel(r'Z, $\mu$m') |
---|
| 2783 | else: |
---|
| 2784 | Plot.set_title(r'$\mu$strain for '+phase+'\n'+coeff[0]+' model') |
---|
| 2785 | Plot.set_xlabel(r'X, $\mu$strain') |
---|
| 2786 | Plot.set_ylabel(r'Y, $\mu$strain') |
---|
| 2787 | Plot.set_zlabel(r'Z, $\mu$strain') |
---|
| 2788 | else: |
---|
| 2789 | h,k,l = generalData['POhkl'] |
---|
| 2790 | if coeff[0] == 'MD': |
---|
| 2791 | print 'March-Dollase preferred orientation plot' |
---|
| 2792 | |
---|
| 2793 | else: |
---|
| 2794 | PH = np.array(generalData['POhkl']) |
---|
| 2795 | phi,beta = G2lat.CrsAng(PH,cell[:6],SGData) |
---|
| 2796 | SHCoef = {} |
---|
| 2797 | for item in coeff[5]: |
---|
| 2798 | L,N = eval(item.strip('C')) |
---|
| 2799 | SHCoef['C%d,0,%d'%(L,N)] = coeff[5][item] |
---|
| 2800 | ODFln = G2lat.Flnh(Start,SHCoef,phi,beta,SGData) |
---|
| 2801 | X = np.linspace(0,90.0,26) |
---|
| 2802 | Y = G2lat.polfcal(ODFln,'0',X,0.0) |
---|
| 2803 | Plot.plot(X,Y,color='k',label=str(PH)) |
---|
| 2804 | Plot.legend(loc='best') |
---|
[1779] | 2805 | Plot.set_title('Axial distribution for HKL='+str(PH)+' in '+phase+'\n'+hist) |
---|
[1731] | 2806 | Plot.set_xlabel(r'$\psi$',fontsize=16) |
---|
| 2807 | Plot.set_ylabel('MRD',fontsize=14) |
---|
[762] | 2808 | Page.canvas.draw() |
---|
| 2809 | |
---|
| 2810 | ################################################################################ |
---|
| 2811 | ##### PlotTexture |
---|
| 2812 | ################################################################################ |
---|
[1804] | 2813 | |
---|
[762] | 2814 | def PlotTexture(G2frame,data,Start=False): |
---|
[1804] | 2815 | '''Pole figure, inverse pole figure plotting. |
---|
[762] | 2816 | dict generalData contains all phase info needed which is in data |
---|
| 2817 | ''' |
---|
| 2818 | |
---|
| 2819 | shModels = ['cylindrical','none','shear - 2/m','rolling - mmm'] |
---|
| 2820 | SamSym = dict(zip(shModels,['0','-1','2/m','mmm'])) |
---|
| 2821 | PatternId = G2frame.PatternId |
---|
| 2822 | generalData = data['General'] |
---|
| 2823 | SGData = generalData['SGData'] |
---|
[1799] | 2824 | pName = generalData['Name'] |
---|
[762] | 2825 | textureData = generalData['SH Texture'] |
---|
| 2826 | G2frame.G2plotNB.Delete('Texture') |
---|
| 2827 | if not textureData['Order']: |
---|
| 2828 | return #no plot!! |
---|
| 2829 | SHData = generalData['SH Texture'] |
---|
| 2830 | SHCoef = SHData['SH Coeff'][1] |
---|
| 2831 | cell = generalData['Cell'][1:7] |
---|
| 2832 | Amat,Bmat = G2lat.cell2AB(cell) |
---|
| 2833 | sq2 = 1.0/math.sqrt(2.0) |
---|
| 2834 | |
---|
| 2835 | def rp2xyz(r,p): |
---|
| 2836 | z = npcosd(r) |
---|
| 2837 | xy = np.sqrt(1.-z**2) |
---|
| 2838 | return xy*npsind(p),xy*npcosd(p),z |
---|
| 2839 | |
---|
| 2840 | def OnMotion(event): |
---|
| 2841 | SHData = data['General']['SH Texture'] |
---|
| 2842 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
| 2843 | xpos = event.xdata |
---|
| 2844 | ypos = event.ydata |
---|
| 2845 | if 'Inverse' in SHData['PlotType']: |
---|
| 2846 | r = xpos**2+ypos**2 |
---|
| 2847 | if r <= 1.0: |
---|
| 2848 | if 'equal' in G2frame.Projection: |
---|
| 2849 | r,p = 2.*npasind(np.sqrt(r)*sq2),npatan2d(ypos,xpos) |
---|
| 2850 | else: |
---|
| 2851 | r,p = 2.*npatand(np.sqrt(r)),npatan2d(ypos,xpos) |
---|
| 2852 | ipf = G2lat.invpolfcal(IODFln,SGData,np.array([r,]),np.array([p,])) |
---|
[1844] | 2853 | xyz = np.inner(Bmat,np.array([rp2xyz(r,p)])) |
---|
[762] | 2854 | y,x,z = list(xyz/np.max(np.abs(xyz))) |
---|
| 2855 | |
---|
| 2856 | G2frame.G2plotNB.status.SetFields(['', |
---|
| 2857 | 'psi =%9.3f, beta =%9.3f, MRD =%9.3f hkl=%5.2f,%5.2f,%5.2f'%(r,p,ipf,x,y,z)]) |
---|
| 2858 | |
---|
| 2859 | elif 'Axial' in SHData['PlotType']: |
---|
| 2860 | pass |
---|
| 2861 | |
---|
| 2862 | else: #ordinary pole figure |
---|
| 2863 | z = xpos**2+ypos**2 |
---|
| 2864 | if z <= 1.0: |
---|
| 2865 | z = np.sqrt(z) |
---|
| 2866 | if 'equal' in G2frame.Projection: |
---|
| 2867 | r,p = 2.*npasind(z*sq2),npatan2d(ypos,xpos) |
---|
| 2868 | else: |
---|
| 2869 | r,p = 2.*npatand(z),npatan2d(ypos,xpos) |
---|
| 2870 | pf = G2lat.polfcal(ODFln,SamSym[textureData['Model']],np.array([r,]),np.array([p,])) |
---|
| 2871 | G2frame.G2plotNB.status.SetFields(['','phi =%9.3f, gam =%9.3f, MRD =%9.3f'%(r,p,pf)]) |
---|
| 2872 | |
---|
| 2873 | try: |
---|
| 2874 | plotNum = G2frame.G2plotNB.plotList.index('Texture') |
---|
| 2875 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2876 | Page.figure.clf() |
---|
| 2877 | Plot = Page.figure.gca() |
---|
| 2878 | if not Page.IsShown(): |
---|
| 2879 | Page.Show() |
---|
| 2880 | except ValueError: |
---|
[1804] | 2881 | if '3D' in SHData['PlotType']: |
---|
| 2882 | Plot = mp3d.Axes3D(G2frame.G2plotNB.add3D('Texture')) |
---|
| 2883 | else: |
---|
| 2884 | Plot = G2frame.G2plotNB.addMpl('Texture').gca() |
---|
[762] | 2885 | plotNum = G2frame.G2plotNB.plotList.index('Texture') |
---|
| 2886 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 2887 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 2888 | |
---|
[796] | 2889 | Page.Choice = None |
---|
[762] | 2890 | Page.SetFocus() |
---|
| 2891 | G2frame.G2plotNB.status.SetFields(['','']) |
---|
| 2892 | PH = np.array(SHData['PFhkl']) |
---|
| 2893 | phi,beta = G2lat.CrsAng(PH,cell,SGData) |
---|
| 2894 | ODFln = G2lat.Flnh(Start,SHCoef,phi,beta,SGData) |
---|
[1780] | 2895 | if not np.any(ODFln): |
---|
| 2896 | return |
---|
[762] | 2897 | PX = np.array(SHData['PFxyz']) |
---|
| 2898 | gam = atan2d(PX[0],PX[1]) |
---|
| 2899 | xy = math.sqrt(PX[0]**2+PX[1]**2) |
---|
| 2900 | xyz = math.sqrt(PX[0]**2+PX[1]**2+PX[2]**2) |
---|
| 2901 | psi = asind(xy/xyz) |
---|
| 2902 | IODFln = G2lat.Glnh(Start,SHCoef,psi,gam,SamSym[textureData['Model']]) |
---|
| 2903 | if 'Axial' in SHData['PlotType']: |
---|
| 2904 | X = np.linspace(0,90.0,26) |
---|
| 2905 | Y = G2lat.polfcal(ODFln,SamSym[textureData['Model']],X,0.0) |
---|
| 2906 | Plot.plot(X,Y,color='k',label=str(SHData['PFhkl'])) |
---|
| 2907 | Plot.legend(loc='best') |
---|
[1799] | 2908 | h,k,l = SHData['PFhkl'] |
---|
| 2909 | Plot.set_title('%d %d %d Axial distribution for %s'%(h,k,l,pName)) |
---|
[762] | 2910 | Plot.set_xlabel(r'$\psi$',fontsize=16) |
---|
| 2911 | Plot.set_ylabel('MRD',fontsize=14) |
---|
| 2912 | |
---|
| 2913 | else: |
---|
| 2914 | npts = 201 |
---|
| 2915 | if 'Inverse' in SHData['PlotType']: |
---|
| 2916 | X,Y = np.meshgrid(np.linspace(1.,-1.,npts),np.linspace(-1.,1.,npts)) |
---|
| 2917 | R,P = np.sqrt(X**2+Y**2).flatten(),npatan2d(X,Y).flatten() |
---|
| 2918 | if 'equal' in G2frame.Projection: |
---|
| 2919 | R = np.where(R <= 1.,2.*npasind(R*sq2),0.0) |
---|
| 2920 | else: |
---|
| 2921 | R = np.where(R <= 1.,2.*npatand(R),0.0) |
---|
| 2922 | Z = np.zeros_like(R) |
---|
| 2923 | Z = G2lat.invpolfcal(IODFln,SGData,R,P) |
---|
| 2924 | Z = np.reshape(Z,(npts,npts)) |
---|
| 2925 | try: |
---|
[1780] | 2926 | CS = Plot.contour(Y,X,Z,aspect='equal') |
---|
| 2927 | Plot.clabel(CS,fontsize=9,inline=1) |
---|
[762] | 2928 | except ValueError: |
---|
| 2929 | pass |
---|
[1780] | 2930 | Img = Plot.imshow(Z.T,aspect='equal',cmap=G2frame.ContourColor,extent=[-1,1,-1,1]) |
---|
[762] | 2931 | Page.figure.colorbar(Img) |
---|
[1799] | 2932 | x,y,z = SHData['PFxyz'] |
---|
[1804] | 2933 | Plot.axis('off') |
---|
[1799] | 2934 | Plot.set_title('%d %d %d Inverse pole figure for %s'%(int(x),int(y),int(z),pName)) |
---|
[762] | 2935 | Plot.set_xlabel(G2frame.Projection.capitalize()+' projection') |
---|
[1804] | 2936 | |
---|
| 2937 | elif '3D' in SHData['PlotType']: |
---|
| 2938 | PSI,GAM = np.mgrid[0:31,0:31] |
---|
| 2939 | PSI = PSI.flatten()*6. |
---|
| 2940 | GAM = GAM.flatten()*12. |
---|
| 2941 | P = G2lat.polfcal(ODFln,SamSym[textureData['Model']],PSI,GAM).reshape((31,31)) |
---|
| 2942 | GAM = np.linspace(0.,360.,31,True) |
---|
| 2943 | PSI = np.linspace(0.,180.,31,True) |
---|
| 2944 | X = np.outer(npsind(GAM),npsind(PSI))*P.T |
---|
| 2945 | Y = np.outer(npcosd(GAM),npsind(PSI))*P.T |
---|
| 2946 | Z = np.outer(np.ones(np.size(GAM)),npcosd(PSI))*P.T |
---|
| 2947 | h,k,l = SHData['PFhkl'] |
---|
| 2948 | |
---|
| 2949 | if np.any(X) and np.any(Y) and np.any(Z): |
---|
| 2950 | errFlags = np.seterr(all='ignore') |
---|
| 2951 | Plot.plot_surface(X,Y,Z,rstride=1,cstride=1,color='g',linewidth=1) |
---|
| 2952 | np.seterr(all='ignore') |
---|
| 2953 | xyzlim = np.array([Plot.get_xlim3d(),Plot.get_ylim3d(),Plot.get_zlim3d()]).T |
---|
| 2954 | XYZlim = [min(xyzlim[0]),max(xyzlim[1])] |
---|
| 2955 | Plot.set_xlim3d(XYZlim) |
---|
| 2956 | Plot.set_ylim3d(XYZlim) |
---|
| 2957 | Plot.set_zlim3d(XYZlim) |
---|
| 2958 | Plot.set_aspect('equal') |
---|
| 2959 | Plot.set_title('%d %d %d Pole distribution for %s'%(h,k,l,pName)) |
---|
| 2960 | Plot.set_xlabel(r'X, MRD') |
---|
| 2961 | Plot.set_ylabel(r'Y, MRD') |
---|
| 2962 | Plot.set_zlabel(r'Z, MRD') |
---|
[762] | 2963 | else: |
---|
[1806] | 2964 | PFproj = textureData.get('PFproj','XY') |
---|
| 2965 | PRrev = textureData.get('PFrev',False) |
---|
[762] | 2966 | X,Y = np.meshgrid(np.linspace(1.,-1.,npts),np.linspace(-1.,1.,npts)) |
---|
| 2967 | R,P = np.sqrt(X**2+Y**2).flatten(),npatan2d(X,Y).flatten() |
---|
| 2968 | if 'equal' in G2frame.Projection: |
---|
| 2969 | R = np.where(R <= 1.,2.*npasind(R*sq2),0.0) |
---|
| 2970 | else: |
---|
| 2971 | R = np.where(R <= 1.,2.*npatand(R),0.0) |
---|
| 2972 | Z = np.zeros_like(R) |
---|
| 2973 | Z = G2lat.polfcal(ODFln,SamSym[textureData['Model']],R,P) |
---|
| 2974 | Z = np.reshape(Z,(npts,npts)) |
---|
| 2975 | try: |
---|
| 2976 | CS = Plot.contour(Y,X,Z,aspect='equal') |
---|
| 2977 | Plot.clabel(CS,fontsize=9,inline=1) |
---|
| 2978 | except ValueError: |
---|
| 2979 | pass |
---|
| 2980 | Img = Plot.imshow(Z.T,aspect='equal',cmap=G2frame.ContourColor,extent=[-1,1,-1,1]) |
---|
| 2981 | Page.figure.colorbar(Img) |
---|
[1799] | 2982 | h,k,l = SHData['PFhkl'] |
---|
[1804] | 2983 | Plot.axis('off') |
---|
[1799] | 2984 | Plot.set_title('%d %d %d Pole figure for %s'%(h,k,l,pName)) |
---|
[762] | 2985 | Plot.set_xlabel(G2frame.Projection.capitalize()+' projection') |
---|
| 2986 | Page.canvas.draw() |
---|
| 2987 | |
---|
| 2988 | ################################################################################ |
---|
[1625] | 2989 | ##### Plot Modulation |
---|
[1601] | 2990 | ################################################################################ |
---|
| 2991 | |
---|
[1625] | 2992 | def ModulationPlot(G2frame,data,atom,ax,off=0): |
---|
| 2993 | global Off,Atom,Ax |
---|
| 2994 | Off = off |
---|
| 2995 | Atom = atom |
---|
| 2996 | Ax = ax |
---|
| 2997 | def OnMotion(event): |
---|
| 2998 | xpos = event.xdata |
---|
| 2999 | if xpos: #avoid out of frame mouse position |
---|
| 3000 | ypos = event.ydata |
---|
| 3001 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 3002 | try: |
---|
| 3003 | G2frame.G2plotNB.status.SetStatusText('t =%9.3f %s =%9.3f'%(xpos,GkDelta+Ax,ypos),1) |
---|
| 3004 | except TypeError: |
---|
| 3005 | G2frame.G2plotNB.status.SetStatusText('Select '+Title+' pattern first',1) |
---|
[1601] | 3006 | |
---|
[1625] | 3007 | def OnPlotKeyPress(event): |
---|
| 3008 | global Off,Atom,Ax |
---|
[1694] | 3009 | newPlot = False |
---|
[1625] | 3010 | if event.key == '0': |
---|
| 3011 | Off = 0 |
---|
[1694] | 3012 | elif event.key in ['+','=']: |
---|
[1625] | 3013 | Off += 1 |
---|
| 3014 | elif event.key == '-': |
---|
[1626] | 3015 | Off -= 1 |
---|
[1630] | 3016 | elif event.key in ['l','r',] and mapData['Flip']: |
---|
[1626] | 3017 | roll = 1 |
---|
| 3018 | if event.key == 'l': |
---|
| 3019 | roll = -1 |
---|
| 3020 | rho = Map['rho'] |
---|
| 3021 | Map['rho'] = np.roll(rho,roll,axis=3) |
---|
[1625] | 3022 | wx.CallAfter(ModulationPlot,G2frame,data,Atom,Ax,Off) |
---|
| 3023 | |
---|
[1601] | 3024 | try: |
---|
| 3025 | plotNum = G2frame.G2plotNB.plotList.index('Modulation') |
---|
| 3026 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3027 | Page.figure.clf() |
---|
| 3028 | Plot = Page.figure.gca() |
---|
| 3029 | if not Page.IsShown(): |
---|
| 3030 | Page.Show() |
---|
| 3031 | except ValueError: |
---|
| 3032 | Plot = G2frame.G2plotNB.addMpl('Modulation').gca() |
---|
| 3033 | plotNum = G2frame.G2plotNB.plotList.index('Modulation') |
---|
| 3034 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[1625] | 3035 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 3036 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
[1630] | 3037 | |
---|
[1625] | 3038 | Page.SetFocus() |
---|
[1604] | 3039 | General = data['General'] |
---|
| 3040 | cx,ct,cs,cia = General['AtomPtrs'] |
---|
[1630] | 3041 | mapData = General['Map'] |
---|
| 3042 | if mapData['Flip']: |
---|
| 3043 | Page.Choice = ['+: shift up','-: shift down','0: reset shift','l: move left','r: move right'] |
---|
| 3044 | else: |
---|
| 3045 | Page.Choice = ['+: shift up','-: shift down','0: reset shift'] |
---|
| 3046 | Page.keyPress = OnPlotKeyPress |
---|
[1604] | 3047 | Map = General['4DmapData'] |
---|
| 3048 | MapType = Map['MapType'] |
---|
| 3049 | rhoSize = np.array(Map['rho'].shape) |
---|
| 3050 | atxyz = np.array(atom[cx:cx+3]) |
---|
[1625] | 3051 | waveType = atom[-1]['SS1']['waveType'] |
---|
| 3052 | Spos = atom[-1]['SS1']['Spos'] |
---|
| 3053 | tau = np.linspace(0.,2.,101) |
---|
| 3054 | wave = np.zeros((3,101)) |
---|
| 3055 | if len(Spos): |
---|
| 3056 | scof = [] |
---|
| 3057 | ccof = [] |
---|
| 3058 | for i,spos in enumerate(Spos): |
---|
| 3059 | if waveType in ['Sawtooth','ZigZag'] and not i: |
---|
| 3060 | Toff = spos[0][0] |
---|
| 3061 | slopes = np.array(spos[0][1:]) |
---|
| 3062 | if waveType == 'Sawtooth': |
---|
| 3063 | wave = G2mth.posSawtooth(tau,Toff,slopes) |
---|
| 3064 | elif waveType == 'ZigZag': |
---|
| 3065 | wave = G2mth.posZigZag(tau,Toff,slopes) |
---|
| 3066 | else: |
---|
| 3067 | scof.append(spos[0][:3]) |
---|
| 3068 | ccof.append(spos[0][3:]) |
---|
[1958] | 3069 | wave += G2mth.posFourier(tau,np.array(scof),np.array(ccof),1) #hmm, why -1 work for Na2CO3? |
---|
[1633] | 3070 | if mapData['Flip']: |
---|
| 3071 | Title = 'Charge flip' |
---|
| 3072 | else: |
---|
| 3073 | Title = MapType |
---|
| 3074 | Title += ' map for atom '+atom[0]+ \ |
---|
[1604] | 3075 | ' at %.4f %.4f %.4f'%(atxyz[0],atxyz[1],atxyz[2]) |
---|
| 3076 | ix = -np.array(np.rint(rhoSize[:3]*atxyz),dtype='i') |
---|
| 3077 | ix += (rhoSize[:3]/2) |
---|
| 3078 | ix = ix%rhoSize[:3] |
---|
| 3079 | rho = np.roll(np.roll(np.roll(Map['rho'],ix[0],axis=0),ix[1],axis=1),ix[2],axis=2) |
---|
| 3080 | ix = rhoSize[:3]/2 |
---|
| 3081 | ib = 4 |
---|
| 3082 | if Ax == 'x': |
---|
| 3083 | slab = np.sum(np.sum(rho[:,ix[1]-ib:ix[1]+ib,ix[2]-ib:ix[2]+ib,:],axis=2),axis=1) |
---|
[1626] | 3084 | Plot.plot(tau,wave[0]) |
---|
[1604] | 3085 | elif Ax == 'y': |
---|
| 3086 | slab = np.sum(np.sum(rho[ix[0]-ib:ix[0]+ib,:,ix[2]-ib:ix[2]+ib,:],axis=2),axis=0) |
---|
[1626] | 3087 | Plot.plot(tau,wave[1]) |
---|
[1604] | 3088 | elif Ax == 'z': |
---|
| 3089 | slab = np.sum(np.sum(rho[ix[0]-ib:ix[0]+ib,ix[1]-ib:ix[1]+ib,:,:],axis=1),axis=0) |
---|
[1626] | 3090 | Plot.plot(tau,wave[2]) |
---|
[1604] | 3091 | Plot.set_title(Title) |
---|
| 3092 | Plot.set_xlabel('t') |
---|
| 3093 | Plot.set_ylabel(r'$\mathsf{\Delta}$%s'%(Ax)) |
---|
[1633] | 3094 | Slab = np.hstack((slab,slab,slab)) |
---|
| 3095 | Plot.contour(Slab[:,:21],20,extent=(0.,2.,-.5+Off*.005,.5+Off*.005)) |
---|
[1604] | 3096 | Page.canvas.draw() |
---|
[1625] | 3097 | |
---|
[1601] | 3098 | ################################################################################ |
---|
[762] | 3099 | ##### PlotCovariance |
---|
| 3100 | ################################################################################ |
---|
| 3101 | |
---|
[859] | 3102 | def PlotCovariance(G2frame,Data): |
---|
[939] | 3103 | 'needs a doc string' |
---|
[762] | 3104 | if not Data: |
---|
| 3105 | print 'No covariance matrix available' |
---|
| 3106 | return |
---|
| 3107 | varyList = Data['varyList'] |
---|
| 3108 | values = Data['variables'] |
---|
| 3109 | Xmax = len(varyList) |
---|
| 3110 | covMatrix = Data['covMatrix'] |
---|
| 3111 | sig = np.sqrt(np.diag(covMatrix)) |
---|
| 3112 | xvar = np.outer(sig,np.ones_like(sig)) |
---|
| 3113 | covArray = np.divide(np.divide(covMatrix,xvar),xvar.T) |
---|
| 3114 | title = ' for\n'+Data['title'] |
---|
[1297] | 3115 | newAtomDict = Data.get('newAtomDict',{}) |
---|
[1772] | 3116 | G2frame.G2plotNB.Delete('Covariance') |
---|
[859] | 3117 | |
---|
[762] | 3118 | |
---|
| 3119 | def OnPlotKeyPress(event): |
---|
| 3120 | newPlot = False |
---|
| 3121 | if event.key == 's': |
---|
| 3122 | choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] |
---|
| 3123 | choice.sort() |
---|
| 3124 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice) |
---|
| 3125 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 3126 | sel = dlg.GetSelection() |
---|
| 3127 | G2frame.VcovColor = choice[sel] |
---|
| 3128 | else: |
---|
| 3129 | G2frame.VcovColor = 'RdYlGn' |
---|
| 3130 | dlg.Destroy() |
---|
[859] | 3131 | PlotCovariance(G2frame,Data) |
---|
[762] | 3132 | |
---|
| 3133 | def OnMotion(event): |
---|
| 3134 | if event.button: |
---|
| 3135 | ytics = imgAx.get_yticks() |
---|
| 3136 | ytics = np.where(ytics<len(varyList),ytics,-1) |
---|
| 3137 | ylabs = [np.where(0<=i ,varyList[int(i)],' ') for i in ytics] |
---|
[817] | 3138 | imgAx.set_yticklabels(ylabs) |
---|
[762] | 3139 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
| 3140 | xpos = int(event.xdata+.5) |
---|
| 3141 | ypos = int(event.ydata+.5) |
---|
| 3142 | if -1 < xpos < len(varyList) and -1 < ypos < len(varyList): |
---|
| 3143 | if xpos == ypos: |
---|
| 3144 | value = values[xpos] |
---|
| 3145 | name = varyList[xpos] |
---|
| 3146 | if varyList[xpos] in newAtomDict: |
---|
| 3147 | name,value = newAtomDict[name] |
---|
| 3148 | msg = '%s value = %.4g, esd = %.4g'%(name,value,sig[xpos]) |
---|
| 3149 | else: |
---|
| 3150 | msg = '%s - %s: %5.3f'%(varyList[xpos],varyList[ypos],covArray[xpos][ypos]) |
---|
| 3151 | Page.canvas.SetToolTipString(msg) |
---|
[796] | 3152 | G2frame.G2plotNB.status.SetFields(['',msg]) |
---|
[817] | 3153 | |
---|
[762] | 3154 | try: |
---|
| 3155 | plotNum = G2frame.G2plotNB.plotList.index('Covariance') |
---|
| 3156 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3157 | Page.figure.clf() |
---|
| 3158 | Plot = Page.figure.gca() |
---|
| 3159 | if not Page.IsShown(): |
---|
| 3160 | Page.Show() |
---|
| 3161 | except ValueError: |
---|
| 3162 | Plot = G2frame.G2plotNB.addMpl('Covariance').gca() |
---|
| 3163 | plotNum = G2frame.G2plotNB.plotList.index('Covariance') |
---|
| 3164 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3165 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 3166 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
[796] | 3167 | Page.Choice = ['s: to change colors'] |
---|
| 3168 | Page.keyPress = OnPlotKeyPress |
---|
[762] | 3169 | Page.SetFocus() |
---|
| 3170 | G2frame.G2plotNB.status.SetFields(['','']) |
---|
| 3171 | acolor = mpl.cm.get_cmap(G2frame.VcovColor) |
---|
[837] | 3172 | Img = Plot.imshow(covArray,aspect='equal',cmap=acolor,interpolation='nearest',origin='lower', |
---|
| 3173 | vmin=-1.,vmax=1.) |
---|
[762] | 3174 | imgAx = Img.get_axes() |
---|
| 3175 | ytics = imgAx.get_yticks() |
---|
| 3176 | ylabs = [varyList[int(i)] for i in ytics[:-1]] |
---|
| 3177 | imgAx.set_yticklabels(ylabs) |
---|
| 3178 | colorBar = Page.figure.colorbar(Img) |
---|
| 3179 | Plot.set_title('V-Cov matrix'+title) |
---|
| 3180 | Plot.set_xlabel('Variable number') |
---|
| 3181 | Plot.set_ylabel('Variable name') |
---|
| 3182 | Page.canvas.draw() |
---|
| 3183 | |
---|
| 3184 | ################################################################################ |
---|
[818] | 3185 | ##### PlotTorsion |
---|
| 3186 | ################################################################################ |
---|
| 3187 | |
---|
| 3188 | def PlotTorsion(G2frame,phaseName,Torsion,TorName,Names=[],Angles=[],Coeff=[]): |
---|
[939] | 3189 | 'needs a doc string' |
---|
[818] | 3190 | |
---|
| 3191 | global names |
---|
| 3192 | names = Names |
---|
| 3193 | sum = np.sum(Torsion) |
---|
| 3194 | torsion = np.log(2*Torsion+1.)/sum |
---|
| 3195 | tMin = np.min(torsion) |
---|
| 3196 | tMax = np.max(torsion) |
---|
| 3197 | torsion = 3.*(torsion-tMin)/(tMax-tMin) |
---|
| 3198 | X = np.linspace(0.,360.,num=45) |
---|
| 3199 | |
---|
[1098] | 3200 | def OnPick(event): |
---|
| 3201 | ind = event.ind[0] |
---|
| 3202 | msg = 'atoms:'+names[ind] |
---|
| 3203 | Page.canvas.SetToolTipString(msg) |
---|
[1099] | 3204 | try: |
---|
| 3205 | page = G2frame.dataDisplay.GetSelection() |
---|
| 3206 | except: |
---|
| 3207 | return |
---|
| 3208 | if G2frame.dataDisplay.GetPageText(page) == 'Torsion restraints': |
---|
| 3209 | torGrid = G2frame.dataDisplay.GetPage(page).Torsions |
---|
| 3210 | torGrid.ClearSelection() |
---|
| 3211 | for row in range(torGrid.GetNumberRows()): |
---|
| 3212 | if names[ind] in torGrid.GetCellValue(row,0): |
---|
| 3213 | torGrid.SelectRow(row) |
---|
| 3214 | torGrid.ForceRefresh() |
---|
| 3215 | |
---|
[818] | 3216 | def OnMotion(event): |
---|
| 3217 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
| 3218 | xpos = event.xdata |
---|
| 3219 | ypos = event.ydata |
---|
| 3220 | msg = 'torsion,energy: %5.3f %5.3f'%(xpos,ypos) |
---|
| 3221 | Page.canvas.SetToolTipString(msg) |
---|
| 3222 | |
---|
| 3223 | try: |
---|
| 3224 | plotNum = G2frame.G2plotNB.plotList.index('Torsion') |
---|
| 3225 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3226 | Page.figure.clf() |
---|
| 3227 | Plot = Page.figure.gca() |
---|
| 3228 | if not Page.IsShown(): |
---|
| 3229 | Page.Show() |
---|
| 3230 | except ValueError: |
---|
| 3231 | Plot = G2frame.G2plotNB.addMpl('Torsion').gca() |
---|
| 3232 | plotNum = G2frame.G2plotNB.plotList.index('Torsion') |
---|
| 3233 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[1098] | 3234 | Page.canvas.mpl_connect('pick_event', OnPick) |
---|
[818] | 3235 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 3236 | |
---|
| 3237 | Page.SetFocus() |
---|
[1098] | 3238 | G2frame.G2plotNB.status.SetFields(['','Use mouse LB to identify torsion atoms']) |
---|
[818] | 3239 | Plot.plot(X,torsion,'b+') |
---|
| 3240 | if len(Coeff): |
---|
| 3241 | X2 = np.linspace(0.,360.,45) |
---|
| 3242 | Y2 = np.array([-G2mth.calcTorsionEnergy(x,Coeff)[1] for x in X2]) |
---|
| 3243 | Plot.plot(X2,Y2,'r') |
---|
| 3244 | if len(Angles): |
---|
| 3245 | Eval = np.array([-G2mth.calcTorsionEnergy(x,Coeff)[1] for x in Angles]) |
---|
[1098] | 3246 | Plot.plot(Angles,Eval,'ro',picker=5) |
---|
[818] | 3247 | Plot.set_xlim((0.,360.)) |
---|
| 3248 | Plot.set_title('Torsion angles for '+TorName+' in '+phaseName) |
---|
| 3249 | Plot.set_xlabel('angle',fontsize=16) |
---|
| 3250 | Plot.set_ylabel('Energy',fontsize=16) |
---|
| 3251 | Page.canvas.draw() |
---|
| 3252 | |
---|
| 3253 | ################################################################################ |
---|
[817] | 3254 | ##### PlotRama |
---|
| 3255 | ################################################################################ |
---|
| 3256 | |
---|
[818] | 3257 | def PlotRama(G2frame,phaseName,Rama,RamaName,Names=[],PhiPsi=[],Coeff=[]): |
---|
[939] | 3258 | 'needs a doc string' |
---|
[817] | 3259 | |
---|
[818] | 3260 | global names |
---|
| 3261 | names = Names |
---|
| 3262 | rama = np.log(2*Rama+1.) |
---|
[817] | 3263 | ramaMax = np.max(rama) |
---|
| 3264 | rama = np.reshape(rama,(45,45)) |
---|
[818] | 3265 | global Phi,Psi |
---|
| 3266 | Phi = [] |
---|
| 3267 | Psi = [] |
---|
[817] | 3268 | |
---|
| 3269 | def OnPlotKeyPress(event): |
---|
| 3270 | newPlot = False |
---|
| 3271 | if event.key == 's': |
---|
| 3272 | choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] |
---|
| 3273 | choice.sort() |
---|
| 3274 | dlg = wx.SingleChoiceDialog(G2frame,'Select','Color scheme',choice) |
---|
| 3275 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 3276 | sel = dlg.GetSelection() |
---|
| 3277 | G2frame.RamaColor = choice[sel] |
---|
| 3278 | else: |
---|
| 3279 | G2frame.RamaColor = 'RdYlGn' |
---|
| 3280 | dlg.Destroy() |
---|
[818] | 3281 | PlotRama(G2frame,phaseName,Rama) |
---|
[817] | 3282 | |
---|
[1098] | 3283 | def OnPick(event): |
---|
| 3284 | ind = event.ind[0] |
---|
| 3285 | msg = 'atoms:'+names[ind] |
---|
| 3286 | Page.canvas.SetToolTipString(msg) |
---|
[1099] | 3287 | try: |
---|
| 3288 | page = G2frame.dataDisplay.GetSelection() |
---|
| 3289 | except: |
---|
| 3290 | return |
---|
| 3291 | if G2frame.dataDisplay.GetPageText(page) == 'Ramachandran restraints': |
---|
| 3292 | ramaGrid = G2frame.dataDisplay.GetPage(page).Ramas |
---|
| 3293 | ramaGrid.ClearSelection() |
---|
| 3294 | for row in range(ramaGrid.GetNumberRows()): |
---|
| 3295 | if names[ind] in ramaGrid.GetCellValue(row,0): |
---|
| 3296 | ramaGrid.SelectRow(row) |
---|
| 3297 | ramaGrid.ForceRefresh() |
---|
[1098] | 3298 | |
---|
[817] | 3299 | def OnMotion(event): |
---|
| 3300 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
| 3301 | xpos = event.xdata |
---|
| 3302 | ypos = event.ydata |
---|
| 3303 | msg = 'phi/psi: %5.3f %5.3f'%(xpos,ypos) |
---|
| 3304 | Page.canvas.SetToolTipString(msg) |
---|
[818] | 3305 | |
---|
[817] | 3306 | try: |
---|
| 3307 | plotNum = G2frame.G2plotNB.plotList.index('Ramachandran') |
---|
| 3308 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3309 | Page.figure.clf() |
---|
| 3310 | Plot = Page.figure.gca() |
---|
| 3311 | if not Page.IsShown(): |
---|
| 3312 | Page.Show() |
---|
| 3313 | except ValueError: |
---|
| 3314 | Plot = G2frame.G2plotNB.addMpl('Ramachandran').gca() |
---|
| 3315 | plotNum = G2frame.G2plotNB.plotList.index('Ramachandran') |
---|
| 3316 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[1098] | 3317 | Page.canvas.mpl_connect('pick_event', OnPick) |
---|
[817] | 3318 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 3319 | Page.canvas.mpl_connect('key_press_event', OnPlotKeyPress) |
---|
| 3320 | |
---|
| 3321 | Page.Choice = ['s: to change colors'] |
---|
| 3322 | Page.keyPress = OnPlotKeyPress |
---|
| 3323 | Page.SetFocus() |
---|
[1098] | 3324 | G2frame.G2plotNB.status.SetFields(['','Use mouse LB to identify phi/psi atoms']) |
---|
[817] | 3325 | acolor = mpl.cm.get_cmap(G2frame.RamaColor) |
---|
[818] | 3326 | if RamaName == 'All' or '-1' in RamaName: |
---|
| 3327 | if len(Coeff): |
---|
| 3328 | X,Y = np.meshgrid(np.linspace(-180.,180.,45),np.linspace(-180.,180.,45)) |
---|
| 3329 | Z = np.array([-G2mth.calcRamaEnergy(x,y,Coeff)[1] for x,y in zip(X.flatten(),Y.flatten())]) |
---|
| 3330 | Plot.contour(X,Y,np.reshape(Z,(45,45))) |
---|
| 3331 | Img = Plot.imshow(rama,aspect='equal',cmap=acolor,interpolation='nearest', |
---|
| 3332 | extent=[-180,180,-180,180],origin='lower') |
---|
| 3333 | if len(PhiPsi): |
---|
| 3334 | Phi,Psi = PhiPsi.T |
---|
| 3335 | Phi = np.where(Phi>180.,Phi-360.,Phi) |
---|
| 3336 | Psi = np.where(Psi>180.,Psi-360.,Psi) |
---|
[1098] | 3337 | Plot.plot(Phi,Psi,'ro',picker=5) |
---|
[818] | 3338 | Plot.set_xlim((-180.,180.)) |
---|
| 3339 | Plot.set_ylim((-180.,180.)) |
---|
| 3340 | else: |
---|
| 3341 | if len(Coeff): |
---|
| 3342 | X,Y = np.meshgrid(np.linspace(0.,360.,45),np.linspace(0.,360.,45)) |
---|
| 3343 | Z = np.array([-G2mth.calcRamaEnergy(x,y,Coeff)[1] for x,y in zip(X.flatten(),Y.flatten())]) |
---|
| 3344 | Plot.contour(X,Y,np.reshape(Z,(45,45))) |
---|
| 3345 | Img = Plot.imshow(rama,aspect='equal',cmap=acolor,interpolation='nearest', |
---|
| 3346 | extent=[0,360,0,360],origin='lower') |
---|
| 3347 | if len(PhiPsi): |
---|
| 3348 | Phi,Psi = PhiPsi.T |
---|
[1098] | 3349 | Plot.plot(Phi,Psi,'ro',picker=5) |
---|
[818] | 3350 | Plot.set_xlim((0.,360.)) |
---|
| 3351 | Plot.set_ylim((0.,360.)) |
---|
| 3352 | Plot.set_title('Ramachandran for '+RamaName+' in '+phaseName) |
---|
[817] | 3353 | Plot.set_xlabel(r'$\phi$',fontsize=16) |
---|
| 3354 | Plot.set_ylabel(r'$\psi$',fontsize=16) |
---|
[818] | 3355 | colorBar = Page.figure.colorbar(Img) |
---|
[817] | 3356 | Page.canvas.draw() |
---|
| 3357 | |
---|
| 3358 | |
---|
| 3359 | ################################################################################ |
---|
[762] | 3360 | ##### PlotSeq |
---|
| 3361 | ################################################################################ |
---|
[1312] | 3362 | def PlotSelectedSequence(G2frame,ColumnList,TableGet,SelectX,fitnum=None,fitvals=None): |
---|
[1282] | 3363 | '''Plot a result from a sequential refinement |
---|
[1284] | 3364 | |
---|
| 3365 | :param wx.Frame G2frame: The main GSAS-II tree "window" |
---|
| 3366 | :param list ColumnList: list of int values corresponding to columns |
---|
| 3367 | selected as y values |
---|
| 3368 | :param function TableGet: a function that takes a column number |
---|
| 3369 | as argument and returns the column label, the values and there ESDs (or None) |
---|
| 3370 | :param function SelectX: a function that returns a selected column |
---|
| 3371 | number (or None) as the X-axis selection |
---|
| 3372 | ''' |
---|
[1403] | 3373 | global Title,xLabel,yLabel |
---|
| 3374 | xLabel = yLabel = Title = '' |
---|
[1295] | 3375 | def OnMotion(event): |
---|
| 3376 | if event.xdata and event.ydata: #avoid out of frame errors |
---|
| 3377 | xpos = event.xdata |
---|
| 3378 | ypos = event.ydata |
---|
| 3379 | msg = '%5.3f %.6g'%(xpos,ypos) |
---|
| 3380 | Page.canvas.SetToolTipString(msg) |
---|
| 3381 | |
---|
[1284] | 3382 | def OnKeyPress(event): |
---|
[1403] | 3383 | global Title,xLabel,yLabel |
---|
[1284] | 3384 | if event.key == 's': |
---|
| 3385 | G2frame.seqXaxis = G2frame.seqXselect() |
---|
| 3386 | Draw() |
---|
[1403] | 3387 | elif event.key == 't': |
---|
[1831] | 3388 | dlg = G2G.MultiStringDialog(G2frame,'Set titles & labels',[' Title ',' x-Label ',' y-Label '], |
---|
[1403] | 3389 | [Title,xLabel,yLabel]) |
---|
| 3390 | if dlg.Show(): |
---|
| 3391 | Title,xLabel,yLabel = dlg.GetValues() |
---|
| 3392 | dlg.Destroy() |
---|
| 3393 | Draw() |
---|
[1806] | 3394 | elif event.key == 'l': |
---|
| 3395 | G2frame.seqLines = not G2frame.seqLines |
---|
| 3396 | wx.CallAfter(Draw) |
---|
[1334] | 3397 | |
---|
[1284] | 3398 | def Draw(): |
---|
[1403] | 3399 | global Title,xLabel,yLabel |
---|
[762] | 3400 | Page.SetFocus() |
---|
[1806] | 3401 | G2frame.G2plotNB.status.SetStatusText( \ |
---|
| 3402 | 'press L to toggle lines, S to select X axis, T to change titles (reselect column to show?)',1) |
---|
[1284] | 3403 | Plot.clear() |
---|
| 3404 | if G2frame.seqXaxis is not None: |
---|
[1312] | 3405 | xName,X,Xsig = Page.seqTableGet(G2frame.seqXaxis) |
---|
[1284] | 3406 | else: |
---|
| 3407 | X = np.arange(0,G2frame.SeqTable.GetNumberRows(),1) |
---|
[1282] | 3408 | xName = 'Data sequence number' |
---|
[1312] | 3409 | for col in Page.seqYaxisList: |
---|
| 3410 | name,Y,sig = Page.seqTableGet(col) |
---|
[1579] | 3411 | # deal with missing (None) values |
---|
| 3412 | Xnew = [] |
---|
| 3413 | Ynew = [] |
---|
| 3414 | Ysnew = [] |
---|
| 3415 | for i in range(len(X)): |
---|
| 3416 | if X[i] is None or Y[i] is None: continue |
---|
| 3417 | Xnew.append(X[i]) |
---|
| 3418 | Ynew.append(Y[i]) |
---|
[1619] | 3419 | if sig: Ysnew.append(sig[i]) |
---|
[1579] | 3420 | if Ysnew: |
---|
[1334] | 3421 | if G2frame.seqReverse and not G2frame.seqXaxis: |
---|
[1579] | 3422 | Ynew = Ynew[::-1] |
---|
| 3423 | Ysnew = Ysnew[::-1] |
---|
[1806] | 3424 | if G2frame.seqLines: |
---|
| 3425 | Plot.errorbar(Xnew,Ynew,yerr=Ysnew,label=name) |
---|
| 3426 | else: |
---|
| 3427 | Plot.errorbar(Xnew,Ynew,yerr=Ysnew,label=name,linestyle='None',marker='x') |
---|
[1284] | 3428 | else: |
---|
[1334] | 3429 | if G2frame.seqReverse and not G2frame.seqXaxis: |
---|
[1579] | 3430 | Ynew = Ynew[::-1] |
---|
| 3431 | Plot.plot(Xnew,Ynew) |
---|
| 3432 | Plot.plot(Xnew,Ynew,'o',label=name) |
---|
| 3433 | if Page.fitvals: # TODO: deal with fitting of None values |
---|
[1334] | 3434 | if G2frame.seqReverse and not G2frame.seqXaxis: |
---|
| 3435 | Page.fitvals = Page.fitvals[::-1] |
---|
| 3436 | Plot.plot(X,Page.fitvals,label='Fit') |
---|
[1312] | 3437 | |
---|
[1284] | 3438 | Plot.legend(loc='best') |
---|
[1403] | 3439 | if Title: |
---|
| 3440 | Plot.set_title(Title) |
---|
| 3441 | else: |
---|
| 3442 | Plot.set_title('') |
---|
| 3443 | if xLabel: |
---|
| 3444 | Plot.set_xlabel(xLabel) |
---|
| 3445 | else: |
---|
| 3446 | Plot.set_xlabel(xName) |
---|
| 3447 | if yLabel: |
---|
| 3448 | Plot.set_ylabel(yLabel) |
---|
| 3449 | else: |
---|
| 3450 | Plot.set_ylabel('Parameter values') |
---|
[1806] | 3451 | Page.canvas.draw() |
---|
[1396] | 3452 | |
---|
| 3453 | G2frame.seqXselect = SelectX |
---|
| 3454 | try: |
---|
| 3455 | G2frame.seqXaxis |
---|
| 3456 | except: |
---|
| 3457 | G2frame.seqXaxis = None |
---|
| 3458 | |
---|
| 3459 | if fitnum is None: |
---|
| 3460 | label = 'Sequential refinement' |
---|
| 3461 | else: |
---|
| 3462 | label = 'Parametric fit #'+str(fitnum+1) |
---|
| 3463 | try: |
---|
| 3464 | plotNum = G2frame.G2plotNB.plotList.index(label) |
---|
| 3465 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3466 | Page.figure.clf() |
---|
| 3467 | Plot = Page.figure.gca() |
---|
| 3468 | if not Page.IsShown(): |
---|
| 3469 | Page.Show() |
---|
| 3470 | except ValueError: |
---|
| 3471 | Plot = G2frame.G2plotNB.addMpl(label).gca() |
---|
| 3472 | plotNum = G2frame.G2plotNB.plotList.index(label) |
---|
| 3473 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3474 | Page.canvas.mpl_connect('key_press_event', OnKeyPress) |
---|
| 3475 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
[1806] | 3476 | Page.Choice = ['l - toggle lines','s - select x-axis','t - change titles',] |
---|
[1396] | 3477 | Page.keyPress = OnKeyPress |
---|
| 3478 | Page.seqYaxisList = ColumnList |
---|
| 3479 | Page.seqTableGet = TableGet |
---|
| 3480 | Page.fitvals = fitvals |
---|
| 3481 | |
---|
[1284] | 3482 | Draw() |
---|
[1396] | 3483 | G2frame.G2plotNB.nb.SetSelection(plotNum) # raises plot tab |
---|
[1284] | 3484 | |
---|
[762] | 3485 | ################################################################################ |
---|
| 3486 | ##### PlotExposedImage & PlotImage |
---|
| 3487 | ################################################################################ |
---|
| 3488 | |
---|
| 3489 | def PlotExposedImage(G2frame,newPlot=False,event=None): |
---|
| 3490 | '''General access module for 2D image plotting |
---|
| 3491 | ''' |
---|
| 3492 | plotNo = G2frame.G2plotNB.nb.GetSelection() |
---|
| 3493 | if G2frame.G2plotNB.nb.GetPageText(plotNo) == '2D Powder Image': |
---|
| 3494 | PlotImage(G2frame,newPlot,event,newImage=True) |
---|
| 3495 | elif G2frame.G2plotNB.nb.GetPageText(plotNo) == '2D Integration': |
---|
| 3496 | PlotIntegration(G2frame,newPlot,event) |
---|
| 3497 | |
---|
[1128] | 3498 | def OnStartMask(G2frame): |
---|
[1124] | 3499 | '''Initiate the start of a Frame or Polygon map |
---|
| 3500 | |
---|
| 3501 | :param wx.Frame G2frame: The main GSAS-II tree "window" |
---|
| 3502 | :param str eventkey: a single letter ('f' or 'p') that |
---|
| 3503 | determines what type of mask is created. |
---|
| 3504 | ''' |
---|
| 3505 | Masks = G2frame.PatternTree.GetItemPyData( |
---|
| 3506 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks')) |
---|
[1128] | 3507 | if G2frame.MaskKey == 'f': |
---|
[1124] | 3508 | Masks['Frames'] = [] |
---|
[1128] | 3509 | elif G2frame.MaskKey == 'p': |
---|
[1124] | 3510 | Masks['Polygons'].append([]) |
---|
[1128] | 3511 | elif G2frame.MaskKey == 's': |
---|
| 3512 | Masks['Points'].append([]) |
---|
| 3513 | elif G2frame.MaskKey == 'a': |
---|
| 3514 | Masks['Arcs'].append([]) |
---|
| 3515 | elif G2frame.MaskKey == 'r': |
---|
| 3516 | Masks['Rings'].append([]) |
---|
[1124] | 3517 | G2imG.UpdateMasks(G2frame,Masks) |
---|
| 3518 | PlotImage(G2frame,newImage=True) |
---|
[1188] | 3519 | |
---|
| 3520 | def OnStartNewDzero(G2frame): |
---|
| 3521 | '''Initiate the start of adding a new d-zero to a strain data set |
---|
[1124] | 3522 | |
---|
[1188] | 3523 | :param wx.Frame G2frame: The main GSAS-II tree "window" |
---|
| 3524 | :param str eventkey: a single letter ('a') that |
---|
| 3525 | triggers the addition of a d-zero. |
---|
| 3526 | ''' |
---|
[1350] | 3527 | G2frame.dataFrame.GetStatusBar().SetStatusText('Add strain ring active - LB pick d-zero value',0) |
---|
[1386] | 3528 | G2frame.PickId = G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Stress/Strain') |
---|
| 3529 | data = G2frame.PatternTree.GetItemPyData(G2frame.PickId) |
---|
| 3530 | return data |
---|
[1188] | 3531 | |
---|
[762] | 3532 | def PlotImage(G2frame,newPlot=False,event=None,newImage=True): |
---|
| 3533 | '''Plot of 2D detector images as contoured plot. Also plot calibration ellipses, |
---|
| 3534 | masks, etc. |
---|
| 3535 | ''' |
---|
| 3536 | from matplotlib.patches import Ellipse,Arc,Circle,Polygon |
---|
| 3537 | import numpy.ma as ma |
---|
[1151] | 3538 | Dsp = lambda tth,wave: wave/(2.*npsind(tth/2.)) |
---|
[1386] | 3539 | global Data,Masks,StrSta |
---|
[762] | 3540 | colors=['b','g','r','c','m','k'] |
---|
| 3541 | Data = G2frame.PatternTree.GetItemPyData( |
---|
| 3542 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls')) |
---|
[1134] | 3543 | # patch |
---|
| 3544 | if 'invert_x' not in Data: |
---|
| 3545 | Data['invert_x'] = False |
---|
| 3546 | Data['invert_y'] = True |
---|
| 3547 | # end patch |
---|
[762] | 3548 | Masks = G2frame.PatternTree.GetItemPyData( |
---|
| 3549 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Masks')) |
---|
| 3550 | try: #may be absent |
---|
| 3551 | StrSta = G2frame.PatternTree.GetItemPyData( |
---|
| 3552 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Stress/Strain')) |
---|
| 3553 | except TypeError: #is missing |
---|
| 3554 | StrSta = {} |
---|
| 3555 | |
---|
| 3556 | def OnImMotion(event): |
---|
| 3557 | Page.canvas.SetToolTipString('') |
---|
| 3558 | sizexy = Data['size'] |
---|
[1763] | 3559 | FlatBkg = Data.get('Flat Bkg',0.) |
---|
[762] | 3560 | if event.xdata and event.ydata and len(G2frame.ImageZ): #avoid out of frame errors |
---|
[1231] | 3561 | Page.canvas.SetToolTipString('%8.2f %8.2fmm'%(event.xdata,event.ydata)) |
---|
[762] | 3562 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 3563 | item = G2frame.itemPicked |
---|
| 3564 | pixelSize = Data['pixelSize'] |
---|
| 3565 | scalex = 1000./pixelSize[0] |
---|
| 3566 | scaley = 1000./pixelSize[1] |
---|
| 3567 | if item and G2frame.PatternTree.GetItemText(G2frame.PickId) == 'Image Controls': |
---|
| 3568 | if 'Text' in str(item): |
---|
| 3569 | Page.canvas.SetToolTipString('%8.3f %8.3fmm'%(event.xdata,event.ydata)) |
---|
| 3570 | else: |
---|
| 3571 | xcent,ycent = Data['center'] |
---|
| 3572 | xpos = event.xdata-xcent |
---|
| 3573 | ypos = event.ydata-ycent |
---|
| 3574 | tth,azm = G2img.GetTthAzm(event.xdata,event.ydata,Data) |
---|
| 3575 | if 'line3' in str(item) or 'line4' in str(item) and not Data['fullIntegrate']: |
---|
| 3576 | Page.canvas.SetToolTipString('%6d deg'%(azm)) |
---|
| 3577 | elif 'line1' in str(item) or 'line2' in str(item): |
---|
[1231] | 3578 | Page.canvas.SetToolTipString('%8.3f deg'%(tth)) |
---|
[762] | 3579 | else: |
---|
| 3580 | xpos = event.xdata |
---|
| 3581 | ypos = event.ydata |
---|
| 3582 | xpix = xpos*scalex |
---|
| 3583 | ypix = ypos*scaley |
---|
| 3584 | Int = 0 |
---|
| 3585 | if (0 <= xpix <= sizexy[0]) and (0 <= ypix <= sizexy[1]): |
---|
[1763] | 3586 | Int = G2frame.ImageZ[ypix][xpix]-int(FlatBkg) |
---|
[1153] | 3587 | tth,azm,D,dsp = G2img.GetTthAzmDsp(xpos,ypos,Data) |
---|
[762] | 3588 | Q = 2.*math.pi/dsp |
---|
[1188] | 3589 | fields = ['','Detector 2-th =%9.3fdeg, dsp =%9.3fA, Q = %6.5fA-1, azm = %7.2fdeg, I = %6d'%(tth,dsp,Q,azm,Int)] |
---|
[1128] | 3590 | if G2frame.MaskKey in ['p','f']: |
---|
[1188] | 3591 | fields[1] = 'Polygon/frame mask pick - LB next point, RB close polygon' |
---|
| 3592 | elif G2frame.StrainKey: |
---|
| 3593 | fields[0] = 'd-zero pick active' |
---|
| 3594 | G2frame.G2plotNB.status.SetFields(fields) |
---|
[762] | 3595 | |
---|
| 3596 | def OnImPlotKeyPress(event): |
---|
| 3597 | try: |
---|
| 3598 | PickName = G2frame.PatternTree.GetItemText(G2frame.PickId) |
---|
| 3599 | except TypeError: |
---|
| 3600 | return |
---|
| 3601 | if PickName == 'Masks': |
---|
[1212] | 3602 | if event.key in ['l','p','f','s','a','r']: |
---|
[1128] | 3603 | G2frame.MaskKey = event.key |
---|
| 3604 | OnStartMask(G2frame) |
---|
[1232] | 3605 | PlotImage(G2frame,newPlot=False) |
---|
[1128] | 3606 | |
---|
[1188] | 3607 | elif PickName == 'Stress/Strain': |
---|
| 3608 | if event.key in ['a',]: |
---|
| 3609 | G2frame.StrainKey = event.key |
---|
[1386] | 3610 | StrSta = OnStartNewDzero(G2frame) |
---|
[1232] | 3611 | PlotImage(G2frame,newPlot=False) |
---|
[1188] | 3612 | |
---|
[762] | 3613 | elif PickName == 'Image Controls': |
---|
[1134] | 3614 | if event.key in ['c',]: |
---|
[762] | 3615 | Xpos = event.xdata |
---|
| 3616 | if not Xpos: #got point out of frame |
---|
| 3617 | return |
---|
| 3618 | Ypos = event.ydata |
---|
| 3619 | dlg = wx.MessageDialog(G2frame,'Are you sure you want to change the center?', |
---|
| 3620 | 'Center change',style=wx.OK|wx.CANCEL) |
---|
| 3621 | try: |
---|
| 3622 | if dlg.ShowModal() == wx.ID_OK: |
---|
| 3623 | print 'move center to: ',Xpos,Ypos |
---|
| 3624 | Data['center'] = [Xpos,Ypos] |
---|
| 3625 | G2imG.UpdateImageControls(G2frame,Data,Masks) |
---|
[1232] | 3626 | PlotImage(G2frame,newPlot=False) |
---|
[762] | 3627 | finally: |
---|
| 3628 | dlg.Destroy() |
---|
[1232] | 3629 | return |
---|
[762] | 3630 | elif event.key == 'l': |
---|
[1205] | 3631 | G2frame.logPlot = not G2frame.logPlot |
---|
[1134] | 3632 | elif event.key in ['x',]: |
---|
[1205] | 3633 | Data['invert_x'] = not Data['invert_x'] |
---|
[1134] | 3634 | elif event.key in ['y',]: |
---|
[1205] | 3635 | Data['invert_y'] = not Data['invert_y'] |
---|
[1232] | 3636 | PlotImage(G2frame,newPlot=True) |
---|
[762] | 3637 | |
---|
| 3638 | def OnKeyBox(event): |
---|
| 3639 | if G2frame.G2plotNB.nb.GetSelection() == G2frame.G2plotNB.plotList.index('2D Powder Image'): |
---|
| 3640 | event.key = cb.GetValue()[0] |
---|
| 3641 | cb.SetValue(' key press') |
---|
[1134] | 3642 | if event.key in ['l','s','a','r','p','x','y']: |
---|
[762] | 3643 | wx.CallAfter(OnImPlotKeyPress,event) |
---|
[1005] | 3644 | Page.canvas.SetFocus() # redirect the Focus from the button back to the plot |
---|
[762] | 3645 | |
---|
| 3646 | def OnImPick(event): |
---|
| 3647 | if G2frame.PatternTree.GetItemText(G2frame.PickId) not in ['Image Controls','Masks']: |
---|
| 3648 | return |
---|
[1128] | 3649 | if G2frame.itemPicked is not None: return |
---|
| 3650 | G2frame.itemPicked = event.artist |
---|
| 3651 | G2frame.mousePicked = event.mouseevent |
---|
[762] | 3652 | |
---|
| 3653 | def OnImRelease(event): |
---|
| 3654 | try: |
---|
| 3655 | PickName = G2frame.PatternTree.GetItemText(G2frame.PickId) |
---|
| 3656 | except TypeError: |
---|
| 3657 | return |
---|
[1185] | 3658 | if PickName not in ['Image Controls','Masks','Stress/Strain']: |
---|
[762] | 3659 | return |
---|
| 3660 | pixelSize = Data['pixelSize'] |
---|
[1763] | 3661 | FlatBkg = Data.get('Flat Bkg',0.) |
---|
[762] | 3662 | scalex = 1000./pixelSize[0] |
---|
| 3663 | scaley = 1000./pixelSize[1] |
---|
[1377] | 3664 | # pixLimit = Data['pixLimit'] #can be too tight |
---|
| 3665 | pixLimit = 20 #this makes the search box 40x40 pixels |
---|
[762] | 3666 | if G2frame.itemPicked is None and PickName == 'Image Controls' and len(G2frame.ImageZ): |
---|
| 3667 | Xpos = event.xdata |
---|
| 3668 | if not (Xpos and G2frame.ifGetRing): #got point out of frame |
---|
| 3669 | return |
---|
| 3670 | Ypos = event.ydata |
---|
| 3671 | if Ypos and not Page.toolbar._active: #make sure zoom/pan not selected |
---|
| 3672 | if event.button == 1: |
---|
| 3673 | Xpix = Xpos*scalex |
---|
| 3674 | Ypix = Ypos*scaley |
---|
[1763] | 3675 | xpos,ypos,I,J = G2img.ImageLocalMax(G2frame.ImageZ-FlatBkg,pixLimit,Xpix,Ypix) |
---|
[762] | 3676 | if I and J: |
---|
| 3677 | xpos += .5 #shift to pixel center |
---|
| 3678 | ypos += .5 |
---|
| 3679 | xpos /= scalex #convert to mm |
---|
| 3680 | ypos /= scaley |
---|
| 3681 | Data['ring'].append([xpos,ypos]) |
---|
| 3682 | elif event.button == 3: |
---|
[1319] | 3683 | G2frame.dataFrame.GetStatusBar().SetStatusText('Calibrating...',0) |
---|
[762] | 3684 | if G2img.ImageCalibrate(G2frame,Data): |
---|
[1319] | 3685 | G2frame.dataFrame.GetStatusBar().SetStatusText('Calibration successful - Show ring picks to check',0) |
---|
[762] | 3686 | print 'Calibration successful' |
---|
| 3687 | else: |
---|
[1319] | 3688 | G2frame.dataFrame.GetStatusBar().SetStatusText('Calibration failed - Show ring picks to diagnose',0) |
---|
[762] | 3689 | print 'Calibration failed' |
---|
| 3690 | G2frame.ifGetRing = False |
---|
| 3691 | G2imG.UpdateImageControls(G2frame,Data,Masks) |
---|
| 3692 | return |
---|
| 3693 | PlotImage(G2frame,newImage=False) |
---|
| 3694 | return |
---|
[1128] | 3695 | elif G2frame.MaskKey and PickName == 'Masks': |
---|
| 3696 | Xpos,Ypos = [event.xdata,event.ydata] |
---|
| 3697 | if not Xpos or not Ypos or Page.toolbar._active: #got point out of frame or zoom/pan selected |
---|
| 3698 | return |
---|
| 3699 | if G2frame.MaskKey == 's' and event.button == 1: |
---|
| 3700 | Masks['Points'][-1] = [Xpos,Ypos,1.] |
---|
| 3701 | G2frame.MaskKey = '' |
---|
| 3702 | elif G2frame.MaskKey == 'r' and event.button == 1: |
---|
| 3703 | tth = G2img.GetTth(Xpos,Ypos,Data) |
---|
| 3704 | Masks['Rings'][-1] = [tth,0.1] |
---|
| 3705 | G2frame.MaskKey = '' |
---|
| 3706 | elif G2frame.MaskKey == 'a' and event.button == 1: |
---|
| 3707 | tth,azm = G2img.GetTthAzm(Xpos,Ypos,Data) |
---|
| 3708 | azm = int(azm) |
---|
| 3709 | Masks['Arcs'][-1] = [tth,[azm-5,azm+5],0.1] |
---|
| 3710 | G2frame.MaskKey = '' |
---|
| 3711 | elif G2frame.MaskKey =='p': |
---|
| 3712 | polygon = Masks['Polygons'][-1] |
---|
[1131] | 3713 | if len(polygon) > 2 and event.button == 3: |
---|
[1128] | 3714 | x0,y0 = polygon[0] |
---|
| 3715 | polygon.append([x0,y0]) |
---|
| 3716 | G2frame.MaskKey = '' |
---|
[1268] | 3717 | G2frame.G2plotNB.status.SetFields(['','Polygon closed']) |
---|
[1128] | 3718 | else: |
---|
| 3719 | G2frame.G2plotNB.status.SetFields(['','New polygon point: %.1f,%.1f'%(Xpos,Ypos)]) |
---|
| 3720 | polygon.append([Xpos,Ypos]) |
---|
| 3721 | elif G2frame.MaskKey =='f': |
---|
| 3722 | frame = Masks['Frames'] |
---|
[1131] | 3723 | if len(frame) > 2 and event.button == 3: |
---|
[1128] | 3724 | x0,y0 = frame[0] |
---|
| 3725 | frame.append([x0,y0]) |
---|
| 3726 | G2frame.MaskKey = '' |
---|
[1268] | 3727 | G2frame.G2plotNB.status.SetFields(['','Frame closed']) |
---|
[1128] | 3728 | else: |
---|
| 3729 | G2frame.G2plotNB.status.SetFields(['','New frame point: %.1f,%.1f'%(Xpos,Ypos)]) |
---|
| 3730 | frame.append([Xpos,Ypos]) |
---|
| 3731 | G2imG.UpdateMasks(G2frame,Masks) |
---|
| 3732 | PlotImage(G2frame,newImage=False) |
---|
[1188] | 3733 | elif PickName == 'Stress/Strain' and G2frame.StrainKey: |
---|
[1185] | 3734 | Xpos,Ypos = [event.xdata,event.ydata] |
---|
| 3735 | if not Xpos or not Ypos or Page.toolbar._active: #got point out of frame or zoom/pan selected |
---|
| 3736 | return |
---|
| 3737 | dsp = G2img.GetDsp(Xpos,Ypos,Data) |
---|
[1761] | 3738 | StrSta['d-zero'].append({'Dset':dsp,'Dcalc':0.0,'pixLimit':10,'cutoff':0.5, |
---|
[1185] | 3739 | 'ImxyObs':[[],[]],'ImtaObs':[[],[]],'ImtaCalc':[[],[]],'Emat':[1.0,1.0,1.0]}) |
---|
[1763] | 3740 | R,r = G2img.MakeStrStaRing(StrSta['d-zero'][-1],G2frame.ImageZ-FlatBkg,Data) |
---|
[1185] | 3741 | if not len(R): |
---|
| 3742 | del StrSta['d-zero'][-1] |
---|
| 3743 | G2frame.ErrorDialog('Strain peak selection','WARNING - No points found for this ring selection') |
---|
[1188] | 3744 | StrSta['d-zero'] = G2mth.sortArray(StrSta['d-zero'],'Dset',reverse=True) |
---|
| 3745 | G2frame.StrainKey = '' |
---|
[1185] | 3746 | G2imG.UpdateStressStrain(G2frame,StrSta) |
---|
| 3747 | PlotStrain(G2frame,StrSta) |
---|
| 3748 | PlotImage(G2frame,newPlot=False) |
---|
[762] | 3749 | else: |
---|
[1128] | 3750 | Xpos,Ypos = [event.xdata,event.ydata] |
---|
| 3751 | if not Xpos or not Ypos or Page.toolbar._active: #got point out of frame or zoom/pan selected |
---|
| 3752 | return |
---|
| 3753 | if G2frame.ifGetRing: #delete a calibration ring pick |
---|
| 3754 | xypos = [Xpos,Ypos] |
---|
| 3755 | rings = Data['ring'] |
---|
| 3756 | for ring in rings: |
---|
| 3757 | if np.allclose(ring,xypos,.01,0): |
---|
| 3758 | rings.remove(ring) |
---|
| 3759 | else: |
---|
[1153] | 3760 | tth,azm,dsp = G2img.GetTthAzmDsp(Xpos,Ypos,Data)[:3] |
---|
[1128] | 3761 | itemPicked = str(G2frame.itemPicked) |
---|
| 3762 | if 'Line2D' in itemPicked and PickName == 'Image Controls': |
---|
| 3763 | if 'line1' in itemPicked: |
---|
| 3764 | Data['IOtth'][0] = max(tth,0.001) |
---|
| 3765 | elif 'line2' in itemPicked: |
---|
| 3766 | Data['IOtth'][1] = tth |
---|
| 3767 | elif 'line3' in itemPicked: |
---|
| 3768 | Data['LRazimuth'][0] = int(azm) |
---|
| 3769 | elif 'line4' in itemPicked and not Data['fullIntegrate']: |
---|
| 3770 | Data['LRazimuth'][1] = int(azm) |
---|
[1163] | 3771 | |
---|
| 3772 | Data['LRazimuth'][0] %= 360 |
---|
| 3773 | Data['LRazimuth'][1] %= 360 |
---|
[1128] | 3774 | if Data['LRazimuth'][0] > Data['LRazimuth'][1]: |
---|
[1163] | 3775 | Data['LRazimuth'][1] += 360 |
---|
| 3776 | if Data['fullIntegrate']: |
---|
| 3777 | Data['LRazimuth'][1] = Data['LRazimuth'][0]+360 |
---|
[1128] | 3778 | |
---|
| 3779 | if Data['IOtth'][0] > Data['IOtth'][1]: |
---|
| 3780 | Data['IOtth'][0],Data['IOtth'][1] = Data['IOtth'][1],Data['IOtth'][0] |
---|
| 3781 | |
---|
| 3782 | G2frame.InnerTth.SetValue("%8.2f" % (Data['IOtth'][0])) |
---|
| 3783 | G2frame.OuterTth.SetValue("%8.2f" % (Data['IOtth'][1])) |
---|
| 3784 | G2frame.Lazim.SetValue("%6d" % (Data['LRazimuth'][0])) |
---|
| 3785 | G2frame.Razim.SetValue("%6d" % (Data['LRazimuth'][1])) |
---|
| 3786 | elif 'Circle' in itemPicked and PickName == 'Masks': |
---|
| 3787 | spots = Masks['Points'] |
---|
| 3788 | newPos = itemPicked.split(')')[0].split('(')[2].split(',') |
---|
| 3789 | newPos = np.array([float(newPos[0]),float(newPos[1])]) |
---|
| 3790 | for spot in spots: |
---|
[1579] | 3791 | if spot and np.allclose(np.array([spot[:2]]),newPos): |
---|
[1128] | 3792 | spot[:2] = Xpos,Ypos |
---|
| 3793 | G2imG.UpdateMasks(G2frame,Masks) |
---|
| 3794 | elif 'Line2D' in itemPicked and PickName == 'Masks': |
---|
| 3795 | Obj = G2frame.itemPicked.findobj() |
---|
| 3796 | rings = Masks['Rings'] |
---|
| 3797 | arcs = Masks['Arcs'] |
---|
| 3798 | polygons = Masks['Polygons'] |
---|
| 3799 | frame = Masks['Frames'] |
---|
| 3800 | for ring in G2frame.ringList: |
---|
| 3801 | if Obj == ring[0]: |
---|
| 3802 | rN = ring[1] |
---|
| 3803 | if ring[2] == 'o': |
---|
| 3804 | rings[rN][0] = G2img.GetTth(Xpos,Ypos,Data)-rings[rN][1]/2. |
---|
| 3805 | else: |
---|
| 3806 | rings[rN][0] = G2img.GetTth(Xpos,Ypos,Data)+rings[rN][1]/2. |
---|
| 3807 | for arc in G2frame.arcList: |
---|
| 3808 | if Obj == arc[0]: |
---|
| 3809 | aN = arc[1] |
---|
| 3810 | if arc[2] == 'o': |
---|
| 3811 | arcs[aN][0] = G2img.GetTth(Xpos,Ypos,Data)-arcs[aN][2]/2 |
---|
| 3812 | elif arc[2] == 'i': |
---|
| 3813 | arcs[aN][0] = G2img.GetTth(Xpos,Ypos,Data)+arcs[aN][2]/2 |
---|
| 3814 | elif arc[2] == 'l': |
---|
| 3815 | arcs[aN][1][0] = int(G2img.GetAzm(Xpos,Ypos,Data)) |
---|
| 3816 | else: |
---|
| 3817 | arcs[aN][1][1] = int(G2img.GetAzm(Xpos,Ypos,Data)) |
---|
[1266] | 3818 | for poly in G2frame.polyList: #merging points problem here? |
---|
[1128] | 3819 | if Obj == poly[0]: |
---|
| 3820 | ind = G2frame.itemPicked.contains(G2frame.mousePicked)[1]['ind'][0] |
---|
[1121] | 3821 | oldPos = np.array([G2frame.mousePicked.xdata,G2frame.mousePicked.ydata]) |
---|
[1128] | 3822 | pN = poly[1] |
---|
| 3823 | for i,xy in enumerate(polygons[pN]): |
---|
[1121] | 3824 | if np.allclose(np.array([xy]),oldPos,atol=1.0): |
---|
[1266] | 3825 | if event.button == 1: |
---|
| 3826 | polygons[pN][i] = Xpos,Ypos |
---|
| 3827 | elif event.button == 3: |
---|
| 3828 | polygons[pN].insert(i,[Xpos,Ypos]) |
---|
| 3829 | break |
---|
[1128] | 3830 | if frame: |
---|
| 3831 | oldPos = np.array([G2frame.mousePicked.xdata,G2frame.mousePicked.ydata]) |
---|
| 3832 | for i,xy in enumerate(frame): |
---|
| 3833 | if np.allclose(np.array([xy]),oldPos,atol=1.0): |
---|
[1266] | 3834 | if event.button == 1: |
---|
| 3835 | frame[i] = Xpos,Ypos |
---|
| 3836 | elif event.button == 3: |
---|
| 3837 | frame.insert(i,[Xpos,Ypos]) |
---|
| 3838 | break |
---|
[1128] | 3839 | G2imG.UpdateMasks(G2frame,Masks) |
---|
| 3840 | # else: #keep for future debugging |
---|
| 3841 | # print str(G2frame.itemPicked),event.xdata,event.ydata,event.button |
---|
| 3842 | PlotImage(G2frame,newImage=True) |
---|
[762] | 3843 | G2frame.itemPicked = None |
---|
| 3844 | |
---|
| 3845 | try: |
---|
| 3846 | plotNum = G2frame.G2plotNB.plotList.index('2D Powder Image') |
---|
| 3847 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3848 | if not newPlot: |
---|
| 3849 | Plot = Page.figure.gca() #get previous powder plot & get limits |
---|
| 3850 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
| 3851 | if newImage: |
---|
| 3852 | Page.figure.clf() |
---|
| 3853 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
| 3854 | except ValueError: |
---|
| 3855 | Plot = G2frame.G2plotNB.addMpl('2D Powder Image').gca() |
---|
| 3856 | plotNum = G2frame.G2plotNB.plotList.index('2D Powder Image') |
---|
| 3857 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 3858 | Page.canvas.mpl_connect('key_press_event', OnImPlotKeyPress) |
---|
| 3859 | Page.canvas.mpl_connect('motion_notify_event', OnImMotion) |
---|
| 3860 | Page.canvas.mpl_connect('pick_event', OnImPick) |
---|
| 3861 | Page.canvas.mpl_connect('button_release_event', OnImRelease) |
---|
| 3862 | xylim = [] |
---|
[796] | 3863 | Page.Choice = None |
---|
[762] | 3864 | if not event: #event from GUI TextCtrl - don't want focus to change to plot!!! |
---|
| 3865 | Page.SetFocus() |
---|
| 3866 | Title = G2frame.PatternTree.GetItemText(G2frame.Image)[4:] |
---|
| 3867 | G2frame.G2plotNB.status.DestroyChildren() |
---|
| 3868 | if G2frame.logPlot: |
---|
| 3869 | Title = 'log('+Title+')' |
---|
| 3870 | Plot.set_title(Title) |
---|
| 3871 | try: |
---|
| 3872 | if G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Image Controls',]: |
---|
[1134] | 3873 | Page.Choice = (' key press','l: log(I) on','x: flip x','y: flip y',) |
---|
[762] | 3874 | if G2frame.logPlot: |
---|
[796] | 3875 | Page.Choice[1] = 'l: log(I) off' |
---|
| 3876 | Page.keyPress = OnImPlotKeyPress |
---|
[1128] | 3877 | elif G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Masks',]: |
---|
[1212] | 3878 | Page.Choice = (' key press','l: log(I) on','s: spot mask','a: arc mask','r: ring mask', |
---|
[1128] | 3879 | 'p: polygon mask','f: frame mask',) |
---|
[1212] | 3880 | if G2frame.logPlot: |
---|
| 3881 | Page.Choice[1] = 'l: log(I) off' |
---|
[1128] | 3882 | Page.keyPress = OnImPlotKeyPress |
---|
[1188] | 3883 | elif G2frame.PatternTree.GetItemText(G2frame.PickId) in ['Stress/Strain',]: |
---|
| 3884 | Page.Choice = (' key press','a: add new ring',) |
---|
| 3885 | Page.keyPress = OnImPlotKeyPress |
---|
[762] | 3886 | except TypeError: |
---|
| 3887 | pass |
---|
| 3888 | size,imagefile = G2frame.PatternTree.GetItemPyData(G2frame.Image) |
---|
[1418] | 3889 | dark = Data.get('dark image',[0,'']) |
---|
[1399] | 3890 | if dark[0]: |
---|
| 3891 | darkfile = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, |
---|
| 3892 | G2frame.root,dark[0]))[1] |
---|
[762] | 3893 | if imagefile != G2frame.oldImagefile: |
---|
| 3894 | imagefile = G2IO.CheckImageFile(G2frame,imagefile) |
---|
| 3895 | if not imagefile: |
---|
| 3896 | G2frame.G2plotNB.Delete('2D Powder Image') |
---|
| 3897 | return |
---|
| 3898 | G2frame.PatternTree.SetItemPyData(G2frame.Image,[size,imagefile]) |
---|
| 3899 | G2frame.ImageZ = G2IO.GetImageData(G2frame,imagefile,imageOnly=True) |
---|
[1399] | 3900 | if dark[0]: |
---|
| 3901 | darkImg = G2IO.GetImageData(G2frame,darkfile,imageOnly=True) |
---|
| 3902 | G2frame.ImageZ += dark[1]*darkImg |
---|
[762] | 3903 | G2frame.oldImagefile = imagefile |
---|
| 3904 | |
---|
| 3905 | imScale = 1 |
---|
| 3906 | if len(G2frame.ImageZ) > 1024: |
---|
| 3907 | imScale = len(G2frame.ImageZ)/1024 |
---|
| 3908 | sizexy = Data['size'] |
---|
| 3909 | pixelSize = Data['pixelSize'] |
---|
| 3910 | scalex = 1000./pixelSize[0] |
---|
| 3911 | scaley = 1000./pixelSize[1] |
---|
| 3912 | Xmax = sizexy[0]*pixelSize[0]/1000. |
---|
| 3913 | Ymax = sizexy[1]*pixelSize[1]/1000. |
---|
| 3914 | xlim = (0,Xmax) |
---|
| 3915 | ylim = (Ymax,0) |
---|
| 3916 | Imin,Imax = Data['range'][1] |
---|
| 3917 | acolor = mpl.cm.get_cmap(Data['color']) |
---|
| 3918 | xcent,ycent = Data['center'] |
---|
| 3919 | Plot.set_xlabel('Image x-axis, mm',fontsize=12) |
---|
| 3920 | Plot.set_ylabel('Image y-axis, mm',fontsize=12) |
---|
| 3921 | #do threshold mask - "real" mask - others are just bondaries |
---|
| 3922 | Zlim = Masks['Thresholds'][1] |
---|
[1763] | 3923 | FlatBkg = Data.get('Flat Bkg',0.0) |
---|
[762] | 3924 | wx.BeginBusyCursor() |
---|
| 3925 | try: |
---|
| 3926 | |
---|
| 3927 | if newImage: |
---|
[1212] | 3928 | Imin,Imax = Data['range'][1] |
---|
[1764] | 3929 | MA = ma.masked_greater(ma.masked_less(G2frame.ImageZ,Zlim[0]+FlatBkg),Zlim[1]+FlatBkg) |
---|
[762] | 3930 | MaskA = ma.getmaskarray(MA) |
---|
[1763] | 3931 | A = G2img.ImageCompress(MA,imScale)-FlatBkg |
---|
[762] | 3932 | AM = G2img.ImageCompress(MaskA,imScale) |
---|
| 3933 | if G2frame.logPlot: |
---|
[1212] | 3934 | A = np.where(A>Imin,np.where(A<Imax,A,0),0) |
---|
[762] | 3935 | A = np.where(A>0,np.log(A),0) |
---|
| 3936 | AM = np.where(AM>0,np.log(AM),0) |
---|
| 3937 | Imin,Imax = [np.amin(A),np.amax(A)] |
---|
| 3938 | ImgM = Plot.imshow(AM,aspect='equal',cmap='Reds', |
---|
| 3939 | interpolation='nearest',vmin=0,vmax=2,extent=[0,Xmax,Ymax,0]) |
---|
| 3940 | Img = Plot.imshow(A,aspect='equal',cmap=acolor, |
---|
| 3941 | interpolation='nearest',vmin=Imin,vmax=Imax,extent=[0,Xmax,Ymax,0]) |
---|
| 3942 | |
---|
| 3943 | Plot.plot(xcent,ycent,'x') |
---|
| 3944 | #G2frame.PatternTree.GetItemText(item) |
---|
| 3945 | if Data['showLines']: |
---|
| 3946 | LRAzim = Data['LRazimuth'] #NB: integers |
---|
| 3947 | Nazm = Data['outAzimuths'] |
---|
| 3948 | delAzm = float(LRAzim[1]-LRAzim[0])/Nazm |
---|
| 3949 | AzmthOff = Data['azmthOff'] |
---|
| 3950 | IOtth = Data['IOtth'] |
---|
| 3951 | wave = Data['wavelength'] |
---|
| 3952 | dspI = wave/(2.0*sind(IOtth[0]/2.0)) |
---|
| 3953 | ellI = G2img.GetEllipse(dspI,Data) #=False if dsp didn't yield an ellipse (ugh! a parabola or a hyperbola) |
---|
| 3954 | dspO = wave/(2.0*sind(IOtth[1]/2.0)) |
---|
| 3955 | ellO = G2img.GetEllipse(dspO,Data) #Ditto & more likely for outer ellipse |
---|
| 3956 | Azm = np.array(range(LRAzim[0],LRAzim[1]+1))-AzmthOff |
---|
| 3957 | if ellI: |
---|
| 3958 | xyI = [] |
---|
| 3959 | for azm in Azm: |
---|
[1163] | 3960 | xy = G2img.GetDetectorXY(dspI,azm,Data) |
---|
| 3961 | if np.any(xy): |
---|
| 3962 | xyI.append(xy) |
---|
| 3963 | if len(xyI): |
---|
| 3964 | xyI = np.array(xyI) |
---|
| 3965 | arcxI,arcyI = xyI.T |
---|
| 3966 | Plot.plot(arcxI,arcyI,picker=3) |
---|
[762] | 3967 | if ellO: |
---|
| 3968 | xyO = [] |
---|
| 3969 | for azm in Azm: |
---|
[1163] | 3970 | xy = G2img.GetDetectorXY(dspO,azm,Data) |
---|
| 3971 | if np.any(xy): |
---|
| 3972 | xyO.append(xy) |
---|
| 3973 | if len(xyO): |
---|
| 3974 | xyO = np.array(xyO) |
---|
| 3975 | arcxO,arcyO = xyO.T |
---|
| 3976 | Plot.plot(arcxO,arcyO,picker=3) |
---|
[762] | 3977 | if ellO and ellI: |
---|
| 3978 | Plot.plot([arcxI[0],arcxO[0]],[arcyI[0],arcyO[0]],picker=3) |
---|
| 3979 | Plot.plot([arcxI[-1],arcxO[-1]],[arcyI[-1],arcyO[-1]],picker=3) |
---|
| 3980 | for i in range(Nazm): |
---|
| 3981 | cake = LRAzim[0]+i*delAzm-AzmthOff |
---|
| 3982 | if Data['centerAzm']: |
---|
| 3983 | cake += delAzm/2. |
---|
| 3984 | ind = np.searchsorted(Azm,cake) |
---|
| 3985 | Plot.plot([arcxI[ind],arcxO[ind]],[arcyI[ind],arcyO[ind]],color='k',dashes=(5,5)) |
---|
| 3986 | |
---|
| 3987 | if G2frame.PatternTree.GetItemText(G2frame.PickId) in 'Image Controls': |
---|
| 3988 | for xring,yring in Data['ring']: |
---|
| 3989 | Plot.plot(xring,yring,'r+',picker=3) |
---|
| 3990 | if Data['setRings']: |
---|
| 3991 | N = 0 |
---|
| 3992 | for ring in Data['rings']: |
---|
| 3993 | xring,yring = np.array(ring).T[:2] |
---|
[1185] | 3994 | Plot.plot(xring,yring,'.',color=colors[N%6]) |
---|
[762] | 3995 | N += 1 |
---|
[1151] | 3996 | for ellipse in Data['ellipses']: #what about hyperbola? |
---|
[762] | 3997 | cent,phi,[width,height],col = ellipse |
---|
[1151] | 3998 | if width > 0: #ellipses |
---|
| 3999 | Plot.add_artist(Ellipse([cent[0],cent[1]],2*width,2*height,phi,ec=col,fc='none')) |
---|
| 4000 | Plot.text(cent[0],cent[1],'+',color=col,ha='center',va='center') |
---|
[762] | 4001 | if G2frame.PatternTree.GetItemText(G2frame.PickId) in 'Stress/Strain': |
---|
[1180] | 4002 | for N,ring in enumerate(StrSta['d-zero']): |
---|
[762] | 4003 | xring,yring = ring['ImxyObs'] |
---|
[1185] | 4004 | Plot.plot(xring,yring,colors[N%6]+'.') |
---|
[762] | 4005 | #masks - mask lines numbered after integration limit lines |
---|
| 4006 | spots = Masks['Points'] |
---|
| 4007 | rings = Masks['Rings'] |
---|
| 4008 | arcs = Masks['Arcs'] |
---|
| 4009 | polygons = Masks['Polygons'] |
---|
[1121] | 4010 | if 'Frames' not in Masks: |
---|
| 4011 | Masks['Frames'] = [] |
---|
| 4012 | frame = Masks['Frames'] |
---|
[1128] | 4013 | for spot in spots: |
---|
| 4014 | if spot: |
---|
| 4015 | x,y,d = spot |
---|
| 4016 | Plot.add_artist(Circle((x,y),radius=d/2,fc='none',ec='r',picker=3)) |
---|
[762] | 4017 | G2frame.ringList = [] |
---|
[1128] | 4018 | for iring,ring in enumerate(rings): |
---|
| 4019 | if ring: |
---|
| 4020 | tth,thick = ring |
---|
| 4021 | wave = Data['wavelength'] |
---|
[1151] | 4022 | xy1 = [] |
---|
| 4023 | xy2 = [] |
---|
| 4024 | Azm = np.linspace(0,362,181) |
---|
| 4025 | for azm in Azm: |
---|
| 4026 | xy1.append(G2img.GetDetectorXY(Dsp(tth+thick/2.,wave),azm,Data)) #what about hyperbola |
---|
| 4027 | xy2.append(G2img.GetDetectorXY(Dsp(tth-thick/2.,wave),azm,Data)) #what about hyperbola |
---|
| 4028 | x1,y1 = np.array(xy1).T |
---|
| 4029 | x2,y2 = np.array(xy2).T |
---|
[1128] | 4030 | G2frame.ringList.append([Plot.plot(x1,y1,'r',picker=3),iring,'o']) |
---|
| 4031 | G2frame.ringList.append([Plot.plot(x2,y2,'r',picker=3),iring,'i']) |
---|
[762] | 4032 | G2frame.arcList = [] |
---|
[1128] | 4033 | for iarc,arc in enumerate(arcs): |
---|
| 4034 | if arc: |
---|
| 4035 | tth,azm,thick = arc |
---|
| 4036 | wave = Data['wavelength'] |
---|
[1151] | 4037 | xy1 = [] |
---|
| 4038 | xy2 = [] |
---|
| 4039 | aR = azm[0],azm[1],azm[1]-azm[0] |
---|
| 4040 | if azm[1]-azm[0] > 180: |
---|
| 4041 | aR[2] /= 2 |
---|
| 4042 | Azm = np.linspace(aR[0],aR[1],aR[2]) |
---|
| 4043 | for azm in Azm: |
---|
| 4044 | xy1.append(G2img.GetDetectorXY(Dsp(tth+thick/2.,wave),azm,Data)) #what about hyperbola |
---|
| 4045 | xy2.append(G2img.GetDetectorXY(Dsp(tth-thick/2.,wave),azm,Data)) #what about hyperbola |
---|
| 4046 | x1,y1 = np.array(xy1).T |
---|
| 4047 | x2,y2 = np.array(xy2).T |
---|
[1128] | 4048 | G2frame.arcList.append([Plot.plot(x1,y1,'r',picker=3),iarc,'o']) |
---|
| 4049 | G2frame.arcList.append([Plot.plot(x2,y2,'r',picker=3),iarc,'i']) |
---|
| 4050 | G2frame.arcList.append([Plot.plot([x1[0],x2[0]],[y1[0],y2[0]],'r',picker=3),iarc,'l']) |
---|
| 4051 | G2frame.arcList.append([Plot.plot([x1[-1],x2[-1]],[y1[-1],y2[-1]],'r',picker=3),iarc,'u']) |
---|
[762] | 4052 | G2frame.polyList = [] |
---|
| 4053 | for ipoly,polygon in enumerate(polygons): |
---|
[1128] | 4054 | if polygon: |
---|
| 4055 | x,y = np.hsplit(np.array(polygon),2) |
---|
| 4056 | G2frame.polyList.append([Plot.plot(x,y,'r+',picker=10),ipoly]) |
---|
| 4057 | Plot.plot(x,y,'r') |
---|
[1121] | 4058 | G2frame.frameList = [] |
---|
| 4059 | if frame: |
---|
| 4060 | x,y = np.hsplit(np.array(frame),2) |
---|
| 4061 | G2frame.frameList.append([Plot.plot(x,y,'g+',picker=10),0]) |
---|
| 4062 | Plot.plot(x,y,'g') |
---|
[762] | 4063 | if newImage: |
---|
| 4064 | colorBar = Page.figure.colorbar(Img) |
---|
| 4065 | Plot.set_xlim(xlim) |
---|
| 4066 | Plot.set_ylim(ylim) |
---|
[1134] | 4067 | if Data['invert_x']: |
---|
| 4068 | Plot.invert_xaxis() |
---|
| 4069 | if Data['invert_y']: |
---|
| 4070 | Plot.invert_yaxis() |
---|
[762] | 4071 | if not newPlot and xylim: |
---|
| 4072 | Page.toolbar.push_current() |
---|
| 4073 | Plot.set_xlim(xylim[0]) |
---|
| 4074 | Plot.set_ylim(xylim[1]) |
---|
| 4075 | xylim = [] |
---|
| 4076 | Page.toolbar.push_current() |
---|
| 4077 | Page.toolbar.draw() |
---|
[1473] | 4078 | # patch for wx 2.9 on Mac, to force a redraw |
---|
| 4079 | i,j= wx.__version__.split('.')[0:2] |
---|
| 4080 | if int(i)+int(j)/10. > 2.8 and 'wxOSX' in wx.PlatformInfo: |
---|
| 4081 | Page.canvas.draw() |
---|
[762] | 4082 | else: |
---|
| 4083 | Page.canvas.draw() |
---|
| 4084 | finally: |
---|
| 4085 | wx.EndBusyCursor() |
---|
| 4086 | |
---|
| 4087 | ################################################################################ |
---|
| 4088 | ##### PlotIntegration |
---|
| 4089 | ################################################################################ |
---|
| 4090 | |
---|
| 4091 | def PlotIntegration(G2frame,newPlot=False,event=None): |
---|
| 4092 | '''Plot of 2D image after image integration with 2-theta and azimuth as coordinates |
---|
| 4093 | ''' |
---|
| 4094 | |
---|
| 4095 | def OnMotion(event): |
---|
| 4096 | Page.canvas.SetToolTipString('') |
---|
| 4097 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 4098 | azm = event.ydata |
---|
| 4099 | tth = event.xdata |
---|
| 4100 | if azm and tth: |
---|
| 4101 | G2frame.G2plotNB.status.SetFields(\ |
---|
| 4102 | ['','Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm)]) |
---|
| 4103 | |
---|
| 4104 | try: |
---|
| 4105 | plotNum = G2frame.G2plotNB.plotList.index('2D Integration') |
---|
| 4106 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 4107 | if not newPlot: |
---|
| 4108 | Plot = Page.figure.gca() #get previous plot & get limits |
---|
| 4109 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
| 4110 | Page.figure.clf() |
---|
| 4111 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
| 4112 | |
---|
| 4113 | except ValueError: |
---|
| 4114 | Plot = G2frame.G2plotNB.addMpl('2D Integration').gca() |
---|
| 4115 | plotNum = G2frame.G2plotNB.plotList.index('2D Integration') |
---|
| 4116 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 4117 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 4118 | Page.views = False |
---|
| 4119 | view = False |
---|
[796] | 4120 | Page.Choice = None |
---|
[762] | 4121 | if not event: |
---|
| 4122 | Page.SetFocus() |
---|
| 4123 | |
---|
| 4124 | Data = G2frame.PatternTree.GetItemPyData( |
---|
| 4125 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls')) |
---|
| 4126 | image = G2frame.Integrate[0] |
---|
| 4127 | xsc = G2frame.Integrate[1] |
---|
| 4128 | ysc = G2frame.Integrate[2] |
---|
| 4129 | Imin,Imax = Data['range'][1] |
---|
| 4130 | acolor = mpl.cm.get_cmap(Data['color']) |
---|
| 4131 | Plot.set_title(G2frame.PatternTree.GetItemText(G2frame.Image)[4:]) |
---|
| 4132 | Plot.set_ylabel('azimuth',fontsize=12) |
---|
| 4133 | Plot.set_xlabel('2-theta',fontsize=12) |
---|
| 4134 | Img = Plot.imshow(image,cmap=acolor,vmin=Imin,vmax=Imax,interpolation='nearest', \ |
---|
| 4135 | extent=[ysc[0],ysc[-1],xsc[-1],xsc[0]],aspect='auto') |
---|
| 4136 | colorBar = Page.figure.colorbar(Img) |
---|
[1148] | 4137 | # if Data['ellipses']: |
---|
| 4138 | # for ellipse in Data['ellipses']: |
---|
| 4139 | # x,y = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color |
---|
| 4140 | # tth,azm = G2img.GetTthAzm(x,y,Data) |
---|
| 4141 | ## azm = np.where(azm < 0.,azm+360,azm) |
---|
| 4142 | # Plot.plot(tth,azm,'b,') |
---|
[762] | 4143 | if not newPlot: |
---|
| 4144 | Page.toolbar.push_current() |
---|
| 4145 | Plot.set_xlim(xylim[0]) |
---|
| 4146 | Plot.set_ylim(xylim[1]) |
---|
| 4147 | xylim = [] |
---|
| 4148 | Page.toolbar.push_current() |
---|
| 4149 | Page.toolbar.draw() |
---|
| 4150 | else: |
---|
| 4151 | Page.canvas.draw() |
---|
| 4152 | |
---|
| 4153 | ################################################################################ |
---|
| 4154 | ##### PlotTRImage |
---|
| 4155 | ################################################################################ |
---|
| 4156 | |
---|
| 4157 | def PlotTRImage(G2frame,tax,tay,taz,newPlot=False): |
---|
| 4158 | '''a test plot routine - not normally used |
---|
| 4159 | ''' |
---|
| 4160 | |
---|
| 4161 | def OnMotion(event): |
---|
| 4162 | Page.canvas.SetToolTipString('') |
---|
| 4163 | Page.canvas.SetCursor(wx.CROSS_CURSOR) |
---|
| 4164 | azm = event.xdata |
---|
| 4165 | tth = event.ydata |
---|
| 4166 | if azm and tth: |
---|
| 4167 | G2frame.G2plotNB.status.SetFields(\ |
---|
| 4168 | ['','Detector 2-th =%9.3fdeg, azm = %7.2fdeg'%(tth,azm)]) |
---|
| 4169 | |
---|
| 4170 | try: |
---|
| 4171 | plotNum = G2frame.G2plotNB.plotList.index('2D Transformed Powder Image') |
---|
| 4172 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 4173 | if not newPlot: |
---|
| 4174 | Plot = Page.figure.gca() #get previous plot & get limits |
---|
| 4175 | xylim = Plot.get_xlim(),Plot.get_ylim() |
---|
| 4176 | Page.figure.clf() |
---|
| 4177 | Plot = Page.figure.gca() #get a fresh plot after clf() |
---|
| 4178 | |
---|
| 4179 | except ValueError: |
---|
| 4180 | Plot = G2frame.G2plotNB.addMpl('2D Transformed Powder Image').gca() |
---|
| 4181 | plotNum = G2frame.G2plotNB.plotList.index('2D Transformed Powder Image') |
---|
| 4182 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 4183 | Page.canvas.mpl_connect('motion_notify_event', OnMotion) |
---|
| 4184 | Page.views = False |
---|
| 4185 | view = False |
---|
[796] | 4186 | Page.Choice = None |
---|
[762] | 4187 | Page.SetFocus() |
---|
| 4188 | |
---|
| 4189 | Data = G2frame.PatternTree.GetItemPyData( |
---|
| 4190 | G2gd.GetPatternTreeItemId(G2frame,G2frame.Image, 'Image Controls')) |
---|
| 4191 | Imin,Imax = Data['range'][1] |
---|
| 4192 | step = (Imax-Imin)/5. |
---|
| 4193 | V = np.arange(Imin,Imax,step) |
---|
| 4194 | acolor = mpl.cm.get_cmap(Data['color']) |
---|
| 4195 | Plot.set_title(G2frame.PatternTree.GetItemText(G2frame.Image)[4:]) |
---|
| 4196 | Plot.set_xlabel('azimuth',fontsize=12) |
---|
| 4197 | Plot.set_ylabel('2-theta',fontsize=12) |
---|
| 4198 | Plot.contour(tax,tay,taz,V,cmap=acolor) |
---|
| 4199 | if Data['showLines']: |
---|
| 4200 | IOtth = Data['IOtth'] |
---|
| 4201 | if Data['fullIntegrate']: |
---|
| 4202 | LRAzim = [-180,180] |
---|
| 4203 | else: |
---|
| 4204 | LRAzim = Data['LRazimuth'] #NB: integers |
---|
| 4205 | Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[0],IOtth[0]],picker=True) |
---|
| 4206 | Plot.plot([LRAzim[0],LRAzim[1]],[IOtth[1],IOtth[1]],picker=True) |
---|
| 4207 | if not Data['fullIntegrate']: |
---|
| 4208 | Plot.plot([LRAzim[0],LRAzim[0]],[IOtth[0],IOtth[1]],picker=True) |
---|
| 4209 | Plot.plot([LRAzim[1],LRAzim[1]],[IOtth[0],IOtth[1]],picker=True) |
---|
| 4210 | if Data['setRings']: |
---|
| 4211 | rings = np.concatenate((Data['rings']),axis=0) |
---|
| 4212 | for xring,yring,dsp in rings: |
---|
| 4213 | x,y = G2img.GetTthAzm(xring,yring,Data) |
---|
| 4214 | Plot.plot(y,x,'r+') |
---|
| 4215 | if Data['ellipses']: |
---|
| 4216 | for ellipse in Data['ellipses']: |
---|
| 4217 | ring = np.array(G2img.makeIdealRing(ellipse[:3])) #skip color |
---|
| 4218 | x,y = np.hsplit(ring,2) |
---|
| 4219 | tth,azm = G2img.GetTthAzm(x,y,Data) |
---|
| 4220 | Plot.plot(azm,tth,'b,') |
---|
| 4221 | if not newPlot: |
---|
| 4222 | Page.toolbar.push_current() |
---|
| 4223 | Plot.set_xlim(xylim[0]) |
---|
| 4224 | Plot.set_ylim(xylim[1]) |
---|
| 4225 | xylim = [] |
---|
| 4226 | Page.toolbar.push_current() |
---|
| 4227 | Page.toolbar.draw() |
---|
| 4228 | else: |
---|
| 4229 | Page.canvas.draw() |
---|
| 4230 | |
---|
| 4231 | ################################################################################ |
---|
| 4232 | ##### PlotStructure |
---|
| 4233 | ################################################################################ |
---|
| 4234 | |
---|
[1381] | 4235 | def PlotStructure(G2frame,data,firstCall=False): |
---|
[762] | 4236 | '''Crystal structure plotting package. Can show structures as balls, sticks, lines, |
---|
| 4237 | thermal motion ellipsoids and polyhedra |
---|
| 4238 | ''' |
---|
[839] | 4239 | |
---|
[951] | 4240 | def FindPeaksBonds(XYZ): |
---|
[1460] | 4241 | rFact = data['Drawing'].get('radiusFactor',0.85) #data['Drawing'] could be empty! |
---|
[951] | 4242 | Bonds = [[] for x in XYZ] |
---|
| 4243 | for i,xyz in enumerate(XYZ): |
---|
| 4244 | Dx = XYZ-xyz |
---|
| 4245 | dist = np.sqrt(np.sum(np.inner(Dx,Amat)**2,axis=1)) |
---|
| 4246 | IndB = ma.nonzero(ma.masked_greater(dist,rFact*2.2)) |
---|
| 4247 | for j in IndB[0]: |
---|
| 4248 | Bonds[i].append(Dx[j]/2.) |
---|
| 4249 | Bonds[j].append(-Dx[j]/2.) |
---|
| 4250 | return Bonds |
---|
| 4251 | |
---|
[1383] | 4252 | # PlotStructure initialization here |
---|
[762] | 4253 | ForthirdPI = 4.0*math.pi/3.0 |
---|
| 4254 | generalData = data['General'] |
---|
| 4255 | cell = generalData['Cell'][1:7] |
---|
| 4256 | Vol = generalData['Cell'][7:8][0] |
---|
| 4257 | Amat,Bmat = G2lat.cell2AB(cell) #Amat - crystal to cartesian, Bmat - inverse |
---|
| 4258 | Gmat,gmat = G2lat.cell2Gmat(cell) |
---|
| 4259 | A4mat = np.concatenate((np.concatenate((Amat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
| 4260 | B4mat = np.concatenate((np.concatenate((Bmat,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
[951] | 4261 | SGData = generalData['SGData'] |
---|
[1633] | 4262 | if generalData['Type'] in ['modulated','magnetic']: |
---|
| 4263 | SSGData = generalData['SSGData'] |
---|
[762] | 4264 | Mydir = generalData['Mydir'] |
---|
[1951] | 4265 | Super = generalData.get('Super',0) |
---|
[762] | 4266 | atomData = data['Atoms'] |
---|
| 4267 | mapPeaks = [] |
---|
[1470] | 4268 | drawingData = data['Drawing'] |
---|
| 4269 | if not drawingData: |
---|
| 4270 | return #nothing setup, nothing to draw |
---|
[762] | 4271 | if 'Map Peaks' in data: |
---|
[766] | 4272 | mapPeaks = np.array(data['Map Peaks']) |
---|
[777] | 4273 | peakMax = 100. |
---|
| 4274 | if len(mapPeaks): |
---|
| 4275 | peakMax = np.max(mapPeaks.T[0]) |
---|
[855] | 4276 | resRBData = data['RBModels'].get('Residue',[]) |
---|
| 4277 | vecRBData = data['RBModels'].get('Vector',[]) |
---|
| 4278 | rbAtmDict = {} |
---|
| 4279 | for rbObj in resRBData+vecRBData: |
---|
| 4280 | exclList = ['X' for i in range(len(rbObj['Ids']))] |
---|
| 4281 | rbAtmDict.update(dict(zip(rbObj['Ids'],exclList))) |
---|
[851] | 4282 | testRBObj = data.get('testRBObj',{}) |
---|
| 4283 | rbObj = testRBObj.get('rbObj',{}) |
---|
[934] | 4284 | MCSA = data.get('MCSA',{}) |
---|
[936] | 4285 | mcsaModels = MCSA.get('Models',[]) |
---|
[1474] | 4286 | if len(mcsaModels) > 1: |
---|
[953] | 4287 | XYZs,Types = G2mth.UpdateMCSAxyz(Bmat,MCSA) |
---|
| 4288 | mcsaXYZ = [] |
---|
| 4289 | mcsaTypes = [] |
---|
[1471] | 4290 | neqv = 0 |
---|
[953] | 4291 | for xyz,atyp in zip(XYZs,Types): |
---|
[1471] | 4292 | equiv = G2spc.GenAtom(xyz,SGData,All=True,Move=False) |
---|
| 4293 | neqv = max(neqv,len(equiv)) |
---|
| 4294 | for item in equiv: |
---|
[953] | 4295 | mcsaXYZ.append(item[0]) |
---|
| 4296 | mcsaTypes.append(atyp) |
---|
[1471] | 4297 | mcsaXYZ = np.array(mcsaXYZ) |
---|
| 4298 | mcsaTypes = np.array(mcsaTypes) |
---|
| 4299 | nuniq = mcsaXYZ.shape[0]/neqv |
---|
| 4300 | mcsaXYZ = np.reshape(mcsaXYZ,(nuniq,neqv,3)) |
---|
| 4301 | mcsaTypes = np.reshape(mcsaTypes,(nuniq,neqv)) |
---|
| 4302 | cent = np.fix(np.sum(mcsaXYZ+2.,axis=0)/nuniq)-2 |
---|
| 4303 | cent[0] = [0,0,0] #make sure 1st one isn't moved |
---|
| 4304 | mcsaXYZ = np.swapaxes(mcsaXYZ,0,1)-cent[:,np.newaxis,:] |
---|
| 4305 | mcsaTypes = np.swapaxes(mcsaTypes,0,1) |
---|
| 4306 | mcsaXYZ = np.reshape(mcsaXYZ,(nuniq*neqv,3)) |
---|
| 4307 | mcsaTypes = np.reshape(mcsaTypes,(nuniq*neqv)) |
---|
[953] | 4308 | mcsaBonds = FindPeaksBonds(mcsaXYZ) |
---|
[851] | 4309 | drawAtoms = drawingData.get('Atoms',[]) |
---|
[762] | 4310 | mapData = {} |
---|
| 4311 | flipData = {} |
---|
| 4312 | rhoXYZ = [] |
---|
[840] | 4313 | showBonds = False |
---|
[762] | 4314 | if 'Map' in generalData: |
---|
| 4315 | mapData = generalData['Map'] |
---|
[863] | 4316 | showBonds = mapData.get('Show bonds',False) |
---|
[762] | 4317 | if 'Flip' in generalData: |
---|
| 4318 | flipData = generalData['Flip'] |
---|
| 4319 | Wt = np.array([255,255,255]) |
---|
| 4320 | Rd = np.array([255,0,0]) |
---|
| 4321 | Gr = np.array([0,255,0]) |
---|
[1378] | 4322 | wxGreen = wx.Colour(0,255,0) |
---|
[762] | 4323 | Bl = np.array([0,0,255]) |
---|
[853] | 4324 | Or = np.array([255,128,0]) |
---|
[1378] | 4325 | wxOrange = wx.Colour(255,128,0) |
---|
[762] | 4326 | 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]]) |
---|
| 4327 | uEdges = np.array([ |
---|
| 4328 | [uBox[0],uBox[1]],[uBox[0],uBox[3]],[uBox[0],uBox[4]],[uBox[1],uBox[2]], |
---|
| 4329 | [uBox[2],uBox[3]],[uBox[1],uBox[5]],[uBox[2],uBox[6]],[uBox[3],uBox[7]], |
---|
| 4330 | [uBox[4],uBox[5]],[uBox[5],uBox[6]],[uBox[6],uBox[7]],[uBox[7],uBox[4]]]) |
---|
| 4331 | mD = 0.1 |
---|
| 4332 | mV = np.array([[[-mD,0,0],[mD,0,0]],[[0,-mD,0],[0,mD,0]],[[0,0,-mD],[0,0,mD]]]) |
---|
| 4333 | mapPeakVecs = np.inner(mV,Bmat) |
---|
| 4334 | |
---|
[1559] | 4335 | backColor = np.array(list(drawingData['backColor'])+[0,]) |
---|
| 4336 | Bc = np.array(list(drawingData['backColor'])) |
---|
| 4337 | uColors = [Rd,Gr,Bl,Wt-Bc, Wt-Bc,Wt-Bc,Wt-Bc,Wt-Bc, Wt-Bc,Wt-Bc,Wt-Bc,Wt-Bc] |
---|
[762] | 4338 | altDown = False |
---|
| 4339 | shiftDown = False |
---|
| 4340 | ctrlDown = False |
---|
[1633] | 4341 | G2frame.tau = 0. |
---|
[762] | 4342 | |
---|
| 4343 | def OnKeyBox(event): |
---|
| 4344 | mode = cb.GetValue() |
---|
| 4345 | if mode in ['jpeg','bmp','tiff',]: |
---|
[1397] | 4346 | try: |
---|
| 4347 | import Image as Im |
---|
| 4348 | except ImportError: |
---|
| 4349 | try: |
---|
| 4350 | from PIL import Image as Im |
---|
| 4351 | except ImportError: |
---|
| 4352 | print "PIL/pillow Image module not present. Cannot save images without this" |
---|
| 4353 | raise Exception("PIL/pillow Image module not found") |
---|
[837] | 4354 | Fname = os.path.join(Mydir,generalData['Name']+'.'+mode) |
---|
[762] | 4355 | size = Page.canvas.GetSize() |
---|
| 4356 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1) |
---|
| 4357 | if mode in ['jpeg',]: |
---|
| 4358 | Pix = glReadPixels(0,0,size[0],size[1],GL_RGBA, GL_UNSIGNED_BYTE) |
---|
[1608] | 4359 | im = Im.new("RGBA", (size[0],size[1])) |
---|
[762] | 4360 | else: |
---|
| 4361 | Pix = glReadPixels(0,0,size[0],size[1],GL_RGB, GL_UNSIGNED_BYTE) |
---|
[1608] | 4362 | im = Im.new("RGB", (size[0],size[1])) |
---|
[762] | 4363 | im.fromstring(Pix) |
---|
| 4364 | im.save(Fname,mode) |
---|
| 4365 | cb.SetValue(' save as/key:') |
---|
| 4366 | G2frame.G2plotNB.status.SetStatusText('Drawing saved to: '+Fname,1) |
---|
| 4367 | else: |
---|
| 4368 | event.key = cb.GetValue()[0] |
---|
| 4369 | cb.SetValue(' save as/key:') |
---|
| 4370 | wx.CallAfter(OnKey,event) |
---|
[1005] | 4371 | Page.canvas.SetFocus() # redirect the Focus from the button back to the plot |
---|
[762] | 4372 | |
---|
| 4373 | def OnKey(event): #on key UP!! |
---|
[1951] | 4374 | keyBox = False |
---|
[762] | 4375 | try: |
---|
| 4376 | keyCode = event.GetKeyCode() |
---|
| 4377 | if keyCode > 255: |
---|
| 4378 | keyCode = 0 |
---|
| 4379 | key = chr(keyCode) |
---|
| 4380 | except AttributeError: #if from OnKeyBox above |
---|
[1951] | 4381 | keyBox = True |
---|
[762] | 4382 | key = str(event.key).upper() |
---|
| 4383 | indx = drawingData['selectedAtoms'] |
---|
[910] | 4384 | cx,ct = drawingData['atomPtrs'][:2] |
---|
[762] | 4385 | if key in ['C']: |
---|
| 4386 | drawingData['viewPoint'] = [[.5,.5,.5],[0,0]] |
---|
| 4387 | drawingData['viewDir'] = [0,0,1] |
---|
| 4388 | drawingData['oldxy'] = [] |
---|
| 4389 | V0 = np.array([0,0,1]) |
---|
| 4390 | V = np.inner(Amat,V0) |
---|
| 4391 | V /= np.sqrt(np.sum(V**2)) |
---|
| 4392 | A = np.arccos(np.sum(V*V0)) |
---|
| 4393 | Q = G2mth.AV2Q(A,[0,1,0]) |
---|
| 4394 | drawingData['Quaternion'] = Q |
---|
| 4395 | SetViewPointText(drawingData['viewPoint'][0]) |
---|
| 4396 | SetViewDirText(drawingData['viewDir']) |
---|
| 4397 | Q = drawingData['Quaternion'] |
---|
| 4398 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
| 4399 | elif key in ['N']: |
---|
| 4400 | drawAtoms = drawingData['Atoms'] |
---|
[1005] | 4401 | if not len(drawAtoms): #no atoms |
---|
| 4402 | return |
---|
[762] | 4403 | pI = drawingData['viewPoint'][1] |
---|
[1005] | 4404 | if not len(pI): |
---|
| 4405 | pI = [0,0] |
---|
[762] | 4406 | if indx: |
---|
| 4407 | pI[0] = indx[pI[1]] |
---|
| 4408 | Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3] |
---|
| 4409 | pI[1] += 1 |
---|
| 4410 | if pI[1] >= len(indx): |
---|
| 4411 | pI[1] = 0 |
---|
| 4412 | else: |
---|
| 4413 | Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3] |
---|
| 4414 | pI[0] += 1 |
---|
| 4415 | if pI[0] >= len(drawAtoms): |
---|
| 4416 | pI[0] = 0 |
---|
| 4417 | drawingData['viewPoint'] = [[Tx,Ty,Tz],pI] |
---|
| 4418 | SetViewPointText(drawingData['viewPoint'][0]) |
---|
| 4419 | G2frame.G2plotNB.status.SetStatusText('View point at atom '+drawAtoms[pI[0]][ct-1]+str(pI),1) |
---|
| 4420 | |
---|
| 4421 | elif key in ['P']: |
---|
| 4422 | drawAtoms = drawingData['Atoms'] |
---|
[1005] | 4423 | if not len(drawAtoms): #no atoms |
---|
| 4424 | return |
---|
[762] | 4425 | pI = drawingData['viewPoint'][1] |
---|
[1005] | 4426 | if not len(pI): |
---|
| 4427 | pI = [0,0] |
---|
[762] | 4428 | if indx: |
---|
| 4429 | pI[0] = indx[pI[1]] |
---|
| 4430 | Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3] |
---|
| 4431 | pI[1] -= 1 |
---|
| 4432 | if pI[1] < 0: |
---|
| 4433 | pI[1] = len(indx)-1 |
---|
| 4434 | else: |
---|
| 4435 | Tx,Ty,Tz = drawAtoms[pI[0]][cx:cx+3] |
---|
| 4436 | pI[0] -= 1 |
---|
| 4437 | if pI[0] < 0: |
---|
| 4438 | pI[0] = len(drawAtoms)-1 |
---|
| 4439 | drawingData['viewPoint'] = [[Tx,Ty,Tz],pI] |
---|
| 4440 | SetViewPointText(drawingData['viewPoint'][0]) |
---|
| 4441 | G2frame.G2plotNB.status.SetStatusText('View point at atom '+drawAtoms[pI[0]][ct-1]+str(pI),1) |
---|
| 4442 | elif key in ['U','D','L','R'] and mapData['Flip'] == True: |
---|
| 4443 | dirDict = {'U':[0,1],'D':[0,-1],'L':[-1,0],'R':[1,0]} |
---|
| 4444 | SetMapRoll(dirDict[key]) |
---|
[1623] | 4445 | if 'rho' in generalData.get('4DmapData',{}): |
---|
| 4446 | Set4DMapRoll(dirDict[key]) |
---|
[762] | 4447 | SetPeakRoll(dirDict[key]) |
---|
| 4448 | SetMapPeaksText(mapPeaks) |
---|
[1694] | 4449 | elif key in ['+','-','=','0'] and generalData['Type'] in ['modulated','magnetic']: |
---|
[1951] | 4450 | if keyBox: |
---|
| 4451 | OnKeyPressed(event) |
---|
[1958] | 4452 | return |
---|
| 4453 | Draw('key up') |
---|
[1951] | 4454 | |
---|
| 4455 | def OnKeyPressed(event): #On key down for repeating operation - used to change tau... |
---|
| 4456 | try: |
---|
| 4457 | keyCode = event.GetKeyCode() |
---|
| 4458 | if keyCode > 255: |
---|
| 4459 | keyCode = 0 |
---|
| 4460 | key = chr(keyCode) |
---|
| 4461 | except AttributeError: #if from OnKeyBox above |
---|
| 4462 | key = str(event.key).upper() |
---|
| 4463 | if key in ['+','-','=','0'] and generalData['Type'] in ['modulated','magnetic']: |
---|
[1633] | 4464 | if key == '0': |
---|
| 4465 | G2frame.tau = 0. |
---|
[1694] | 4466 | elif key in ['+','=']: |
---|
[1633] | 4467 | G2frame.tau += 0.05 |
---|
[1694] | 4468 | elif key == '-': |
---|
[1633] | 4469 | G2frame.tau -= 0.05 |
---|
| 4470 | G2frame.tau %= 1. #force 0-1 range |
---|
[1951] | 4471 | G2frame.G2plotNB.status.SetStatusText('Modulation tau = %.2f'%(G2frame.tau),1) |
---|
[1958] | 4472 | data['Drawing']['Atoms'],Fade = G2mth.ApplyModulation(data,G2frame.tau) #modifies drawing atom array! |
---|
[1951] | 4473 | SetDrawAtomsText(data['Drawing']['Atoms']) |
---|
| 4474 | G2phG.FindBondsDraw(data) #rebuild bonds & polygons |
---|
[1958] | 4475 | if not np.any(Fade): |
---|
| 4476 | Fade += 1 |
---|
| 4477 | Draw('key down',Fade) |
---|
[762] | 4478 | |
---|
| 4479 | def GetTruePosition(xy,Add=False): |
---|
| 4480 | View = glGetIntegerv(GL_VIEWPORT) |
---|
| 4481 | Proj = glGetDoublev(GL_PROJECTION_MATRIX) |
---|
| 4482 | Model = glGetDoublev(GL_MODELVIEW_MATRIX) |
---|
| 4483 | Zmax = 1. |
---|
| 4484 | if Add: |
---|
| 4485 | Indx = GetSelectedAtoms() |
---|
| 4486 | if G2frame.dataDisplay.GetPageText(getSelection()) == 'Map peaks': |
---|
| 4487 | for i,peak in enumerate(mapPeaks): |
---|
| 4488 | x,y,z = peak[1:4] |
---|
| 4489 | X,Y,Z = gluProject(x,y,z,Model,Proj,View) |
---|
| 4490 | XY = [int(X),int(View[3]-Y)] |
---|
| 4491 | if np.allclose(xy,XY,atol=10) and Z < Zmax: |
---|
| 4492 | Zmax = Z |
---|
| 4493 | try: |
---|
| 4494 | Indx.remove(i) |
---|
| 4495 | ClearSelectedAtoms() |
---|
| 4496 | for id in Indx: |
---|
| 4497 | SetSelectedAtoms(id,Add) |
---|
| 4498 | except: |
---|
| 4499 | SetSelectedAtoms(i,Add) |
---|
| 4500 | else: |
---|
[910] | 4501 | cx = drawingData['atomPtrs'][0] |
---|
[762] | 4502 | for i,atom in enumerate(drawAtoms): |
---|
| 4503 | x,y,z = atom[cx:cx+3] |
---|
| 4504 | X,Y,Z = gluProject(x,y,z,Model,Proj,View) |
---|
| 4505 | XY = [int(X),int(View[3]-Y)] |
---|
| 4506 | if np.allclose(xy,XY,atol=10) and Z < Zmax: |
---|
| 4507 | Zmax = Z |
---|
| 4508 | try: |
---|
| 4509 | Indx.remove(i) |
---|
| 4510 | ClearSelectedAtoms() |
---|
| 4511 | for id in Indx: |
---|
| 4512 | SetSelectedAtoms(id,Add) |
---|
| 4513 | except: |
---|
| 4514 | SetSelectedAtoms(i,Add) |
---|
| 4515 | |
---|
| 4516 | def OnMouseDown(event): |
---|
| 4517 | xy = event.GetPosition() |
---|
| 4518 | if event.ShiftDown(): |
---|
| 4519 | if event.LeftIsDown(): |
---|
| 4520 | GetTruePosition(xy) |
---|
| 4521 | elif event.RightIsDown(): |
---|
| 4522 | GetTruePosition(xy,True) |
---|
| 4523 | else: |
---|
| 4524 | drawingData['oldxy'] = list(xy) |
---|
| 4525 | |
---|
| 4526 | def OnMouseMove(event): |
---|
| 4527 | if event.ShiftDown(): #don't want any inadvertant moves when picking |
---|
| 4528 | return |
---|
| 4529 | newxy = event.GetPosition() |
---|
| 4530 | |
---|
[851] | 4531 | if event.Dragging(): |
---|
[860] | 4532 | if event.AltDown() and rbObj: |
---|
[851] | 4533 | if event.LeftIsDown(): |
---|
| 4534 | SetRBRotation(newxy) |
---|
| 4535 | Q = rbObj['Orient'][0] |
---|
| 4536 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
| 4537 | elif event.RightIsDown(): |
---|
| 4538 | SetRBTranslation(newxy) |
---|
| 4539 | Tx,Ty,Tz = rbObj['Orig'][0] |
---|
| 4540 | G2frame.G2plotNB.status.SetStatusText('New view point: %.4f, %.4f, %.4f'%(Tx,Ty,Tz),1) |
---|
| 4541 | elif event.MiddleIsDown(): |
---|
| 4542 | SetRBRotationZ(newxy) |
---|
| 4543 | Q = rbObj['Orient'][0] |
---|
| 4544 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
| 4545 | Draw('move') |
---|
| 4546 | elif not event.ControlDown(): |
---|
| 4547 | if event.LeftIsDown(): |
---|
| 4548 | SetRotation(newxy) |
---|
| 4549 | Q = drawingData['Quaternion'] |
---|
| 4550 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
| 4551 | elif event.RightIsDown(): |
---|
| 4552 | SetTranslation(newxy) |
---|
| 4553 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
[1928] | 4554 | rho = G2mth.getRho([Tx,Ty,Tz],mapData) |
---|
| 4555 | G2frame.G2plotNB.status.SetStatusText('New view point: %.4f, %.4f, %.4f; density: %.4f'%(Tx,Ty,Tz,rho),1) |
---|
[851] | 4556 | elif event.MiddleIsDown(): |
---|
| 4557 | SetRotationZ(newxy) |
---|
| 4558 | Q = drawingData['Quaternion'] |
---|
| 4559 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
| 4560 | Draw('move') |
---|
| 4561 | |
---|
[762] | 4562 | |
---|
| 4563 | def OnMouseWheel(event): |
---|
| 4564 | if event.ShiftDown(): |
---|
| 4565 | return |
---|
[924] | 4566 | drawingData['cameraPos'] += event.GetWheelRotation()/24. |
---|
[762] | 4567 | drawingData['cameraPos'] = max(10,min(500,drawingData['cameraPos'])) |
---|
| 4568 | G2frame.G2plotNB.status.SetStatusText('New camera distance: %.2f'%(drawingData['cameraPos']),1) |
---|
| 4569 | page = getSelection() |
---|
| 4570 | if page: |
---|
| 4571 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Options': |
---|
[924] | 4572 | G2frame.dataDisplay.cameraPosTxt.SetLabel('Camera Position: '+'%.2f'%(drawingData['cameraPos'])) |
---|
| 4573 | G2frame.dataDisplay.cameraSlider.SetValue(drawingData['cameraPos']) |
---|
[762] | 4574 | Draw('wheel') |
---|
| 4575 | |
---|
| 4576 | def getSelection(): |
---|
| 4577 | try: |
---|
| 4578 | return G2frame.dataDisplay.GetSelection() |
---|
| 4579 | except AttributeError: |
---|
[1306] | 4580 | G2frame.G2plotNB.status.SetStatusText('Select this from Phase data window!',1) |
---|
[762] | 4581 | return 0 |
---|
| 4582 | |
---|
| 4583 | def SetViewPointText(VP): |
---|
| 4584 | page = getSelection() |
---|
| 4585 | if page: |
---|
| 4586 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Options': |
---|
[924] | 4587 | G2frame.dataDisplay.viewPoint.SetValue('%.3f %.3f %.3f'%(VP[0],VP[1],VP[2])) |
---|
[762] | 4588 | |
---|
[851] | 4589 | def SetRBOrigText(): |
---|
| 4590 | page = getSelection() |
---|
| 4591 | if page: |
---|
| 4592 | if G2frame.dataDisplay.GetPageText(page) == 'RB Models': |
---|
| 4593 | for i,sizer in enumerate(testRBObj['Sizers']['Xsizers']): |
---|
| 4594 | sizer.SetValue('%8.5f'%(testRBObj['rbObj']['Orig'][0][i])) |
---|
| 4595 | |
---|
| 4596 | def SetRBOrienText(): |
---|
| 4597 | page = getSelection() |
---|
| 4598 | if page: |
---|
| 4599 | if G2frame.dataDisplay.GetPageText(page) == 'RB Models': |
---|
| 4600 | for i,sizer in enumerate(testRBObj['Sizers']['Osizers']): |
---|
| 4601 | sizer.SetValue('%8.5f'%(testRBObj['rbObj']['Orient'][0][i])) |
---|
| 4602 | |
---|
[762] | 4603 | def SetViewDirText(VD): |
---|
| 4604 | page = getSelection() |
---|
| 4605 | if page: |
---|
| 4606 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Options': |
---|
[922] | 4607 | G2frame.dataDisplay.viewDir.SetValue('%.3f %.3f %.3f'%(VD[0],VD[1],VD[2])) |
---|
[762] | 4608 | |
---|
| 4609 | def SetMapPeaksText(mapPeaks): |
---|
| 4610 | page = getSelection() |
---|
| 4611 | if page: |
---|
| 4612 | if G2frame.dataDisplay.GetPageText(page) == 'Map peaks': |
---|
| 4613 | G2frame.MapPeaksTable.SetData(mapPeaks) |
---|
| 4614 | panel = G2frame.dataDisplay.GetPage(page).GetChildren() |
---|
| 4615 | names = [child.GetName() for child in panel] |
---|
[1880] | 4616 | try: |
---|
| 4617 | panel[names.index('GridWindow')].Refresh() |
---|
| 4618 | except ValueError: #different wx versions! |
---|
| 4619 | panel[names.index('grid window')].Refresh() |
---|
[762] | 4620 | |
---|
[1951] | 4621 | def SetDrawAtomsText(drawAtoms): |
---|
| 4622 | page = getSelection() |
---|
| 4623 | if page: |
---|
| 4624 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms': |
---|
| 4625 | table = G2frame.atomTable.GetData() |
---|
| 4626 | for i,atom in enumerate(drawAtoms): |
---|
| 4627 | table[i][2:5] = atom[2:5] |
---|
| 4628 | G2frame.atomTable.SetData(table) |
---|
| 4629 | panel = G2frame.dataDisplay.GetPage(page).GetChildren() |
---|
| 4630 | names = [child.GetName() for child in panel] |
---|
| 4631 | try: |
---|
| 4632 | panel[names.index('GridWindow')].Refresh() |
---|
| 4633 | except ValueError: #different wx versions! |
---|
| 4634 | panel[names.index('grid window')].Refresh() |
---|
| 4635 | |
---|
[762] | 4636 | def ClearSelectedAtoms(): |
---|
| 4637 | page = getSelection() |
---|
| 4638 | if page: |
---|
| 4639 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms': |
---|
| 4640 | G2frame.dataDisplay.GetPage(page).ClearSelection() #this is the Atoms grid in Draw Atoms |
---|
| 4641 | elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks': |
---|
| 4642 | G2frame.dataDisplay.GetPage(page).ClearSelection() #this is the Atoms grid in Atoms |
---|
| 4643 | elif G2frame.dataDisplay.GetPageText(page) == 'Atoms': |
---|
| 4644 | G2frame.dataDisplay.GetPage(page).ClearSelection() #this is the Atoms grid in Atoms |
---|
| 4645 | |
---|
| 4646 | |
---|
| 4647 | def SetSelectedAtoms(ind,Add=False): |
---|
| 4648 | page = getSelection() |
---|
| 4649 | if page: |
---|
| 4650 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms': |
---|
| 4651 | G2frame.dataDisplay.GetPage(page).SelectRow(ind,Add) #this is the Atoms grid in Draw Atoms |
---|
| 4652 | elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks': |
---|
| 4653 | G2frame.dataDisplay.GetPage(page).SelectRow(ind,Add) |
---|
| 4654 | elif G2frame.dataDisplay.GetPageText(page) == 'Atoms': |
---|
[807] | 4655 | Id = drawAtoms[ind][-3] |
---|
[762] | 4656 | for i,atom in enumerate(atomData): |
---|
| 4657 | if atom[-1] == Id: |
---|
| 4658 | G2frame.dataDisplay.GetPage(page).SelectRow(i) #this is the Atoms grid in Atoms |
---|
| 4659 | |
---|
| 4660 | def GetSelectedAtoms(): |
---|
| 4661 | page = getSelection() |
---|
| 4662 | Ind = [] |
---|
| 4663 | if page: |
---|
| 4664 | if G2frame.dataDisplay.GetPageText(page) == 'Draw Atoms': |
---|
| 4665 | Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows() #this is the Atoms grid in Draw Atoms |
---|
| 4666 | elif G2frame.dataDisplay.GetPageText(page) == 'Map peaks': |
---|
| 4667 | Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows() |
---|
| 4668 | elif G2frame.dataDisplay.GetPageText(page) == 'Atoms': |
---|
| 4669 | Ind = G2frame.dataDisplay.GetPage(page).GetSelectedRows() #this is the Atoms grid in Atoms |
---|
| 4670 | return Ind |
---|
| 4671 | |
---|
| 4672 | def SetBackground(): |
---|
| 4673 | R,G,B,A = Page.camera['backColor'] |
---|
| 4674 | glClearColor(R,G,B,A) |
---|
| 4675 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
---|
| 4676 | |
---|
| 4677 | def SetLights(): |
---|
| 4678 | glEnable(GL_DEPTH_TEST) |
---|
| 4679 | glShadeModel(GL_SMOOTH) |
---|
| 4680 | glEnable(GL_LIGHTING) |
---|
| 4681 | glEnable(GL_LIGHT0) |
---|
| 4682 | glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0) |
---|
| 4683 | glLightfv(GL_LIGHT0,GL_AMBIENT,[1,1,1,.8]) |
---|
| 4684 | glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1]) |
---|
| 4685 | |
---|
[1623] | 4686 | def GetRoll(newxy,rhoshape): |
---|
[762] | 4687 | Q = drawingData['Quaternion'] |
---|
| 4688 | dxy = G2mth.prodQVQ(G2mth.invQ(Q),np.inner(Bmat,newxy+[0,])) |
---|
[1623] | 4689 | dxy = np.array(dxy*rhoshape) |
---|
[762] | 4690 | roll = np.where(dxy>0.5,1,np.where(dxy<-.5,-1,0)) |
---|
| 4691 | return roll |
---|
| 4692 | |
---|
| 4693 | def SetMapRoll(newxy): |
---|
| 4694 | rho = mapData['rho'] |
---|
[1623] | 4695 | roll = GetRoll(newxy,rho.shape) |
---|
[762] | 4696 | mapData['rho'] = np.roll(np.roll(np.roll(rho,roll[0],axis=0),roll[1],axis=1),roll[2],axis=2) |
---|
| 4697 | drawingData['oldxy'] = list(newxy) |
---|
| 4698 | |
---|
[1623] | 4699 | def Set4DMapRoll(newxy): |
---|
| 4700 | rho = generalData['4DmapData']['rho'] |
---|
| 4701 | roll = GetRoll(newxy,rho.shape[:3]) |
---|
| 4702 | generalData['4DmapData']['rho'] = np.roll(np.roll(np.roll(rho,roll[0],axis=0),roll[1],axis=1),roll[2],axis=2) |
---|
| 4703 | |
---|
[762] | 4704 | def SetPeakRoll(newxy): |
---|
| 4705 | rho = mapData['rho'] |
---|
[1623] | 4706 | roll = GetRoll(newxy,rho.shape) |
---|
[762] | 4707 | steps = 1./np.array(rho.shape) |
---|
| 4708 | dxy = roll*steps |
---|
| 4709 | for peak in mapPeaks: |
---|
| 4710 | peak[1:4] += dxy |
---|
| 4711 | peak[1:4] %= 1. |
---|
| 4712 | peak[4] = np.sqrt(np.sum(np.inner(Amat,peak[1:4])**2)) |
---|
| 4713 | |
---|
| 4714 | def SetTranslation(newxy): |
---|
| 4715 | #first get translation vector in screen coords. |
---|
| 4716 | oldxy = drawingData['oldxy'] |
---|
| 4717 | if not len(oldxy): oldxy = list(newxy) |
---|
| 4718 | dxy = newxy-oldxy |
---|
| 4719 | drawingData['oldxy'] = list(newxy) |
---|
| 4720 | V = np.array([-dxy[0],dxy[1],0.]) |
---|
| 4721 | #then transform to rotated crystal coordinates & apply to view point |
---|
| 4722 | Q = drawingData['Quaternion'] |
---|
| 4723 | V = np.inner(Bmat,G2mth.prodQVQ(G2mth.invQ(Q),V)) |
---|
| 4724 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
| 4725 | Tx += V[0]*0.01 |
---|
| 4726 | Ty += V[1]*0.01 |
---|
| 4727 | Tz += V[2]*0.01 |
---|
| 4728 | drawingData['viewPoint'][0] = Tx,Ty,Tz |
---|
| 4729 | SetViewPointText([Tx,Ty,Tz]) |
---|
| 4730 | |
---|
[851] | 4731 | def SetRBTranslation(newxy): |
---|
| 4732 | #first get translation vector in screen coords. |
---|
| 4733 | oldxy = drawingData['oldxy'] |
---|
| 4734 | if not len(oldxy): oldxy = list(newxy) |
---|
| 4735 | dxy = newxy-oldxy |
---|
| 4736 | drawingData['oldxy'] = list(newxy) |
---|
| 4737 | V = np.array([-dxy[0],dxy[1],0.]) |
---|
| 4738 | #then transform to rotated crystal coordinates & apply to RB origin |
---|
| 4739 | Q = drawingData['Quaternion'] |
---|
| 4740 | V = np.inner(Bmat,G2mth.prodQVQ(G2mth.invQ(Q),V)) |
---|
| 4741 | Tx,Ty,Tz = rbObj['Orig'][0] |
---|
| 4742 | Tx -= V[0]*0.01 |
---|
| 4743 | Ty -= V[1]*0.01 |
---|
| 4744 | Tz -= V[2]*0.01 |
---|
| 4745 | rbObj['Orig'][0] = Tx,Ty,Tz |
---|
| 4746 | SetRBOrigText() |
---|
| 4747 | |
---|
[762] | 4748 | def SetRotation(newxy): |
---|
[1383] | 4749 | 'Perform a rotation in x-y space due to a left-mouse drag' |
---|
| 4750 | #first get rotation vector in screen coords. & angle increment |
---|
[762] | 4751 | oldxy = drawingData['oldxy'] |
---|
| 4752 | if not len(oldxy): oldxy = list(newxy) |
---|
| 4753 | dxy = newxy-oldxy |
---|
| 4754 | drawingData['oldxy'] = list(newxy) |
---|
| 4755 | V = np.array([dxy[1],dxy[0],0.]) |
---|
| 4756 | A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2) |
---|
[1383] | 4757 | if not A: return # nothing changed, nothing to do |
---|
| 4758 | # next transform vector back to xtal coordinates via inverse quaternion |
---|
| 4759 | # & make new quaternion |
---|
[762] | 4760 | Q = drawingData['Quaternion'] |
---|
| 4761 | V = G2mth.prodQVQ(G2mth.invQ(Q),np.inner(Bmat,V)) |
---|
| 4762 | DQ = G2mth.AVdeg2Q(A,V) |
---|
| 4763 | Q = G2mth.prodQQ(Q,DQ) |
---|
| 4764 | drawingData['Quaternion'] = Q |
---|
[1383] | 4765 | # finally get new view vector - last row of rotation matrix |
---|
[762] | 4766 | VD = np.inner(Bmat,G2mth.Q2Mat(Q)[2]) |
---|
| 4767 | VD /= np.sqrt(np.sum(VD**2)) |
---|
| 4768 | drawingData['viewDir'] = VD |
---|
| 4769 | SetViewDirText(VD) |
---|
| 4770 | |
---|
| 4771 | def SetRotationZ(newxy): |
---|
| 4772 | #first get rotation vector (= view vector) in screen coords. & angle increment |
---|
| 4773 | View = glGetIntegerv(GL_VIEWPORT) |
---|
| 4774 | cent = [View[2]/2,View[3]/2] |
---|
| 4775 | oldxy = drawingData['oldxy'] |
---|
| 4776 | if not len(oldxy): oldxy = list(newxy) |
---|
| 4777 | dxy = newxy-oldxy |
---|
| 4778 | drawingData['oldxy'] = list(newxy) |
---|
| 4779 | V = drawingData['viewDir'] |
---|
| 4780 | A = [0,0] |
---|
| 4781 | A[0] = dxy[1]*.25 |
---|
| 4782 | A[1] = dxy[0]*.25 |
---|
| 4783 | if newxy[0] > cent[0]: |
---|
| 4784 | A[0] *= -1 |
---|
| 4785 | if newxy[1] < cent[1]: |
---|
| 4786 | A[1] *= -1 |
---|
| 4787 | # next transform vector back to xtal coordinates & make new quaternion |
---|
| 4788 | Q = drawingData['Quaternion'] |
---|
| 4789 | V = np.inner(Amat,V) |
---|
| 4790 | Qx = G2mth.AVdeg2Q(A[0],V) |
---|
| 4791 | Qy = G2mth.AVdeg2Q(A[1],V) |
---|
| 4792 | Q = G2mth.prodQQ(Q,Qx) |
---|
| 4793 | Q = G2mth.prodQQ(Q,Qy) |
---|
| 4794 | drawingData['Quaternion'] = Q |
---|
| 4795 | |
---|
[851] | 4796 | def SetRBRotation(newxy): |
---|
| 4797 | #first get rotation vector in screen coords. & angle increment |
---|
| 4798 | oldxy = drawingData['oldxy'] |
---|
| 4799 | if not len(oldxy): oldxy = list(newxy) |
---|
| 4800 | dxy = newxy-oldxy |
---|
| 4801 | drawingData['oldxy'] = list(newxy) |
---|
| 4802 | V = np.array([dxy[1],dxy[0],0.]) |
---|
| 4803 | A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2) |
---|
| 4804 | # next transform vector back to xtal coordinates via inverse quaternion |
---|
| 4805 | # & make new quaternion |
---|
| 4806 | Q = rbObj['Orient'][0] #rotate RB to Cart |
---|
| 4807 | QC = drawingData['Quaternion'] #rotate Cart to drawing |
---|
| 4808 | V = G2mth.prodQVQ(G2mth.invQ(QC),V) |
---|
| 4809 | V = G2mth.prodQVQ(G2mth.invQ(Q),V) |
---|
| 4810 | DQ = G2mth.AVdeg2Q(A,V) |
---|
| 4811 | Q = G2mth.prodQQ(Q,DQ) |
---|
| 4812 | rbObj['Orient'][0] = Q |
---|
| 4813 | SetRBOrienText() |
---|
| 4814 | |
---|
| 4815 | def SetRBRotationZ(newxy): |
---|
| 4816 | #first get rotation vector (= view vector) in screen coords. & angle increment |
---|
| 4817 | View = glGetIntegerv(GL_VIEWPORT) |
---|
| 4818 | cent = [View[2]/2,View[3]/2] |
---|
| 4819 | oldxy = drawingData['oldxy'] |
---|
| 4820 | if not len(oldxy): oldxy = list(newxy) |
---|
| 4821 | dxy = newxy-oldxy |
---|
| 4822 | drawingData['oldxy'] = list(newxy) |
---|
| 4823 | V = drawingData['viewDir'] |
---|
| 4824 | A = [0,0] |
---|
| 4825 | A[0] = dxy[1]*.25 |
---|
| 4826 | A[1] = dxy[0]*.25 |
---|
| 4827 | if newxy[0] < cent[0]: |
---|
| 4828 | A[0] *= -1 |
---|
| 4829 | if newxy[1] > cent[1]: |
---|
| 4830 | A[1] *= -1 |
---|
| 4831 | # next transform vector back to RB coordinates & make new quaternion |
---|
| 4832 | Q = rbObj['Orient'][0] #rotate RB to cart |
---|
| 4833 | V = np.inner(Amat,V) |
---|
| 4834 | V = -G2mth.prodQVQ(G2mth.invQ(Q),V) |
---|
| 4835 | Qx = G2mth.AVdeg2Q(A[0],V) |
---|
| 4836 | Qy = G2mth.AVdeg2Q(A[1],V) |
---|
| 4837 | Q = G2mth.prodQQ(Q,Qx) |
---|
| 4838 | Q = G2mth.prodQQ(Q,Qy) |
---|
| 4839 | rbObj['Orient'][0] = Q |
---|
| 4840 | SetRBOrienText() |
---|
| 4841 | |
---|
[762] | 4842 | def RenderBox(): |
---|
| 4843 | glEnable(GL_COLOR_MATERIAL) |
---|
| 4844 | glLineWidth(2) |
---|
| 4845 | glEnable(GL_BLEND) |
---|
| 4846 | glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) |
---|
| 4847 | glEnable(GL_LINE_SMOOTH) |
---|
| 4848 | glBegin(GL_LINES) |
---|
| 4849 | for line,color in zip(uEdges,uColors): |
---|
| 4850 | glColor3ubv(color) |
---|
| 4851 | glVertex3fv(line[0]) |
---|
| 4852 | glVertex3fv(line[1]) |
---|
| 4853 | glEnd() |
---|
| 4854 | glColor4ubv([0,0,0,0]) |
---|
| 4855 | glDisable(GL_LINE_SMOOTH) |
---|
| 4856 | glDisable(GL_BLEND) |
---|
| 4857 | glDisable(GL_COLOR_MATERIAL) |
---|
| 4858 | |
---|
| 4859 | def RenderUnitVectors(x,y,z): |
---|
| 4860 | xyz = np.array([x,y,z]) |
---|
| 4861 | glEnable(GL_COLOR_MATERIAL) |
---|
| 4862 | glLineWidth(1) |
---|
| 4863 | glPushMatrix() |
---|
| 4864 | glTranslate(x,y,z) |
---|
| 4865 | glScalef(1/cell[0],1/cell[1],1/cell[2]) |
---|
| 4866 | glBegin(GL_LINES) |
---|
| 4867 | for line,color in zip(uEdges,uColors)[:3]: |
---|
| 4868 | glColor3ubv(color) |
---|
| 4869 | glVertex3fv(-line[1]/2.) |
---|
| 4870 | glVertex3fv(line[1]/2.) |
---|
| 4871 | glEnd() |
---|
| 4872 | glPopMatrix() |
---|
| 4873 | glColor4ubv([0,0,0,0]) |
---|
| 4874 | glDisable(GL_COLOR_MATERIAL) |
---|
| 4875 | |
---|
| 4876 | def RenderSphere(x,y,z,radius,color): |
---|
| 4877 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
| 4878 | glPushMatrix() |
---|
| 4879 | glTranslate(x,y,z) |
---|
| 4880 | glMultMatrixf(B4mat.T) |
---|
| 4881 | q = gluNewQuadric() |
---|
| 4882 | gluSphere(q,radius,20,10) |
---|
| 4883 | glPopMatrix() |
---|
| 4884 | |
---|
| 4885 | def RenderDots(XYZ,RC): |
---|
| 4886 | glEnable(GL_COLOR_MATERIAL) |
---|
| 4887 | XYZ = np.array(XYZ) |
---|
| 4888 | glPushMatrix() |
---|
| 4889 | for xyz,rc in zip(XYZ,RC): |
---|
| 4890 | x,y,z = xyz |
---|
| 4891 | r,c = rc |
---|
| 4892 | glColor3ubv(c) |
---|
| 4893 | glPointSize(r*50) |
---|
| 4894 | glBegin(GL_POINTS) |
---|
| 4895 | glVertex3fv(xyz) |
---|
| 4896 | glEnd() |
---|
| 4897 | glPopMatrix() |
---|
| 4898 | glColor4ubv([0,0,0,0]) |
---|
| 4899 | glDisable(GL_COLOR_MATERIAL) |
---|
| 4900 | |
---|
| 4901 | def RenderSmallSphere(x,y,z,radius,color): |
---|
| 4902 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
| 4903 | glPushMatrix() |
---|
| 4904 | glTranslate(x,y,z) |
---|
| 4905 | glMultMatrixf(B4mat.T) |
---|
| 4906 | q = gluNewQuadric() |
---|
| 4907 | gluSphere(q,radius,4,2) |
---|
| 4908 | glPopMatrix() |
---|
| 4909 | |
---|
| 4910 | def RenderEllipsoid(x,y,z,ellipseProb,E,R4,color): |
---|
| 4911 | s1,s2,s3 = E |
---|
| 4912 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
| 4913 | glPushMatrix() |
---|
| 4914 | glTranslate(x,y,z) |
---|
| 4915 | glMultMatrixf(B4mat.T) |
---|
| 4916 | glMultMatrixf(R4.T) |
---|
| 4917 | glEnable(GL_NORMALIZE) |
---|
| 4918 | glScale(s1,s2,s3) |
---|
| 4919 | q = gluNewQuadric() |
---|
| 4920 | gluSphere(q,ellipseProb,20,10) |
---|
| 4921 | glDisable(GL_NORMALIZE) |
---|
| 4922 | glPopMatrix() |
---|
| 4923 | |
---|
| 4924 | def RenderBonds(x,y,z,Bonds,radius,color,slice=20): |
---|
| 4925 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
| 4926 | glPushMatrix() |
---|
| 4927 | glTranslate(x,y,z) |
---|
| 4928 | glMultMatrixf(B4mat.T) |
---|
| 4929 | for bond in Bonds: |
---|
| 4930 | glPushMatrix() |
---|
| 4931 | Dx = np.inner(Amat,bond) |
---|
| 4932 | Z = np.sqrt(np.sum(Dx**2)) |
---|
| 4933 | if Z: |
---|
| 4934 | azm = atan2d(-Dx[1],-Dx[0]) |
---|
| 4935 | phi = acosd(Dx[2]/Z) |
---|
| 4936 | glRotate(-azm,0,0,1) |
---|
| 4937 | glRotate(phi,1,0,0) |
---|
| 4938 | q = gluNewQuadric() |
---|
| 4939 | gluCylinder(q,radius,radius,Z,slice,2) |
---|
| 4940 | glPopMatrix() |
---|
| 4941 | glPopMatrix() |
---|
| 4942 | |
---|
| 4943 | def RenderLines(x,y,z,Bonds,color): |
---|
[935] | 4944 | glShadeModel(GL_FLAT) |
---|
[762] | 4945 | xyz = np.array([x,y,z]) |
---|
| 4946 | glEnable(GL_COLOR_MATERIAL) |
---|
| 4947 | glLineWidth(1) |
---|
| 4948 | glColor3fv(color) |
---|
| 4949 | glPushMatrix() |
---|
| 4950 | glBegin(GL_LINES) |
---|
| 4951 | for bond in Bonds: |
---|
| 4952 | glVertex3fv(xyz) |
---|
| 4953 | glVertex3fv(xyz+bond) |
---|
| 4954 | glEnd() |
---|
| 4955 | glColor4ubv([0,0,0,0]) |
---|
| 4956 | glPopMatrix() |
---|
| 4957 | glDisable(GL_COLOR_MATERIAL) |
---|
[935] | 4958 | glShadeModel(GL_SMOOTH) |
---|
[762] | 4959 | |
---|
| 4960 | def RenderPolyhedra(x,y,z,Faces,color): |
---|
[961] | 4961 | glShadeModel(GL_FLAT) |
---|
[762] | 4962 | glPushMatrix() |
---|
| 4963 | glTranslate(x,y,z) |
---|
| 4964 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
| 4965 | glShadeModel(GL_SMOOTH) |
---|
| 4966 | glMultMatrixf(B4mat.T) |
---|
| 4967 | for face,norm in Faces: |
---|
| 4968 | glPolygonMode(GL_FRONT_AND_BACK,GL_FILL) |
---|
| 4969 | glFrontFace(GL_CW) |
---|
| 4970 | glNormal3fv(norm) |
---|
| 4971 | glBegin(GL_TRIANGLES) |
---|
| 4972 | for vert in face: |
---|
| 4973 | glVertex3fv(vert) |
---|
| 4974 | glEnd() |
---|
| 4975 | glPopMatrix() |
---|
[961] | 4976 | glShadeModel(GL_SMOOTH) |
---|
[762] | 4977 | |
---|
[766] | 4978 | def RenderMapPeak(x,y,z,color,den): |
---|
[935] | 4979 | glShadeModel(GL_FLAT) |
---|
[762] | 4980 | xyz = np.array([x,y,z]) |
---|
| 4981 | glEnable(GL_COLOR_MATERIAL) |
---|
| 4982 | glLineWidth(3) |
---|
[766] | 4983 | glColor3fv(color*den/255) |
---|
[762] | 4984 | glPushMatrix() |
---|
| 4985 | glBegin(GL_LINES) |
---|
| 4986 | for vec in mapPeakVecs: |
---|
| 4987 | glVertex3fv(vec[0]+xyz) |
---|
| 4988 | glVertex3fv(vec[1]+xyz) |
---|
| 4989 | glEnd() |
---|
| 4990 | glColor4ubv([0,0,0,0]) |
---|
| 4991 | glPopMatrix() |
---|
| 4992 | glDisable(GL_COLOR_MATERIAL) |
---|
[935] | 4993 | glShadeModel(GL_SMOOTH) |
---|
[762] | 4994 | |
---|
| 4995 | def RenderBackbone(Backbone,BackboneColor,radius): |
---|
| 4996 | glPushMatrix() |
---|
| 4997 | glMultMatrixf(B4mat.T) |
---|
| 4998 | glEnable(GL_COLOR_MATERIAL) |
---|
| 4999 | glShadeModel(GL_SMOOTH) |
---|
| 5000 | gleSetJoinStyle(TUBE_NORM_EDGE | TUBE_JN_ANGLE | TUBE_JN_CAP) |
---|
| 5001 | glePolyCylinder(Backbone,BackboneColor,radius) |
---|
| 5002 | glPopMatrix() |
---|
| 5003 | glDisable(GL_COLOR_MATERIAL) |
---|
| 5004 | |
---|
[987] | 5005 | def RenderLabel(x,y,z,label,r,color,matRot): |
---|
| 5006 | ''' |
---|
[1378] | 5007 | color wx.Colour object |
---|
[987] | 5008 | ''' |
---|
[762] | 5009 | glPushMatrix() |
---|
| 5010 | glTranslate(x,y,z) |
---|
| 5011 | glMultMatrixf(B4mat.T) |
---|
| 5012 | glDisable(GL_LIGHTING) |
---|
[935] | 5013 | glRasterPos3f(0,0,0) |
---|
[987] | 5014 | glMultMatrixf(matRot) |
---|
| 5015 | glRotate(180,1,0,0) #fix to flip about x-axis |
---|
| 5016 | text = gltext.Text(text=label,font=Font,foreground=color) |
---|
| 5017 | text.draw_text(scale=0.025) |
---|
[762] | 5018 | glEnable(GL_LIGHTING) |
---|
| 5019 | glPopMatrix() |
---|
| 5020 | |
---|
| 5021 | def RenderMap(rho,rhoXYZ,indx,Rok): |
---|
[935] | 5022 | glShadeModel(GL_FLAT) |
---|
[762] | 5023 | cLevel = drawingData['contourLevel'] |
---|
| 5024 | XYZ = [] |
---|
| 5025 | RC = [] |
---|
| 5026 | for i,xyz in enumerate(rhoXYZ): |
---|
| 5027 | if not Rok[i]: |
---|
| 5028 | x,y,z = xyz |
---|
| 5029 | I,J,K = indx[i] |
---|
| 5030 | alpha = 1.0 |
---|
| 5031 | if cLevel < 1.: |
---|
| 5032 | alpha = (abs(rho[I,J,K])/mapData['rhoMax']-cLevel)/(1.-cLevel) |
---|
| 5033 | if rho[I,J,K] < 0.: |
---|
| 5034 | XYZ.append(xyz) |
---|
| 5035 | RC.append([0.1*alpha,Rd]) |
---|
| 5036 | else: |
---|
| 5037 | XYZ.append(xyz) |
---|
| 5038 | RC.append([0.1*alpha,Gr]) |
---|
| 5039 | RenderDots(XYZ,RC) |
---|
[935] | 5040 | glShadeModel(GL_SMOOTH) |
---|
[762] | 5041 | |
---|
[1958] | 5042 | def Draw(caller='',Fade=None): |
---|
[762] | 5043 | #useful debug? |
---|
| 5044 | # if caller: |
---|
| 5045 | # print caller |
---|
| 5046 | # end of useful debug |
---|
| 5047 | mapData = generalData['Map'] |
---|
| 5048 | pageName = '' |
---|
| 5049 | page = getSelection() |
---|
| 5050 | if page: |
---|
| 5051 | pageName = G2frame.dataDisplay.GetPageText(page) |
---|
| 5052 | rhoXYZ = [] |
---|
| 5053 | if len(mapData['rho']): |
---|
| 5054 | VP = np.array(drawingData['viewPoint'][0])-np.array([.5,.5,.5]) |
---|
| 5055 | contLevel = drawingData['contourLevel']*mapData['rhoMax'] |
---|
[1951] | 5056 | if 'delt-F' in mapData['MapType'] or 'N' in mapData.get('Type',''): |
---|
[762] | 5057 | rho = ma.array(mapData['rho'],mask=(np.abs(mapData['rho'])<contLevel)) |
---|
| 5058 | else: |
---|
| 5059 | rho = ma.array(mapData['rho'],mask=(mapData['rho']<contLevel)) |
---|
| 5060 | steps = 1./np.array(rho.shape) |
---|
| 5061 | incre = np.where(VP>=0,VP%steps,VP%steps-steps) |
---|
| 5062 | Vsteps = -np.array(VP/steps,dtype='i') |
---|
| 5063 | rho = np.roll(np.roll(np.roll(rho,Vsteps[0],axis=0),Vsteps[1],axis=1),Vsteps[2],axis=2) |
---|
| 5064 | indx = np.array(ma.nonzero(rho)).T |
---|
| 5065 | rhoXYZ = indx*steps+VP-incre |
---|
| 5066 | Nc = len(rhoXYZ) |
---|
| 5067 | rcube = 2000.*Vol/(ForthirdPI*Nc) |
---|
| 5068 | rmax = math.exp(math.log(rcube)/3.)**2 |
---|
| 5069 | radius = min(drawingData['mapSize']**2,rmax) |
---|
| 5070 | view = np.array(drawingData['viewPoint'][0]) |
---|
| 5071 | Rok = np.sum(np.inner(Amat,rhoXYZ-view).T**2,axis=1)>radius |
---|
| 5072 | Ind = GetSelectedAtoms() |
---|
| 5073 | VS = np.array(Page.canvas.GetSize()) |
---|
| 5074 | aspect = float(VS[0])/float(VS[1]) |
---|
| 5075 | cPos = drawingData['cameraPos'] |
---|
| 5076 | Zclip = drawingData['Zclip']*cPos/200. |
---|
| 5077 | Q = drawingData['Quaternion'] |
---|
| 5078 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
| 5079 | cx,ct,cs,ci = drawingData['atomPtrs'] |
---|
| 5080 | bondR = drawingData['bondRadius'] |
---|
| 5081 | G,g = G2lat.cell2Gmat(cell) |
---|
| 5082 | GS = G |
---|
| 5083 | GS[0][1] = GS[1][0] = math.sqrt(GS[0][0]*GS[1][1]) |
---|
| 5084 | GS[0][2] = GS[2][0] = math.sqrt(GS[0][0]*GS[2][2]) |
---|
| 5085 | GS[1][2] = GS[2][1] = math.sqrt(GS[1][1]*GS[2][2]) |
---|
| 5086 | ellipseProb = G2lat.criticalEllipse(drawingData['ellipseProb']/100.) |
---|
| 5087 | |
---|
| 5088 | SetBackground() |
---|
| 5089 | glInitNames() |
---|
| 5090 | glPushName(0) |
---|
| 5091 | |
---|
| 5092 | glMatrixMode(GL_PROJECTION) |
---|
| 5093 | glLoadIdentity() |
---|
| 5094 | glViewport(0,0,VS[0],VS[1]) |
---|
| 5095 | gluPerspective(20.,aspect,cPos-Zclip,cPos+Zclip) |
---|
| 5096 | gluLookAt(0,0,cPos,0,0,0,0,1,0) |
---|
| 5097 | SetLights() |
---|
| 5098 | |
---|
| 5099 | glMatrixMode(GL_MODELVIEW) |
---|
| 5100 | glLoadIdentity() |
---|
| 5101 | matRot = G2mth.Q2Mat(Q) |
---|
| 5102 | matRot = np.concatenate((np.concatenate((matRot,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
| 5103 | glMultMatrixf(matRot.T) |
---|
| 5104 | glMultMatrixf(A4mat.T) |
---|
| 5105 | glTranslate(-Tx,-Ty,-Tz) |
---|
| 5106 | if drawingData['unitCellBox']: |
---|
| 5107 | RenderBox() |
---|
| 5108 | if drawingData['showABC']: |
---|
| 5109 | x,y,z = drawingData['viewPoint'][0] |
---|
| 5110 | RenderUnitVectors(x,y,z) |
---|
| 5111 | Backbones = {} |
---|
| 5112 | BackboneColor = [] |
---|
| 5113 | time0 = time.time() |
---|
| 5114 | # glEnable(GL_BLEND) |
---|
| 5115 | # glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) |
---|
[1958] | 5116 | if Fade == None: |
---|
| 5117 | atmFade = np.ones(len(drawingData['Atoms'])) |
---|
| 5118 | else: |
---|
| 5119 | atmFade = Fade |
---|
[762] | 5120 | for iat,atom in enumerate(drawingData['Atoms']): |
---|
| 5121 | x,y,z = atom[cx:cx+3] |
---|
| 5122 | Bonds = atom[-2] |
---|
| 5123 | Faces = atom[-1] |
---|
| 5124 | try: |
---|
| 5125 | atNum = generalData['AtomTypes'].index(atom[ct]) |
---|
| 5126 | except ValueError: |
---|
| 5127 | atNum = -1 |
---|
| 5128 | CL = atom[cs+2] |
---|
[1958] | 5129 | if not atmFade[iat]: |
---|
| 5130 | continue |
---|
| 5131 | atColor = atmFade[iat]*np.array(CL)/255. |
---|
[855] | 5132 | if drawingData['showRigidBodies'] and atom[ci] in rbAtmDict: |
---|
| 5133 | bndColor = Or |
---|
| 5134 | else: |
---|
| 5135 | bndColor = atColor |
---|
[762] | 5136 | if iat in Ind and G2frame.dataDisplay.GetPageText(getSelection()) != 'Map peaks': |
---|
[855] | 5137 | atColor = np.array(Gr)/255. |
---|
[762] | 5138 | # color += [.25,] |
---|
| 5139 | radius = 0.5 |
---|
| 5140 | if atom[cs] != '': |
---|
| 5141 | try: |
---|
| 5142 | glLoadName(atom[-3]) |
---|
| 5143 | except: #problem with old files - missing code |
---|
| 5144 | pass |
---|
| 5145 | if 'balls' in atom[cs]: |
---|
| 5146 | vdwScale = drawingData['vdwScale'] |
---|
| 5147 | ballScale = drawingData['ballScale'] |
---|
| 5148 | if atNum < 0: |
---|
| 5149 | radius = 0.2 |
---|
| 5150 | elif 'H' == atom[ct]: |
---|
| 5151 | if drawingData['showHydrogen']: |
---|
| 5152 | if 'vdW' in atom[cs] and atNum >= 0: |
---|
| 5153 | radius = vdwScale*generalData['vdWRadii'][atNum] |
---|
| 5154 | else: |
---|
| 5155 | radius = ballScale*drawingData['sizeH'] |
---|
| 5156 | else: |
---|
| 5157 | radius = 0.0 |
---|
| 5158 | else: |
---|
| 5159 | if 'vdW' in atom[cs]: |
---|
| 5160 | radius = vdwScale*generalData['vdWRadii'][atNum] |
---|
| 5161 | else: |
---|
| 5162 | radius = ballScale*generalData['BondRadii'][atNum] |
---|
[855] | 5163 | RenderSphere(x,y,z,radius,atColor) |
---|
[762] | 5164 | if 'sticks' in atom[cs]: |
---|
[855] | 5165 | RenderBonds(x,y,z,Bonds,bondR,bndColor) |
---|
[762] | 5166 | elif 'ellipsoids' in atom[cs]: |
---|
[855] | 5167 | RenderBonds(x,y,z,Bonds,bondR,bndColor) |
---|
[762] | 5168 | if atom[cs+3] == 'A': |
---|
| 5169 | Uij = atom[cs+5:cs+11] |
---|
| 5170 | U = np.multiply(G2spc.Uij2U(Uij),GS) |
---|
| 5171 | U = np.inner(Amat,np.inner(U,Amat).T) |
---|
| 5172 | E,R = nl.eigh(U) |
---|
| 5173 | R4 = np.concatenate((np.concatenate((R,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
| 5174 | E = np.sqrt(E) |
---|
| 5175 | if atom[ct] == 'H' and not drawingData['showHydrogen']: |
---|
| 5176 | pass |
---|
| 5177 | else: |
---|
[855] | 5178 | RenderEllipsoid(x,y,z,ellipseProb,E,R4,atColor) |
---|
[762] | 5179 | else: |
---|
| 5180 | if atom[ct] == 'H' and not drawingData['showHydrogen']: |
---|
| 5181 | pass |
---|
| 5182 | else: |
---|
| 5183 | radius = ellipseProb*math.sqrt(abs(atom[cs+4])) |
---|
[855] | 5184 | RenderSphere(x,y,z,radius,atColor) |
---|
[762] | 5185 | elif 'lines' in atom[cs]: |
---|
| 5186 | radius = 0.1 |
---|
[855] | 5187 | RenderLines(x,y,z,Bonds,bndColor) |
---|
[762] | 5188 | # RenderBonds(x,y,z,Bonds,0.05,color,6) |
---|
| 5189 | elif atom[cs] == 'sticks': |
---|
| 5190 | radius = 0.1 |
---|
[855] | 5191 | RenderBonds(x,y,z,Bonds,bondR,bndColor) |
---|
[762] | 5192 | elif atom[cs] == 'polyhedra': |
---|
[855] | 5193 | RenderPolyhedra(x,y,z,Faces,atColor) |
---|
[762] | 5194 | elif atom[cs] == 'backbone': |
---|
| 5195 | if atom[ct-1].split()[0] in ['C','N']: |
---|
| 5196 | if atom[2] not in Backbones: |
---|
| 5197 | Backbones[atom[2]] = [] |
---|
| 5198 | Backbones[atom[2]].append(list(np.inner(Amat,np.array([x,y,z])))) |
---|
[855] | 5199 | BackboneColor.append(list(atColor)) |
---|
[762] | 5200 | |
---|
| 5201 | if atom[cs+1] == 'type': |
---|
[987] | 5202 | RenderLabel(x,y,z,' '+atom[ct],radius,wxGreen,matRot) |
---|
[762] | 5203 | elif atom[cs+1] == 'name': |
---|
[987] | 5204 | RenderLabel(x,y,z,' '+atom[ct-1],radius,wxGreen,matRot) |
---|
[762] | 5205 | elif atom[cs+1] == 'number': |
---|
[987] | 5206 | RenderLabel(x,y,z,' '+str(iat),radius,wxGreen,matRot) |
---|
[762] | 5207 | elif atom[cs+1] == 'residue' and atom[ct-1] == 'CA': |
---|
[987] | 5208 | RenderLabel(x,y,z,' '+atom[ct-4],radius,wxGreen,matRot) |
---|
[762] | 5209 | elif atom[cs+1] == '1-letter' and atom[ct-1] == 'CA': |
---|
[987] | 5210 | RenderLabel(x,y,z,' '+atom[ct-3],radius,wxGreen,matRot) |
---|
[762] | 5211 | elif atom[cs+1] == 'chain' and atom[ct-1] == 'CA': |
---|
[987] | 5212 | RenderLabel(x,y,z,' '+atom[ct-2],radius,wxGreen,matRot) |
---|
[762] | 5213 | # glDisable(GL_BLEND) |
---|
| 5214 | if len(rhoXYZ): |
---|
| 5215 | RenderMap(rho,rhoXYZ,indx,Rok) |
---|
| 5216 | if len(mapPeaks): |
---|
[839] | 5217 | XYZ = mapPeaks.T[1:4].T |
---|
| 5218 | mapBonds = FindPeaksBonds(XYZ) |
---|
[1669] | 5219 | for ind,[mag,x,y,z] in enumerate(mapPeaks[:,:4]): |
---|
[762] | 5220 | if ind in Ind and pageName == 'Map peaks': |
---|
[766] | 5221 | RenderMapPeak(x,y,z,Gr,1.0) |
---|
[762] | 5222 | else: |
---|
[1646] | 5223 | if mag > 0.: |
---|
| 5224 | RenderMapPeak(x,y,z,Wt,mag/peakMax) |
---|
| 5225 | else: |
---|
| 5226 | RenderMapPeak(x,y,z,Rd,-mag/peakMax) |
---|
[840] | 5227 | if showBonds: |
---|
| 5228 | RenderLines(x,y,z,mapBonds[ind],Wt) |
---|
[851] | 5229 | if len(testRBObj) and pageName == 'RB Models': |
---|
[885] | 5230 | XYZ = G2mth.UpdateRBXYZ(Bmat,testRBObj['rbObj'],testRBObj['rbData'],testRBObj['rbType'])[0] |
---|
[851] | 5231 | rbBonds = FindPeaksBonds(XYZ) |
---|
| 5232 | for ind,[x,y,z] in enumerate(XYZ): |
---|
| 5233 | aType = testRBObj['rbAtTypes'][ind] |
---|
[935] | 5234 | name = ' '+aType+str(ind) |
---|
[851] | 5235 | color = np.array(testRBObj['AtInfo'][aType][1]) |
---|
| 5236 | RenderSphere(x,y,z,0.2,color/255.) |
---|
| 5237 | RenderBonds(x,y,z,rbBonds[ind],0.03,Gr) |
---|
[987] | 5238 | RenderLabel(x,y,z,name,0.2,wxOrange,matRot) |
---|
[934] | 5239 | if len(mcsaModels) > 1 and pageName == 'MC/SA': #skip the default MD entry |
---|
[951] | 5240 | for ind,[x,y,z] in enumerate(mcsaXYZ): |
---|
[953] | 5241 | aType = mcsaTypes[ind] |
---|
[935] | 5242 | name = ' '+aType+str(ind) |
---|
[934] | 5243 | color = np.array(MCSA['AtInfo'][aType][1]) |
---|
| 5244 | RenderSphere(x,y,z,0.2,color/255.) |
---|
[951] | 5245 | RenderBonds(x,y,z,mcsaBonds[ind],0.03,Gr) |
---|
[987] | 5246 | RenderLabel(x,y,z,name,0.2,wxOrange,matRot) |
---|
[762] | 5247 | if Backbones: |
---|
| 5248 | for chain in Backbones: |
---|
| 5249 | Backbone = Backbones[chain] |
---|
| 5250 | RenderBackbone(Backbone,BackboneColor,bondR) |
---|
| 5251 | # print time.time()-time0 |
---|
[1379] | 5252 | if Page.context: Page.canvas.SetCurrent(Page.context) # wx 2.9 fix |
---|
[762] | 5253 | Page.canvas.SwapBuffers() |
---|
[1379] | 5254 | |
---|
[762] | 5255 | def OnSize(event): |
---|
| 5256 | Draw('size') |
---|
| 5257 | |
---|
| 5258 | def OnFocus(event): #not needed?? Bind commented out below |
---|
| 5259 | Draw('focus') |
---|
| 5260 | |
---|
[1383] | 5261 | # PlotStructure execution starts here (N.B. initialization above) |
---|
[762] | 5262 | try: |
---|
| 5263 | plotNum = G2frame.G2plotNB.plotList.index(generalData['Name']) |
---|
[1448] | 5264 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
[762] | 5265 | except ValueError: |
---|
| 5266 | Plot = G2frame.G2plotNB.addOgl(generalData['Name']) |
---|
| 5267 | plotNum = G2frame.G2plotNB.plotList.index(generalData['Name']) |
---|
| 5268 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 5269 | Page.views = False |
---|
| 5270 | view = False |
---|
| 5271 | altDown = False |
---|
[1448] | 5272 | G2frame.G2plotNB.nb.SetSelection(plotNum) # make sure plot tab is raised for wx >2.8 |
---|
[985] | 5273 | Font = Page.GetFont() |
---|
[762] | 5274 | Page.SetFocus() |
---|
[796] | 5275 | Page.Choice = None |
---|
[1439] | 5276 | if mapData.get('Flip',False): |
---|
[993] | 5277 | choice = [' save as/key:','jpeg','tiff','bmp','c: center on 1/2,1/2,1/2', |
---|
| 5278 | 'u: roll up','d: roll down','l: roll left','r: roll right'] |
---|
[762] | 5279 | else: |
---|
| 5280 | choice = [' save as/key:','jpeg','tiff','bmp','c: center on 1/2,1/2,1/2','n: next','p: previous'] |
---|
[1633] | 5281 | if generalData['Type'] in ['modulated','magnetic',] and len(drawAtoms): |
---|
| 5282 | choice += ['+: increase tau','-: decrease tau','0: set tau = 0'] |
---|
| 5283 | |
---|
[1928] | 5284 | Tx,Ty,Tz = drawingData['viewPoint'][0] |
---|
| 5285 | rho = G2mth.getRho([Tx,Ty,Tz],mapData) |
---|
| 5286 | G2frame.G2plotNB.status.SetStatusText('View point: %.4f, %.4f, %.4f; density: %.4f'%(Tx,Ty,Tz,rho),1) |
---|
| 5287 | |
---|
[762] | 5288 | cb = wx.ComboBox(G2frame.G2plotNB.status,style=wx.CB_DROPDOWN|wx.CB_READONLY,choices=choice) |
---|
| 5289 | cb.Bind(wx.EVT_COMBOBOX, OnKeyBox) |
---|
| 5290 | cb.SetValue(' save as/key:') |
---|
| 5291 | Page.canvas.Bind(wx.EVT_MOUSEWHEEL, OnMouseWheel) |
---|
| 5292 | Page.canvas.Bind(wx.EVT_LEFT_DOWN, OnMouseDown) |
---|
| 5293 | Page.canvas.Bind(wx.EVT_RIGHT_DOWN, OnMouseDown) |
---|
| 5294 | Page.canvas.Bind(wx.EVT_MIDDLE_DOWN, OnMouseDown) |
---|
| 5295 | Page.canvas.Bind(wx.EVT_KEY_UP, OnKey) |
---|
[1951] | 5296 | Page.canvas.Bind(wx.EVT_KEY_DOWN,OnKeyPressed) |
---|
[762] | 5297 | Page.canvas.Bind(wx.EVT_MOTION, OnMouseMove) |
---|
| 5298 | Page.canvas.Bind(wx.EVT_SIZE, OnSize) |
---|
| 5299 | # Page.canvas.Bind(wx.EVT_SET_FOCUS, OnFocus) |
---|
| 5300 | Page.camera['position'] = drawingData['cameraPos'] |
---|
| 5301 | Page.camera['viewPoint'] = np.inner(Amat,drawingData['viewPoint'][0]) |
---|
[1559] | 5302 | Page.camera['backColor'] = backColor/255. |
---|
[859] | 5303 | try: |
---|
| 5304 | Page.canvas.SetCurrent() |
---|
| 5305 | except: |
---|
| 5306 | pass |
---|
[762] | 5307 | Draw('main') |
---|
[1381] | 5308 | if firstCall: Draw('main') # draw twice the first time that graphics are displayed |
---|
| 5309 | |
---|
[831] | 5310 | ################################################################################ |
---|
| 5311 | #### Plot Rigid Body |
---|
| 5312 | ################################################################################ |
---|
| 5313 | |
---|
[835] | 5314 | def PlotRigidBody(G2frame,rbType,AtInfo,rbData,defaults): |
---|
[831] | 5315 | '''RB plotting package. Can show rigid body structures as balls & sticks |
---|
| 5316 | ''' |
---|
| 5317 | |
---|
[839] | 5318 | def FindBonds(XYZ): |
---|
[831] | 5319 | rbTypes = rbData['rbTypes'] |
---|
| 5320 | Radii = [] |
---|
| 5321 | for Atype in rbTypes: |
---|
| 5322 | Radii.append(AtInfo[Atype][0]) |
---|
[854] | 5323 | if Atype == 'H': |
---|
| 5324 | Radii[-1] = 0.5 |
---|
[831] | 5325 | Radii = np.array(Radii) |
---|
| 5326 | Bonds = [[] for i in range(len(Radii))] |
---|
| 5327 | for i,xyz in enumerate(XYZ): |
---|
| 5328 | Dx = XYZ-xyz |
---|
| 5329 | dist = np.sqrt(np.sum(Dx**2,axis=1)) |
---|
| 5330 | sumR = Radii[i]+Radii |
---|
| 5331 | IndB = ma.nonzero(ma.masked_greater(dist-0.85*sumR,0.)) |
---|
| 5332 | for j in IndB[0]: |
---|
| 5333 | Bonds[i].append(Dx[j]*Radii[i]/sumR[j]) |
---|
| 5334 | Bonds[j].append(-Dx[j]*Radii[j]/sumR[j]) |
---|
| 5335 | return Bonds |
---|
| 5336 | |
---|
| 5337 | Wt = np.array([255,255,255]) |
---|
| 5338 | Rd = np.array([255,0,0]) |
---|
| 5339 | Gr = np.array([0,255,0]) |
---|
| 5340 | Bl = np.array([0,0,255]) |
---|
| 5341 | uBox = np.array([[0,0,0],[1,0,0],[0,1,0],[0,0,1]]) |
---|
| 5342 | uEdges = np.array([[uBox[0],uBox[1]],[uBox[0],uBox[2]],[uBox[0],uBox[3]]]) |
---|
| 5343 | uColors = [Rd,Gr,Bl] |
---|
| 5344 | if rbType == 'Vector': |
---|
[836] | 5345 | atNames = [str(i)+':'+Ty for i,Ty in enumerate(rbData['rbTypes'])] |
---|
[831] | 5346 | XYZ = np.array([[0.,0.,0.] for Ty in rbData['rbTypes']]) |
---|
| 5347 | for imag,mag in enumerate(rbData['VectMag']): |
---|
| 5348 | XYZ += mag*rbData['rbVect'][imag] |
---|
[835] | 5349 | Bonds = FindBonds(XYZ) |
---|
[831] | 5350 | elif rbType == 'Residue': |
---|
[934] | 5351 | # atNames = [str(i)+':'+Ty for i,Ty in enumerate(rbData['atNames'])] |
---|
| 5352 | atNames = rbData['atNames'] |
---|
[836] | 5353 | XYZ = np.copy(rbData['rbXYZ']) #don't mess with original! |
---|
| 5354 | Seq = rbData['rbSeq'] |
---|
[840] | 5355 | for ia,ib,ang,mv in Seq: |
---|
| 5356 | va = XYZ[ia]-XYZ[ib] |
---|
| 5357 | Q = G2mth.AVdeg2Q(ang,va) |
---|
| 5358 | for im in mv: |
---|
| 5359 | vb = XYZ[im]-XYZ[ib] |
---|
| 5360 | vb = G2mth.prodQVQ(Q,vb) |
---|
| 5361 | XYZ[im] = XYZ[ib]+vb |
---|
[836] | 5362 | Bonds = FindBonds(XYZ) |
---|
[831] | 5363 | elif rbType == 'Z-matrix': |
---|
| 5364 | pass |
---|
| 5365 | |
---|
[860] | 5366 | # def SetRBOrigin(): |
---|
| 5367 | # page = getSelection() |
---|
| 5368 | # if page: |
---|
| 5369 | # if G2frame.dataDisplay.GetPageText(page) == 'Rigid bodies': |
---|
| 5370 | # G2frame.MapPeaksTable.SetData(mapPeaks) |
---|
| 5371 | # panel = G2frame.dataDisplay.GetPage(page).GetChildren() |
---|
| 5372 | # names = [child.GetName() for child in panel] |
---|
| 5373 | # panel[names.index('grid window')].Refresh() |
---|
| 5374 | |
---|
[831] | 5375 | def OnMouseDown(event): |
---|
| 5376 | xy = event.GetPosition() |
---|
| 5377 | defaults['oldxy'] = list(xy) |
---|
| 5378 | |
---|
| 5379 | def OnMouseMove(event): |
---|
| 5380 | newxy = event.GetPosition() |
---|
| 5381 | |
---|
| 5382 | if event.Dragging(): |
---|
| 5383 | if event.LeftIsDown(): |
---|
| 5384 | SetRotation(newxy) |
---|
| 5385 | Q = defaults['Quaternion'] |
---|
| 5386 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
[860] | 5387 | # elif event.RightIsDown(): |
---|
| 5388 | # SetRBOrigin(newxy) |
---|
[831] | 5389 | elif event.MiddleIsDown(): |
---|
| 5390 | SetRotationZ(newxy) |
---|
| 5391 | Q = defaults['Quaternion'] |
---|
| 5392 | G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1) |
---|
| 5393 | Draw('move') |
---|
| 5394 | |
---|
| 5395 | def OnMouseWheel(event): |
---|
| 5396 | defaults['cameraPos'] += event.GetWheelRotation()/24 |
---|
| 5397 | defaults['cameraPos'] = max(10,min(500,defaults['cameraPos'])) |
---|
| 5398 | G2frame.G2plotNB.status.SetStatusText('New camera distance: %.2f'%(defaults['cameraPos']),1) |
---|
| 5399 | Draw('wheel') |
---|
| 5400 | |
---|
| 5401 | def SetBackground(): |
---|
| 5402 | R,G,B,A = Page.camera['backColor'] |
---|
| 5403 | glClearColor(R,G,B,A) |
---|
| 5404 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
---|
| 5405 | |
---|
| 5406 | def SetLights(): |
---|
| 5407 | glEnable(GL_DEPTH_TEST) |
---|
[934] | 5408 | glShadeModel(GL_FLAT) |
---|
[831] | 5409 | glEnable(GL_LIGHTING) |
---|
| 5410 | glEnable(GL_LIGHT0) |
---|
| 5411 | glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0) |
---|
| 5412 | glLightfv(GL_LIGHT0,GL_AMBIENT,[1,1,1,.8]) |
---|
| 5413 | glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1]) |
---|
| 5414 | |
---|
[860] | 5415 | # def SetRBOrigin(newxy): |
---|
| 5416 | ##first get translation vector in screen coords. |
---|
| 5417 | # oldxy = defaults['oldxy'] |
---|
| 5418 | # if not len(oldxy): oldxy = list(newxy) |
---|
| 5419 | # dxy = newxy-oldxy |
---|
| 5420 | # defaults['oldxy'] = list(newxy) |
---|
| 5421 | # V = np.array([dxy[0],-dxy[1],0.])/100. |
---|
| 5422 | # Q = defaults['Quaternion'] |
---|
| 5423 | # V = G2mth.prodQVQ(G2mth.invQ(Q),V) |
---|
| 5424 | # rbData['rbXYZ'] += V |
---|
| 5425 | # PlotRigidBody(G2frame,rbType,AtInfo,rbData,defaults) |
---|
| 5426 | # |
---|
[831] | 5427 | def SetRotation(newxy): |
---|
| 5428 | #first get rotation vector in screen coords. & angle increment |
---|
| 5429 | oldxy = defaults['oldxy'] |
---|
| 5430 | if not len(oldxy): oldxy = list(newxy) |
---|
| 5431 | dxy = newxy-oldxy |
---|
| 5432 | defaults['oldxy'] = list(newxy) |
---|
| 5433 | V = np.array([dxy[1],dxy[0],0.]) |
---|
| 5434 | A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2) |
---|
| 5435 | # next transform vector back to xtal coordinates via inverse quaternion |
---|
| 5436 | # & make new quaternion |
---|
| 5437 | Q = defaults['Quaternion'] |
---|
| 5438 | V = G2mth.prodQVQ(G2mth.invQ(Q),V) |
---|
| 5439 | DQ = G2mth.AVdeg2Q(A,V) |
---|
| 5440 | Q = G2mth.prodQQ(Q,DQ) |
---|
| 5441 | defaults['Quaternion'] = Q |
---|
| 5442 | # finally get new view vector - last row of rotation matrix |
---|
| 5443 | VD = G2mth.Q2Mat(Q)[2] |
---|
| 5444 | VD /= np.sqrt(np.sum(VD**2)) |
---|
| 5445 | defaults['viewDir'] = VD |
---|
| 5446 | |
---|
| 5447 | def SetRotationZ(newxy): |
---|
| 5448 | #first get rotation vector (= view vector) in screen coords. & angle increment |
---|
| 5449 | View = glGetIntegerv(GL_VIEWPORT) |
---|
| 5450 | cent = [View[2]/2,View[3]/2] |
---|
| 5451 | oldxy = defaults['oldxy'] |
---|
| 5452 | if not len(oldxy): oldxy = list(newxy) |
---|
| 5453 | dxy = newxy-oldxy |
---|
| 5454 | defaults['oldxy'] = list(newxy) |
---|
| 5455 | V = defaults['viewDir'] |
---|
| 5456 | A = [0,0] |
---|
| 5457 | A[0] = dxy[1]*.25 |
---|
| 5458 | A[1] = dxy[0]*.25 |
---|
| 5459 | if newxy[0] > cent[0]: |
---|
| 5460 | A[0] *= -1 |
---|
| 5461 | if newxy[1] < cent[1]: |
---|
| 5462 | A[1] *= -1 |
---|
| 5463 | # next transform vector back to xtal coordinates & make new quaternion |
---|
| 5464 | Q = defaults['Quaternion'] |
---|
| 5465 | Qx = G2mth.AVdeg2Q(A[0],V) |
---|
| 5466 | Qy = G2mth.AVdeg2Q(A[1],V) |
---|
| 5467 | Q = G2mth.prodQQ(Q,Qx) |
---|
| 5468 | Q = G2mth.prodQQ(Q,Qy) |
---|
| 5469 | defaults['Quaternion'] = Q |
---|
| 5470 | |
---|
| 5471 | def RenderUnitVectors(x,y,z): |
---|
| 5472 | xyz = np.array([x,y,z]) |
---|
| 5473 | glEnable(GL_COLOR_MATERIAL) |
---|
| 5474 | glLineWidth(1) |
---|
| 5475 | glPushMatrix() |
---|
| 5476 | glTranslate(x,y,z) |
---|
| 5477 | glBegin(GL_LINES) |
---|
| 5478 | for line,color in zip(uEdges,uColors): |
---|
| 5479 | glColor3ubv(color) |
---|
| 5480 | glVertex3fv(-line[1]) |
---|
| 5481 | glVertex3fv(line[1]) |
---|
| 5482 | glEnd() |
---|
| 5483 | glPopMatrix() |
---|
| 5484 | glColor4ubv([0,0,0,0]) |
---|
| 5485 | glDisable(GL_COLOR_MATERIAL) |
---|
| 5486 | |
---|
| 5487 | def RenderSphere(x,y,z,radius,color): |
---|
| 5488 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
| 5489 | glPushMatrix() |
---|
| 5490 | glTranslate(x,y,z) |
---|
| 5491 | q = gluNewQuadric() |
---|
| 5492 | gluSphere(q,radius,20,10) |
---|
| 5493 | glPopMatrix() |
---|
| 5494 | |
---|
| 5495 | def RenderBonds(x,y,z,Bonds,radius,color,slice=20): |
---|
| 5496 | glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color) |
---|
| 5497 | glPushMatrix() |
---|
| 5498 | glTranslate(x,y,z) |
---|
| 5499 | for Dx in Bonds: |
---|
| 5500 | glPushMatrix() |
---|
| 5501 | Z = np.sqrt(np.sum(Dx**2)) |
---|
| 5502 | if Z: |
---|
| 5503 | azm = atan2d(-Dx[1],-Dx[0]) |
---|
| 5504 | phi = acosd(Dx[2]/Z) |
---|
| 5505 | glRotate(-azm,0,0,1) |
---|
| 5506 | glRotate(phi,1,0,0) |
---|
| 5507 | q = gluNewQuadric() |
---|
| 5508 | gluCylinder(q,radius,radius,Z,slice,2) |
---|
| 5509 | glPopMatrix() |
---|
| 5510 | glPopMatrix() |
---|
| 5511 | |
---|
[987] | 5512 | def RenderLabel(x,y,z,label,matRot): |
---|
[831] | 5513 | glPushMatrix() |
---|
| 5514 | glTranslate(x,y,z) |
---|
| 5515 | glDisable(GL_LIGHTING) |
---|
[935] | 5516 | glRasterPos3f(0,0,0) |
---|
[987] | 5517 | glMultMatrixf(matRot) |
---|
| 5518 | glRotate(180,1,0,0) #fix to flip about x-axis |
---|
| 5519 | text = gltext.TextElement(text=label,font=Font,foreground=wx.WHITE) |
---|
| 5520 | text.draw_text(scale=0.025) |
---|
[831] | 5521 | glEnable(GL_LIGHTING) |
---|
| 5522 | glPopMatrix() |
---|
| 5523 | |
---|
| 5524 | def Draw(caller=''): |
---|
| 5525 | #useful debug? |
---|
| 5526 | # if caller: |
---|
| 5527 | # print caller |
---|
| 5528 | # end of useful debug |
---|
| 5529 | cPos = defaults['cameraPos'] |
---|
| 5530 | VS = np.array(Page.canvas.GetSize()) |
---|
| 5531 | aspect = float(VS[0])/float(VS[1]) |
---|
| 5532 | Zclip = 500.0 |
---|
| 5533 | Q = defaults['Quaternion'] |
---|
| 5534 | SetBackground() |
---|
| 5535 | glInitNames() |
---|
| 5536 | glPushName(0) |
---|
| 5537 | |
---|
| 5538 | glMatrixMode(GL_PROJECTION) |
---|
| 5539 | glLoadIdentity() |
---|
| 5540 | glViewport(0,0,VS[0],VS[1]) |
---|
[1054] | 5541 | gluPerspective(20.,aspect,1.,500.) |
---|
[831] | 5542 | gluLookAt(0,0,cPos,0,0,0,0,1,0) |
---|
| 5543 | SetLights() |
---|
| 5544 | |
---|
| 5545 | glMatrixMode(GL_MODELVIEW) |
---|
| 5546 | glLoadIdentity() |
---|
| 5547 | matRot = G2mth.Q2Mat(Q) |
---|
| 5548 | matRot = np.concatenate((np.concatenate((matRot,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0) |
---|
| 5549 | glMultMatrixf(matRot.T) |
---|
| 5550 | RenderUnitVectors(0.,0.,0.) |
---|
[934] | 5551 | radius = 0.2 |
---|
[831] | 5552 | for iat,atom in enumerate(XYZ): |
---|
| 5553 | x,y,z = atom |
---|
[835] | 5554 | CL = AtInfo[rbData['rbTypes'][iat]][1] |
---|
[831] | 5555 | color = np.array(CL)/255. |
---|
| 5556 | RenderSphere(x,y,z,radius,color) |
---|
[934] | 5557 | RenderBonds(x,y,z,Bonds[iat],0.05,color) |
---|
[987] | 5558 | RenderLabel(x,y,z,' '+atNames[iat],matRot) |
---|
[1379] | 5559 | if Page.context: Page.canvas.SetCurrent(Page.context) # wx 2.9 fix |
---|
[831] | 5560 | Page.canvas.SwapBuffers() |
---|
| 5561 | |
---|
| 5562 | def OnSize(event): |
---|
| 5563 | Draw('size') |
---|
| 5564 | |
---|
| 5565 | try: |
---|
[837] | 5566 | plotNum = G2frame.G2plotNB.plotList.index('Rigid body') |
---|
[831] | 5567 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 5568 | except ValueError: |
---|
[837] | 5569 | Plot = G2frame.G2plotNB.addOgl('Rigid body') |
---|
| 5570 | plotNum = G2frame.G2plotNB.plotList.index('Rigid body') |
---|
[831] | 5571 | Page = G2frame.G2plotNB.nb.GetPage(plotNum) |
---|
| 5572 | Page.views = False |
---|
| 5573 | view = False |
---|
| 5574 | altDown = False |
---|
| 5575 | Page.SetFocus() |
---|
[985] | 5576 | Font = Page.GetFont() |
---|
[831] | 5577 | Page.canvas.Bind(wx.EVT_MOUSEWHEEL, OnMouseWheel) |
---|
| 5578 | Page.canvas.Bind(wx.EVT_LEFT_DOWN, OnMouseDown) |
---|
| 5579 | Page.canvas.Bind(wx.EVT_RIGHT_DOWN, OnMouseDown) |
---|
| 5580 | Page.canvas.Bind(wx.EVT_MIDDLE_DOWN, OnMouseDown) |
---|
| 5581 | Page.canvas.Bind(wx.EVT_MOTION, OnMouseMove) |
---|
| 5582 | Page.canvas.Bind(wx.EVT_SIZE, OnSize) |
---|
| 5583 | Page.camera['position'] = defaults['cameraPos'] |
---|
| 5584 | Page.camera['backColor'] = np.array([0,0,0,0]) |
---|
| 5585 | Page.canvas.SetCurrent() |
---|
| 5586 | Draw('main') |
---|