# -*- coding: utf-8 -*- #GSASII - phase data display routines ########### SVN repository information ################### # $Date: 2013-05-17 22:24:47 +0000 (Fri, 17 May 2013) $ # $Author: toby $ # $Revision: 924 $ # $URL: trunk/GSASIIphsGUI.py $ # $Id: GSASIIphsGUI.py 924 2013-05-17 22:24:47Z toby $ ########### SVN repository information ################### ''' *GSASIIphsGUI: Phase GUI* ------------------------- Module to create the GUI for display of phase information in the data display window when a phase is selected. (pages displayed in response to some phase tabs are done in other modules, such as GSASIIddata.) ''' import wx import wx.grid as wg import wx.lib.gridmovers as wgmove import wx.wizard as wz import matplotlib as mpl import math import copy import time import sys import random as ran import cPickle import GSASIIpath GSASIIpath.SetVersionNumber("$Revision: 924 $") import GSASIIlattice as G2lat import GSASIIspc as G2spc import GSASIIElem as G2elem import GSASIIElemGUI as G2elemGUI import GSASIIddataGUI as G2ddG import GSASIIplot as G2plt import GSASIIgrid as G2gd import GSASIIIO as G2IO import GSASIIstruct as G2str import GSASIImath as G2mth import GSASIIpwd as G2pwd import numpy as np import numpy.linalg as nl import numpy.ma as ma VERY_LIGHT_GREY = wx.Colour(235,235,235) WHITE = wx.Colour(255,255,255) BLACK = wx.Colour(0,0,0) mapDefault = {'MapType':'','RefList':'','Resolution':0.5,'Show bonds':True, 'rho':[],'rhoMax':0.,'mapSize':10.0,'cutOff':50.,'Flip':False} # trig functions in degrees sind = lambda x: np.sin(x*np.pi/180.) tand = lambda x: np.tan(x*np.pi/180.) cosd = lambda x: np.cos(x*np.pi/180.) asind = lambda x: 180.*np.arcsin(x)/np.pi acosd = lambda x: 180.*np.arccos(x)/np.pi def UpdatePhaseData(G2frame,Item,data,oldPage): '''Create the data display window contents when a phase is clicked on in the man (data tree) window. Called only from :mod:`GSASIIgrid.MovePatternTreeToGrid`, which in turn is called from :mod:`GSASII.GSASII.OnPatternTreeSelChanged` when a tree item is selected. :param wx.frame G2frame: the main GSAS-II frame object :param wx.TreeItemId Item: the tree item that was selected :param dict data: all the information on the phase in a dictionary :param int oldPage: This sets a tab to select when moving from one phase to another, in which case the same tab is selected to display first. This is set only when the previous data tree selection is a phase, if not the value is None. The default action is to bring up the General tab. ''' #patch if 'RBModels' not in data: data['RBModels'] = {} #end patch global rbAtmDict rbAtmDict = {} if G2frame.dataDisplay: G2frame.dataDisplay.Destroy() PhaseName = G2frame.PatternTree.GetItemText(Item) G2gd.SetDataMenuBar(G2frame) G2frame.dataFrame.SetLabel('Phase Data for '+PhaseName) G2frame.dataFrame.CreateStatusBar() G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize()) def SetupGeneral(): generalData = data['General'] atomData = data['Atoms'] generalData['AtomTypes'] = [] generalData['Isotopes'] = {} # various patches if 'Isotope' not in generalData: generalData['Isotope'] = {} if 'Data plot type' not in generalData: generalData['Data plot type'] = 'Mustrain' if 'POhkl' not in generalData: generalData['POhkl'] = [0,0,1] if 'Map' not in generalData: generalData['Map'] = mapDefault if 'Flip' not in generalData: generalData['Flip'] = {'RefList':'','Resolution':0.5,'Norm element':'None', 'k-factor':0.1,'k-Max':20.} if 'doPawley' not in generalData: generalData['doPawley'] = False if 'Pawley dmin' not in generalData: generalData['Pawley dmin'] = 1.0 if 'Pawley neg wt' not in generalData: generalData['Pawley neg wt'] = 0.0 if 'MCSA controls' not in generalData: generalData['MCSA controls'] = {'Data source':'','Annealing':[50.0,0.001,0.90,1000], 'dmin':2.0,'Algolrithm':'Normal','Jump coeff':[0.95,0.5]} #'Normal','Random jump','Tremayne jump' # end of patches generalData['NoAtoms'] = {} generalData['BondRadii'] = [] generalData['AngleRadii'] = [] generalData['vdWRadii'] = [] generalData['AtomMass'] = [] generalData['Color'] = [] generalData['Mydir'] = G2frame.dirname cx,ct,cs,cia = [3,1,7,9] if generalData['Type'] =='macromolecular': cx,ct,cs,cia = [6,4,10,12] generalData['AtomPtrs'] = [cx,ct,cs,cia] for atom in atomData: atom[ct] = atom[ct].lower().capitalize() #force to standard form if generalData['AtomTypes'].count(atom[ct]): generalData['NoAtoms'][atom[ct]] += atom[cs-1]*float(atom[cs+1]) elif atom[ct] != 'UNK': Info = G2elem.GetAtomInfo(atom[ct]) generalData['AtomTypes'].append(atom[ct]) generalData['Z'] = Info['Z'] generalData['Isotopes'][atom[ct]] = Info['Isotopes'] generalData['BondRadii'].append(Info['Drad']) generalData['AngleRadii'].append(Info['Arad']) generalData['vdWRadii'].append(Info['Vdrad']) if atom[ct] in generalData['Isotope']: generalData['AtomMass'].append(Info['Isotopes'][generalData['Isotope'][atom[ct]]][0]) else: generalData['Isotope'][atom[ct]] = 'Nat. Abund.' generalData['AtomMass'].append(Info['Mass']) generalData['NoAtoms'][atom[ct]] = atom[cs-1]*float(atom[cs+1]) generalData['Color'].append(Info['Color']) F000X = 0. F000N = 0. for i,elem in enumerate(generalData['AtomTypes']): F000X += generalData['NoAtoms'][elem]*generalData['Z'] isotope = generalData['Isotope'][elem] F000N += generalData['NoAtoms'][elem]*generalData['Isotopes'][elem][isotope][1] generalData['F000X'] = F000X generalData['F000N'] = F000N ################################################################################ ##### General phase routines ################################################################################ def UpdateGeneral(): '''Draw the controls for the General phase data subpage ''' """ This is the default dictionary structure for phase data (taken from GSASII.py) 'General':{ 'Name':PhaseName 'Type':'nuclear' 'SGData':SGData 'Cell':[False,10.,10.,10.,90.,90.,90,1000.] 'AtomPtrs':[] 'Histogram list':['',] 'Pawley dmin':1.0, 'Pawley neg wt':0.0} 'Atoms':[] 'Drawing':{} """ # UpdateGeneral execution starts here phaseTypes = ['nuclear','modulated','magnetic','macromolecular'] SetupGeneral() generalData = data['General'] Map = generalData['Map'] Flip = generalData['Flip'] MCSA = generalData['MCSA controls'] PWDR = any(['PWDR' in item for item in data['Histograms'].keys()]) # UpdateGeneral execution continues below def NameSizer(): def OnPhaseName(event): oldName = generalData['Name'] generalData['Name'] = NameTxt.GetValue() G2frame.G2plotNB.Rename(oldName,generalData['Name']) G2frame.dataFrame.SetLabel('Phase Data for '+generalData['Name']) G2frame.PatternTree.SetItemText(Item,generalData['Name']) #Hmm, need to change phase name key in Reflection Lists for each histogram def OnPhaseType(event): if not generalData['AtomTypes']: #can change only if no atoms! generalData['Type'] = TypeTxt.GetValue() wx.CallAfter(UpdateGeneral) else: TypeTxt.SetValue(generalData['Type']) def OnSpaceGroup(event): SpcGp = SGTxt.GetValue() SGErr,SGData = G2spc.SpcGroup(SpcGp) # try a lookup on the user-supplied name if SGErr: SpGrpNorm = G2spc.StandardizeSpcName(SpcGp) if SpGrpNorm: E,SGData = G2spc.SpcGroup(SpGrpNorm) if not E: SGErr = False if SGErr: text = [G2spc.SGErrors(SGErr)+'\nSpace Group set to previous'] SGTxt.SetValue(generalData['SGData']['SpGrp']) msg = 'Space Group Error' Style = wx.ICON_EXCLAMATION else: text = G2spc.SGPrint(SGData) generalData['SGData'] = SGData msg = 'Space Group Information' Style = wx.ICON_INFORMATION Text = '' for line in text: Text += line+'\n' wx.MessageBox(Text,caption=msg,style=Style) # General.DestroyChildren() #needed to clear away bad cellSizer, etc. wx.CallAfter(UpdateGeneral) nameSizer = wx.BoxSizer(wx.HORIZONTAL) nameSizer.Add(wx.StaticText(General,-1,' Phase name: '),0,wx.ALIGN_CENTER_VERTICAL) NameTxt = wx.TextCtrl(General,-1,value=generalData['Name'],style=wx.TE_PROCESS_ENTER) NameTxt.Bind(wx.EVT_TEXT_ENTER,OnPhaseName) NameTxt.Bind(wx.EVT_KILL_FOCUS,OnPhaseName) nameSizer.Add(NameTxt,0,wx.ALIGN_CENTER_VERTICAL) nameSizer.Add(wx.StaticText(General,-1,' Phase type: '),0,wx.ALIGN_CENTER_VERTICAL) TypeTxt = wx.ComboBox(General,-1,value=generalData['Type'],choices=phaseTypes, style=wx.CB_READONLY|wx.CB_DROPDOWN) TypeTxt.Bind(wx.EVT_COMBOBOX, OnPhaseType) nameSizer.Add(TypeTxt,0,wx.ALIGN_CENTER_VERTICAL) nameSizer.Add(wx.StaticText(General,-1,' Space group: '),0,wx.ALIGN_CENTER_VERTICAL) SGTxt = wx.TextCtrl(General,-1,value=generalData['SGData']['SpGrp'],style=wx.TE_PROCESS_ENTER) SGTxt.Bind(wx.EVT_TEXT_ENTER,OnSpaceGroup) nameSizer.Add(SGTxt,0,wx.ALIGN_CENTER_VERTICAL) return nameSizer def CellSizer(): cellGUIlist = [[['m3','m3m'],4,zip([" Unit cell: a = "," Vol = "],["%.5f","%.3f"],[True,False],[0,0])], [['3R','3mR'],6,zip([" a = "," alpha = "," Vol = "],["%.5f","%.3f","%.3f"],[True,True,False],[0,2,0])], [['3','3m1','31m','6/m','6/mmm','4/m','4/mmm'],6,zip([" a = "," c = "," Vol = "],["%.5f","%.5f","%.3f"],[True,True,False],[0,2,0])], [['mmm'],8,zip([" a = "," b = "," c = "," Vol = "],["%.5f","%.5f","%.5f","%.3f"], [True,True,True,False],[0,1,2,0])], [['2/m'+'a'],10,zip([" a = "," b = "," c = "," alpha = "," Vol = "], ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])], [['2/m'+'b'],10,zip([" a = "," b = "," c = "," beta = "," Vol = "], ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])], [['2/m'+'c'],10,zip([" a = "," b = "," c = "," gamma = "," Vol = "], ["%.5f","%.5f","%.5f","%.3f","%.3f"],[True,True,True,True,False],[0,1,2,4,0])], [['-1'],8,zip([" a = "," b = "," c = "," Vol = "," alpha = "," beta = "," gamma = "], ["%.5f","%.5f","%.5f","%.3f","%.3f","%.3f","%.3f"], [True,True,True,False,True,True,True],[0,1,2,0,3,4,5])]] def OnCellRef(event): generalData['Cell'][0] = cellRef.GetValue() def OnCellChange(event): SGData = generalData['SGData'] laue = SGData['SGLaue'] if laue == '2/m': laue += SGData['SGUniq'] cell = generalData['Cell'] Obj = event.GetEventObject() ObjId = cellList.index(Obj.GetId()) try: value = max(1.0,float(Obj.GetValue())) except ValueError: if ObjId < 3: #bad cell edge - reset value = controls[6+ObjId] else: #bad angle value = 90. if laue in ['m3','m3m']: cell[1] = cell[2] = cell[3] = value cell[4] = cell[5] = cell[6] = 90.0 Obj.SetValue("%.5f"%(cell[1])) elif laue in ['3R','3mR']: if ObjId == 0: cell[1] = cell[2] = cell[3] = value Obj.SetValue("%.5f"%(cell[1])) else: cell[4] = cell[5] = cell[6] = value Obj.SetValue("%.5f"%(cell[4])) elif laue in ['3','3m1','31m','6/m','6/mmm','4/m','4/mmm']: cell[4] = cell[5] = 90. cell[6] = 120. if laue in ['4/m','4/mmm']: cell[6] = 90. if ObjId == 0: cell[1] = cell[2] = value Obj.SetValue("%.5f"%(cell[1])) else: cell[3] = value Obj.SetValue("%.5f"%(cell[3])) elif laue in ['mmm']: cell[ObjId+1] = value cell[4] = cell[5] = cell[6] = 90. Obj.SetValue("%.5f"%(cell[ObjId+1])) elif laue in ['2/m'+'a']: cell[5] = cell[6] = 90. if ObjId != 3: cell[ObjId+1] = value Obj.SetValue("%.5f"%(cell[ObjId+1])) else: cell[4] = value Obj.SetValue("%.3f"%(cell[4])) elif laue in ['2/m'+'b']: cell[4] = cell[6] = 90. if ObjId != 3: cell[ObjId+1] = value Obj.SetValue("%.5f"%(cell[ObjId+1])) else: cell[5] = value Obj.SetValue("%.3f"%(cell[5])) elif laue in ['2/m'+'c']: cell[5] = cell[6] = 90. if ObjId != 3: cell[ObjId+1] = value Obj.SetValue("%.5f"%(cell[ObjId+1])) else: cell[6] = value Obj.SetValue("%.3f"%(cell[6])) else: cell[ObjId+1] = value if ObjId < 3: Obj.SetValue("%.5f"%(cell[1+ObjId])) else: Obj.SetValue("%.3f"%(cell[1+ObjId])) cell[7] = G2lat.calc_V(G2lat.cell2A(cell[1:7])) volVal.SetValue("%.3f"%(cell[7])) density,mattCoeff = G2mth.getDensity(generalData) if denSizer: denSizer[1].SetValue('%.3f'%(density)) if denSizer[2]: denSizer[2].SetValue('%.3f'%(mattCoeff)) generalData['Cell'] = cell cell = generalData['Cell'] laue = generalData['SGData']['SGLaue'] if laue == '2/m': laue += generalData['SGData']['SGUniq'] for cellGUI in cellGUIlist: if laue in cellGUI[0]: useGUI = cellGUI cellSizer = wx.FlexGridSizer(2,useGUI[1]+1,5,5) if PWDR: cellRef = wx.CheckBox(General,-1,label='Refine unit cell:') cellSizer.Add(cellRef,0,wx.ALIGN_CENTER_VERTICAL) cellRef.Bind(wx.EVT_CHECKBOX, OnCellRef) cellRef.SetValue(cell[0]) cellList = [] for txt,fmt,ifEdit,Id in useGUI[2]: cellSizer.Add(wx.StaticText(General,label=txt),0,wx.ALIGN_CENTER_VERTICAL) if ifEdit: #a,b,c,etc. cellVal = wx.TextCtrl(General,value=(fmt%(cell[Id+1])), style=wx.TE_PROCESS_ENTER) cellVal.Bind(wx.EVT_TEXT_ENTER,OnCellChange) cellVal.Bind(wx.EVT_KILL_FOCUS,OnCellChange) cellSizer.Add(cellVal,0,wx.ALIGN_CENTER_VERTICAL) cellList.append(cellVal.GetId()) else: #volume volVal = wx.TextCtrl(General,value=(fmt%(cell[7])),style=wx.TE_READONLY) volVal.SetBackgroundColour(VERY_LIGHT_GREY) cellSizer.Add(volVal,0,wx.ALIGN_CENTER_VERTICAL) return cellSizer def ElemSizer(): def OnIsotope(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] isotope = Obj.GetValue() generalData['Isotope'][item] = isotope indx = generalData['AtomTypes'].index(item) data['General']['AtomMass'][indx] = generalData['Isotopes'][item][isotope][0] density,mattCoeff = G2mth.getDensity(generalData) denSizer[1].SetValue('%.3f'%(density)) if denSizer[2]: denSizer[2].SetValue('%.3f'%(mattCoeff)) elemSizer = wx.FlexGridSizer(8,len(generalData['AtomTypes'])+1,1,1) elemSizer.Add(wx.StaticText(General,label=' Elements'),0,wx.ALIGN_CENTER_VERTICAL) for elem in generalData['AtomTypes']: typTxt = wx.TextCtrl(General,value=elem,style=wx.TE_READONLY) typTxt.SetBackgroundColour(VERY_LIGHT_GREY) elemSizer.Add(typTxt,0,wx.ALIGN_CENTER_VERTICAL) elemSizer.Add(wx.StaticText(General,label=' Isotope'),0,wx.ALIGN_CENTER_VERTICAL) for elem in generalData['AtomTypes']: choices = generalData['Isotopes'][elem].keys() isoSel = wx.ComboBox(General,-1,value=generalData['Isotope'][elem],choices=choices, style=wx.CB_READONLY|wx.CB_DROPDOWN) isoSel.Bind(wx.EVT_COMBOBOX,OnIsotope) Indx[isoSel.GetId()] = elem elemSizer.Add(isoSel,1,wx.ALIGN_CENTER_VERTICAL|wx.EXPAND) elemSizer.Add(wx.StaticText(General,label=' No. per cell'),0,wx.ALIGN_CENTER_VERTICAL) for elem in generalData['AtomTypes']: numbTxt = wx.TextCtrl(General,value='%.1f'%(generalData['NoAtoms'][elem]), style=wx.TE_READONLY) numbTxt.SetBackgroundColour(VERY_LIGHT_GREY) elemSizer.Add(numbTxt,0,wx.ALIGN_CENTER_VERTICAL) elemSizer.Add(wx.StaticText(General,label=' Atom weight'),0,wx.ALIGN_CENTER_VERTICAL) for wt in generalData['AtomMass']: wtTxt = wx.TextCtrl(General,value='%.3f'%(wt),style=wx.TE_READONLY) wtTxt.SetBackgroundColour(VERY_LIGHT_GREY) elemSizer.Add(wtTxt,0,wx.ALIGN_CENTER_VERTICAL) elemSizer.Add(wx.StaticText(General,label=' Bond radii'),0,wx.ALIGN_CENTER_VERTICAL) for rad in generalData['BondRadii']: bondRadii = wx.TextCtrl(General,value='%.2f'%(rad),style=wx.TE_READONLY) bondRadii.SetBackgroundColour(VERY_LIGHT_GREY) elemSizer.Add(bondRadii,0,wx.ALIGN_CENTER_VERTICAL) elemSizer.Add(wx.StaticText(General,label=' Angle radii'),0,wx.ALIGN_CENTER_VERTICAL) for rad in generalData['AngleRadii']: elemTxt = wx.TextCtrl(General,value='%.2f'%(rad),style=wx.TE_READONLY) elemTxt.SetBackgroundColour(VERY_LIGHT_GREY) elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL) elemSizer.Add(wx.StaticText(General,label=' van der Waals radii'),0,wx.ALIGN_CENTER_VERTICAL) for rad in generalData['vdWRadii']: elemTxt = wx.TextCtrl(General,value='%.2f'%(rad),style=wx.TE_READONLY) elemTxt.SetBackgroundColour(VERY_LIGHT_GREY) elemSizer.Add(elemTxt,0,wx.ALIGN_CENTER_VERTICAL) elemSizer.Add(wx.StaticText(General,label=' Default color'),0,wx.ALIGN_CENTER_VERTICAL) for R,G,B in generalData['Color']: colorTxt = wx.TextCtrl(General,value='',style=wx.TE_READONLY) colorTxt.SetBackgroundColour(wx.Colour(R,G,B)) elemSizer.Add(colorTxt,0,wx.ALIGN_CENTER_VERTICAL) return elemSizer def DenSizer(): mass = G2mth.getMass(generalData) density,mattCoeff = G2mth.getDensity(generalData) denSizer = wx.BoxSizer(wx.HORIZONTAL) denSizer.Add(wx.StaticText(General,-1,' Density: '),0,wx.ALIGN_CENTER_VERTICAL) denTxt = wx.TextCtrl(General,-1,'%.3f'%(density),style=wx.TE_READONLY) denTxt.SetBackgroundColour(VERY_LIGHT_GREY) denSizer.Add(denTxt,0,wx.ALIGN_CENTER_VERTICAL) mattTxt = None if generalData['Type'] == 'macromolecular' and mass > 0.0: denSizer.Add(wx.StaticText(General,-1,' Matthews coeff.: '), 0,wx.ALIGN_CENTER_VERTICAL) mattTxt = wx.TextCtrl(General,-1,'%.3f'%(mattCoeff),style=wx.TE_READONLY) mattTxt.SetBackgroundColour(VERY_LIGHT_GREY) denSizer.Add(mattTxt,0,wx.ALIGN_CENTER_VERTICAL) return denSizer,denTxt,mattTxt def PawleySizer(): def OnPawleyRef(event): generalData['doPawley'] = pawlRef.GetValue() def OnPawleyVal(event): try: dmin = float(pawlVal.GetValue()) if 0.25 <= dmin <= 20.: generalData['Pawley dmin'] = dmin except ValueError: pass pawlVal.SetValue("%.3f"%(generalData['Pawley dmin'])) #reset in case of error def OnPawleyNegWt(event): try: wt = float(pawlNegWt.GetValue()) if 0. <= wt <= 1.: generalData['Pawley neg wt'] = wt except ValueError: pass pawlNegWt.SetValue("%.2f"%(generalData['Pawley neg wt'])) #reset in case of error pawleySizer = wx.BoxSizer(wx.HORIZONTAL) pawleySizer.Add(wx.StaticText(General,label=' Pawley controls: '),0,wx.ALIGN_CENTER_VERTICAL) pawlRef = wx.CheckBox(General,-1,label=' Do Pawley refinement?') pawlRef.SetValue(generalData['doPawley']) pawlRef.Bind(wx.EVT_CHECKBOX,OnPawleyRef) pawleySizer.Add(pawlRef,0,wx.ALIGN_CENTER_VERTICAL) pawleySizer.Add(wx.StaticText(General,label=' Pawley dmin: '),0,wx.ALIGN_CENTER_VERTICAL) pawlVal = wx.TextCtrl(General,value='%.3f'%(generalData['Pawley dmin']),style=wx.TE_PROCESS_ENTER) pawlVal.Bind(wx.EVT_TEXT_ENTER,OnPawleyVal) pawlVal.Bind(wx.EVT_KILL_FOCUS,OnPawleyVal) pawleySizer.Add(pawlVal,0,wx.ALIGN_CENTER_VERTICAL) pawleySizer.Add(wx.StaticText(General,label=' Pawley neg. wt.: '),0,wx.ALIGN_CENTER_VERTICAL) pawlNegWt = wx.TextCtrl(General,value='%.2f'%(generalData['Pawley neg wt']),style=wx.TE_PROCESS_ENTER) pawlNegWt.Bind(wx.EVT_TEXT_ENTER,OnPawleyNegWt) pawlNegWt.Bind(wx.EVT_KILL_FOCUS,OnPawleyNegWt) pawleySizer.Add(pawlNegWt,0,wx.ALIGN_CENTER_VERTICAL) return pawleySizer def MapSizer(): def OnMapType(event): Map['MapType'] = mapType.GetValue() def OnRefList(event): Map['RefList'] = refList.GetValue() def OnResVal(event): try: res = float(mapRes.GetValue()) if 0.25 <= res <= 20.: Map['Resolution'] = res except ValueError: pass mapRes.SetValue("%.2f"%(Map['Resolution'])) #reset in case of error def OnCutOff(event): try: res = float(cutOff.GetValue()) if 10.0 <= res <= 100.: Map['cutOff'] = res except ValueError: pass cutOff.SetValue("%.1f"%(Map['cutOff'])) #reset in case of error #patch if 'cutOff' not in Map: Map['cutOff'] = 100.0 mapTypes = ['Fobs','Fcalc','delt-F','2*Fo-Fc','Omit','Patterson'] refList = data['Histograms'].keys() if not generalData['AtomTypes']: mapTypes = ['Patterson',] Map['MapType'] = 'Patterson' mapSizer = wx.BoxSizer(wx.VERTICAL) lineSizer = wx.BoxSizer(wx.HORIZONTAL) lineSizer.Add(wx.StaticText(General,label=' Fourier map controls: Map type: '),0,wx.ALIGN_CENTER_VERTICAL) mapType = wx.ComboBox(General,-1,value=Map['MapType'],choices=mapTypes, style=wx.CB_READONLY|wx.CB_DROPDOWN) mapType.Bind(wx.EVT_COMBOBOX,OnMapType) lineSizer.Add(mapType,0,wx.ALIGN_CENTER_VERTICAL) lineSizer.Add(wx.StaticText(General,label=' Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL) refList = wx.ComboBox(General,-1,value=Map['RefList'],choices=refList, style=wx.CB_READONLY|wx.CB_DROPDOWN) refList.Bind(wx.EVT_COMBOBOX,OnRefList) lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL) mapSizer.Add(lineSizer,0,wx.ALIGN_CENTER_VERTICAL) line2Sizer = wx.BoxSizer(wx.HORIZONTAL) line2Sizer.Add(wx.StaticText(General,label=' Resolution: '),0,wx.ALIGN_CENTER_VERTICAL) mapRes = wx.TextCtrl(General,value='%.2f'%(Map['Resolution']),style=wx.TE_PROCESS_ENTER) mapRes.Bind(wx.EVT_TEXT_ENTER,OnResVal) mapRes.Bind(wx.EVT_KILL_FOCUS,OnResVal) line2Sizer.Add(mapRes,0,wx.ALIGN_CENTER_VERTICAL) line2Sizer.Add(wx.StaticText(General,label=' Peak cutoff %: '),0,wx.ALIGN_CENTER_VERTICAL) cutOff = wx.TextCtrl(General,value='%.1f'%(Map['cutOff']),style=wx.TE_PROCESS_ENTER) cutOff.Bind(wx.EVT_TEXT_ENTER,OnCutOff) cutOff.Bind(wx.EVT_KILL_FOCUS,OnCutOff) line2Sizer.Add(cutOff,0,wx.ALIGN_CENTER_VERTICAL) mapSizer.Add(line2Sizer,0,wx.ALIGN_CENTER_VERTICAL) return mapSizer def FlipSizer(): if 'k-Max' not in Flip: Flip['k-Max'] = 20. def OnRefList(event): Flip['RefList'] = refList.GetValue() def OnNormElem(event): PE = G2elemGUI.PickElement(G2frame,ifNone=True) if PE.ShowModal() == wx.ID_OK: Flip['Norm element'] = PE.Elem.strip() normElem.SetLabel(Flip['Norm element']) PE.Destroy() def OnResVal(event): try: res = float(flipRes.GetValue()) if 0.25 <= res <= 20.: Flip['Resolution'] = res except ValueError: pass flipRes.SetValue("%.2f"%(Flip['Resolution'])) #reset in case of error def OnkFactor(event): try: res = float(kFactor.GetValue()) if 0.1 <= res <= 1.2: Flip['k-factor'] = res except ValueError: pass kFactor.SetValue("%.3f"%(Flip['k-factor'])) #reset in case of error def OnkMax(event): try: res = float(kMax.GetValue()) if res >= 10.: Flip['k-Max'] = res except ValueError: pass kMax.SetValue("%.1f"%(Flip['k-Max'])) #reset in case of error refList = data['Histograms'].keys() flipSizer = wx.BoxSizer(wx.VERTICAL) lineSizer = wx.BoxSizer(wx.HORIZONTAL) lineSizer.Add(wx.StaticText(General,label=' Charge flip controls: Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL) refList = wx.ComboBox(General,-1,value=Flip['RefList'],choices=refList, style=wx.CB_READONLY|wx.CB_DROPDOWN) refList.Bind(wx.EVT_COMBOBOX,OnRefList) lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL) lineSizer.Add(wx.StaticText(General,label=' Normalizing element: '),0,wx.ALIGN_CENTER_VERTICAL) normElem = wx.Button(General,label=Flip['Norm element'],style=wx.TE_READONLY) normElem.Bind(wx.EVT_BUTTON,OnNormElem) lineSizer.Add(normElem,0,wx.ALIGN_CENTER_VERTICAL) flipSizer.Add(lineSizer,0,wx.ALIGN_CENTER_VERTICAL) line2Sizer = wx.BoxSizer(wx.HORIZONTAL) line2Sizer.Add(wx.StaticText(General,label=' Resolution: '),0,wx.ALIGN_CENTER_VERTICAL) flipRes = wx.TextCtrl(General,value='%.2f'%(Flip['Resolution']),style=wx.TE_PROCESS_ENTER) flipRes.Bind(wx.EVT_TEXT_ENTER,OnResVal) flipRes.Bind(wx.EVT_KILL_FOCUS,OnResVal) line2Sizer.Add(flipRes,0,wx.ALIGN_CENTER_VERTICAL) line2Sizer.Add(wx.StaticText(General,label=' k-Factor (0.1-1.2): '),0,wx.ALIGN_CENTER_VERTICAL) kFactor = wx.TextCtrl(General,value='%.3f'%(Flip['k-factor']),style=wx.TE_PROCESS_ENTER) kFactor.Bind(wx.EVT_TEXT_ENTER,OnkFactor) kFactor.Bind(wx.EVT_KILL_FOCUS,OnkFactor) line2Sizer.Add(kFactor,0,wx.ALIGN_CENTER_VERTICAL) line2Sizer.Add(wx.StaticText(General,label=' k-Max (>=10.0): '),0,wx.ALIGN_CENTER_VERTICAL) kMax = wx.TextCtrl(General,value='%.1f'%(Flip['k-Max']),style=wx.TE_PROCESS_ENTER) kMax.Bind(wx.EVT_TEXT_ENTER,OnkMax) kMax.Bind(wx.EVT_KILL_FOCUS,OnkMax) line2Sizer.Add(kMax,0,wx.ALIGN_CENTER_VERTICAL) flipSizer.Add(line2Sizer,0,wx.ALIGN_CENTER_VERTICAL) return flipSizer def MCSASizer(): Ind = {} def OnRefList(event): MCSA['Data source'] = refList.GetValue() def OnDmin(event): try: val = float(dmin.GetValue()) if 1.0 <= val < 5.0: MCSA['dmin'] = val except ValueError: pass dmin.SetValue("%.3f"%(MCSA['dmin'])) #reset in case of error def OnAlist(event): MCSA['Algolrithm'] = Alist.GetValue() if 'Tremayne' in MCSA['Algolrithm']: wx.CallAfter(UpdateGeneral) def OnAjump(event): Obj = event.GetEventObject() ind = Indx[Obj.GetId()] try: val = float(Obj.GetValue()) if .0 <= val <= 1.0: MCSA['Jump coeff'][ind] = val except ValueError: pass Obj.SetValue("%.3f"%(MCSA['Jump coeff'][ind])) #reset in case of error def OnAnneal(event): Obj = event.GetEventObject() ind,fmt = Indx[Obj.GetId()] if ind < 3: try: val = float(Obj.GetValue()) if .0 <= val: MCSA['Annealing'][ind] = val except ValueError: pass else: try: val = int(Obj.GetValue()) if 1 <= val: MCSA['Annealing'][3] = val except ValueError: pass Obj.SetValue(fmt%(MCSA['Annealing'][ind])) #reset in case of error refList = [] if len(data['Pawley ref']): refList = ['Pawley reflections'] for item in data['Histograms'].keys(): if 'HKLF' in item: refList.append(item) mcsaSizer = wx.BoxSizer(wx.VERTICAL) lineSizer = wx.BoxSizer(wx.HORIZONTAL) lineSizer.Add(wx.StaticText(General,label=' Monte Carlo/Simulated Annealing controls: Reflection set from: '),0,wx.ALIGN_CENTER_VERTICAL) refList = wx.ComboBox(General,-1,value=MCSA['Data source'],choices=refList, style=wx.CB_READONLY|wx.CB_DROPDOWN) refList.Bind(wx.EVT_COMBOBOX,OnRefList) lineSizer.Add(refList,0,wx.ALIGN_CENTER_VERTICAL) lineSizer.Add(wx.StaticText(General,label=' d-min: '),0,wx.ALIGN_CENTER_VERTICAL) dmin = wx.TextCtrl(General,-1,value='%.3f'%(MCSA['dmin']),style=wx.TE_PROCESS_ENTER) dmin.Bind(wx.EVT_TEXT_ENTER,OnDmin) dmin.Bind(wx.EVT_KILL_FOCUS,OnDmin) lineSizer.Add(dmin,0,wx.ALIGN_CENTER_VERTICAL) mcsaSizer.Add(lineSizer) mcsaSizer.Add((5,5),) line2Sizer = wx.BoxSizer(wx.HORIZONTAL) Achoice = ['Normal','Random jump','Tremayne jump'] line2Sizer.Add(wx.StaticText(General,label=' MC/SA algorithm: '),0,wx.ALIGN_CENTER_VERTICAL) Alist = wx.ComboBox(General,-1,value=MCSA['Algolrithm'],choices=Achoice, style=wx.CB_READONLY|wx.CB_DROPDOWN) Alist.Bind(wx.EVT_COMBOBOX,OnAlist) line2Sizer.Add(Alist,0,wx.ALIGN_CENTER_VERTICAL) if 'Tremayne' in MCSA['Algolrithm']: for i,name in enumerate([' A-jump: ',' B-jump: ']): line2Sizer.Add(wx.StaticText(General,label=name),0,wx.ALIGN_CENTER_VERTICAL) Ajump = wx.TextCtrl(General,-1,value='%.3f'%(MCSA['Jump coeff'][i]),style=wx.TE_PROCESS_ENTER) Ajump.Bind(wx.EVT_TEXT_ENTER,OnAjump) Ajump.Bind(wx.EVT_KILL_FOCUS,OnAjump) Indx[Ajump.GetId()] = i line2Sizer.Add(Ajump,0,wx.ALIGN_CENTER_VERTICAL) mcsaSizer.Add(line2Sizer) mcsaSizer.Add((5,5),) line3Sizer = wx.BoxSizer(wx.HORIZONTAL) line3Sizer.Add(wx.StaticText(General,label=' Annealing schedule: '),0,wx.ALIGN_CENTER_VERTICAL) names = [' Start temp: ',' Final temp: ',' Slope: ',' No. trials: '] fmts = ['%.1f','%.5f','%.2f','%d'] for i,[name,fmt] in enumerate(zip(names,fmts)): line3Sizer.Add(wx.StaticText(General,label=name),0,wx.ALIGN_CENTER_VERTICAL) anneal = wx.TextCtrl(General,-1,value=fmt%(MCSA['Annealing'][i]),style=wx.TE_PROCESS_ENTER) anneal.Bind(wx.EVT_TEXT_ENTER,OnAnneal) anneal.Bind(wx.EVT_KILL_FOCUS,OnAnneal) Indx[anneal.GetId()] = [i,fmt] line3Sizer.Add(anneal,0,wx.ALIGN_CENTER_VERTICAL) mcsaSizer.Add(line3Sizer) return mcsaSizer # UpdateGeneral execution continues here if General.GetSizer(): General.GetSizer().Clear(True) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add((5,5),0) mainSizer.Add(NameSizer(),0) mainSizer.Add((5,5),0) mainSizer.Add(CellSizer(),0) mainSizer.Add((5,5),0) Indx = {} denSizer = None if len(generalData['AtomTypes']): denSizer = DenSizer() mainSizer.Add(denSizer[0]) mainSizer.Add((5,5),0) mainSizer.Add(ElemSizer()) G2gd.HorizontalLine(mainSizer,General) mainSizer.Add(PawleySizer()) G2gd.HorizontalLine(mainSizer,General) mainSizer.Add(MapSizer()) G2gd.HorizontalLine(mainSizer,General) mainSizer.Add(FlipSizer()) G2gd.HorizontalLine(mainSizer,General) mainSizer.Add(MCSASizer()) General.SetSizer(mainSizer) General.SetScrollbars(1,1,1,1) if G2frame.dataFrame.PhaseUserSize is None: Size = mainSizer.GetMinSize() Size[0] += 40 Size[1] = max(Size[1],290) + 35 General.SetSize(Size) General.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) Size[1] = min(Size[1],500) # don't let initial size get larger than 500 points G2frame.dataFrame.setSizePosLeft(Size) else: Size = G2frame.dataFrame.PhaseUserSize General.SetSize(G2frame.dataFrame.GetClientSize()) Size = mainSizer.ComputeFittingWindowSize(G2frame.dataFrame) General.SetVirtualSize(Size) General.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) G2frame.dataFrame.Update() G2frame.dataFrame.SetStatusText('') ################################################################################ ##### Atom routines ################################################################################ def FillAtomsGrid(Atoms): '''Display the contents of the Atoms tab ''' def RefreshAtomGrid(event): r,c = event.GetRow(),event.GetCol() if r < 0 and c < 0: for row in range(Atoms.GetNumberRows()): Atoms.SelectRow(row,True) if r < 0: #double click on col label! Change all atoms! sel = -1 noSkip = True if Atoms.GetColLabelValue(c) == 'refine': Type = generalData['Type'] if Type in ['nuclear','macromolecular']: choice = ['F - site fraction','X - coordinates','U - thermal parameters'] elif Type in ['magnetic',]: choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment'] dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelections() parms = '' for x in sel: parms += choice[x][0] dlg.Destroy() elif Atoms.GetColLabelValue(c) == 'I/A': choice = ['Isotropic','Anisotropic'] dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal Motion',choice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = choice[sel][0] dlg.Destroy() elif Atoms.GetColLabelValue(c) == 'Type': choice = generalData['AtomTypes'] dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom types',choice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = choice[sel] noSkip = False Atoms.ClearSelection() for row in range(Atoms.GetNumberRows()): if parms == atomData[row][c]: Atoms.SelectRow(row,True) dlg.Destroy() SetupGeneral() elif Atoms.GetColLabelValue(c) == 'residue': choice = [] for r in range(Atoms.GetNumberRows()): if str(atomData[r][c]) not in choice: choice.append(str(atomData[r][c])) choice.sort() dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue',choice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = choice[sel] noSkip = False Atoms.ClearSelection() for row in range(Atoms.GetNumberRows()): if parms == atomData[row][c]: Atoms.SelectRow(row,True) dlg.Destroy() elif Atoms.GetColLabelValue(c) == 'res no': choice = [] for r in range(Atoms.GetNumberRows()): if str(atomData[r][c]) not in choice: choice.append(str(atomData[r][c])) dlg = wx.SingleChoiceDialog(G2frame,'Select','Residue no.',choice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = choice[sel] noSkip = False Atoms.ClearSelection() for row in range(Atoms.GetNumberRows()): if int(parms) == atomData[row][c]: Atoms.SelectRow(row,True) dlg.Destroy() elif Atoms.GetColLabelValue(c) == 'chain': choice = [] for r in range(Atoms.GetNumberRows()): if atomData[r][c] not in choice: choice.append(atomData[r][c]) dlg = wx.SingleChoiceDialog(G2frame,'Select','Chain',choice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = choice[sel] noSkip = False Atoms.ClearSelection() for row in range(Atoms.GetNumberRows()): if parms == atomData[row][c]: Atoms.SelectRow(row,True) dlg.Destroy() elif Atoms.GetColLabelValue(c) == 'Uiso': #this needs to ask for value pass #& then change all 'I' atoms if sel >= 0 and noSkip: ui = colLabels.index('U11') us = colLabels.index('Uiso') ss = colLabels.index('site sym') for r in range(Atoms.GetNumberRows()): ID = atomData[r][-1] if parms != atomData[r][c] and Atoms.GetColLabelValue(c) == 'I/A': if parms == 'A': #'I' --> 'A' Uiso = float(Atoms.GetCellValue(r,us)) sytsym = atomData[r][ss] CSI = G2spc.GetCSuinel(sytsym) atomData[r][ui:ui+6] = Uiso*np.array(CSI[3]) atomData[r][us] = 0.0 Atoms.SetCellStyle(r,us,VERY_LIGHT_GREY,True) for i in range(6): ci = ui+i Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) if CSI[2][i]: Atoms.SetCellStyle(r,ci,WHITE,False) else: #'A' --> 'I' Uij = atomData[r][ui:ui+6] Uiso = (Uij[0]+Uij[1]+Uij[2])/3.0 atomData[r][us] = Uiso Atoms.SetCellStyle(r,us,WHITE,False) for i in range(6): ci = ui+i atomData[r][ci] = 0.0 Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) if not Atoms.IsReadOnly(r,c): if Atoms.GetColLabelValue(c) == 'refine': rbExcl = rbAtmDict.get(atomData[r][-1],'') if rbExcl: for excl in rbExcl: atomData[r][c] = parms.replace(excl,'') else: atomData[r][c] = parms else: atomData[r][c] = parms if 'Atoms' in data['Drawing']: DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID) wx.CallAfter(Paint) def ChangeAtomCell(event): def chkUij(Uij,CSI): #needs to do something!!! return Uij r,c = event.GetRow(),event.GetCol() if r >= 0 and c >= 0: ID = atomData[r][-1] if Atoms.GetColLabelValue(c) in ['x','y','z']: ci = colLabels.index('x') XYZ = atomData[r][ci:ci+3] if None in XYZ: XYZ = [0,0,0] SScol = colLabels.index('site sym') Mulcol = colLabels.index('mult') E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp']) Sytsym,Mult = G2spc.SytSym(XYZ,SGData) atomData[r][SScol] = Sytsym atomData[r][Mulcol] = Mult if atomData[r][colLabels.index('I/A')] == 'A': ui = colLabels.index('U11') CSI = G2spc.GetCSuinel(Sytsym) atomData[r][ui:ui+6] = chkUij(atomData[r][ui:ui+6],Sytsym) for i in range(6): ci = i+ui Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) if CSI[2][i]: Atoms.SetCellStyle(r,ci,WHITE,False) SetupGeneral() elif Atoms.GetColLabelValue(c) == 'I/A': #note use of text color to make it vanish! if atomData[r][c] == 'I': Uij = atomData[r][c+2:c+8] atomData[r][c+1] = (Uij[0]+Uij[1]+Uij[2])/3.0 Atoms.SetCellStyle(r,c+1,WHITE,False) Atoms.SetCellTextColour(r,c+1,BLACK) for i in range(6): ci = i+colLabels.index('U11') Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) Atoms.SetCellTextColour(r,ci,VERY_LIGHT_GREY) atomData[r][ci] = 0.0 else: value = atomData[r][c+1] CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')]) atomData[r][c+1] = 0.0 Atoms.SetCellStyle(r,c+1,VERY_LIGHT_GREY,True) Atoms.SetCellTextColour(r,c+1,VERY_LIGHT_GREY) for i in range(6): ci = i+colLabels.index('U11') atomData[r][ci] = value*CSI[3][i] Atoms.SetCellStyle(r,ci,VERY_LIGHT_GREY,True) Atoms.SetCellTextColour(r,ci,BLACK) if CSI[2][i]: Atoms.SetCellStyle(r,ci,WHITE,False) elif Atoms.GetColLabelValue(c) in ['U11','U22','U33','U12','U13','U23']: value = atomData[r][c] CSI = G2spc.GetCSuinel(atomData[r][colLabels.index('site sym')]) iUij = CSI[0][c-colLabels.index('U11')] for i in range(6): if iUij == CSI[0][i]: atomData[r][i+colLabels.index('U11')] = value*CSI[1][i] elif Atoms.GetColLabelValue(c) == 'refine': atomData[r][c] = atomData[r][c].replace(rbAtmDict.get(atomData[r][-1],''),'') if 'Atoms' in data['Drawing']: DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID) wx.CallAfter(Paint) def AtomTypeSelect(event): r,c = event.GetRow(),event.GetCol() if Atoms.GetColLabelValue(c) == 'Type': PE = G2elemGUI.PickElement(G2frame) if PE.ShowModal() == wx.ID_OK: if PE.Elem != 'None': atomData[r][c] = PE.Elem.strip() name = atomData[r][c] if len(name) in [2,4]: atomData[r][c-1] = name[:2]+'(%d)'%(r+1) else: atomData[r][c-1] = name[:1]+'(%d)'%(r+1) PE.Destroy() SetupGeneral() wx.CallAfter(Paint) value = Atoms.GetCellValue(r,c) atomData[r][c] = value ID = atomData[r][-1] if 'Atoms' in data['Drawing']: DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID) SetupGeneral() else: event.Skip() def RowSelect(event): r,c = event.GetRow(),event.GetCol() if not event.AltDown(): Atoms.frm = -1 G2frame.dataFrame.SetStatusText('') if r < 0 and c < 0: if Atoms.IsSelection(): Atoms.ClearSelection() elif c < 0: #only row clicks if event.ControlDown(): if r in Atoms.GetSelectedRows(): Atoms.DeselectRow(r) else: Atoms.SelectRow(r,True) elif event.ShiftDown(): indxs = Atoms.GetSelectedRows() Atoms.ClearSelection() ibeg = 0 if indxs: ibeg = indxs[-1] for row in range(ibeg,r+1): Atoms.SelectRow(row,True) elif event.AltDown(): if atomData[r][-1] in rbAtmDict: G2frame.dataFrame.SetStatusText('**** ERROR - atom is in a rigid body and can not be moved ****') Atoms.frm = -1 Atoms.ClearSelection() else: if Atoms.frm < 0: #pick atom to be moved Atoms.frm = r Atoms.SelectRow(r,True) n = colLabels.index('Name') G2frame.dataFrame.SetStatusText('Atom '+atomData[r][n]+' is to be moved') else: #move it item = atomData.pop(Atoms.frm) atomData.insert(r,item) Atoms.frm = -1 G2frame.dataFrame.SetStatusText('') wx.CallAfter(Paint) else: Atoms.ClearSelection() Atoms.SelectRow(r,True) def ChangeSelection(event): r,c = event.GetRow(),event.GetCol() if r < 0 and c < 0: Atoms.ClearSelection() if c < 0: if r in Atoms.GetSelectedRows(): Atoms.DeselectRow(r) else: Atoms.SelectRow(r,True) if r < 0: if c in Atoms.GetSelectedCols(): Atoms.DeselectCol(c) else: Atoms.SelectCol(c,True) def Paint(): table = [] rowLabels = [] for i,atom in enumerate(atomData): table.append(atom) rowLabels.append(str(i)) atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types) Atoms.SetTable(atomTable, True) Atoms.frm = -1 colType = colLabels.index('Type') colR = colLabels.index('refine') colSS = colLabels.index('site sym') colX = colLabels.index('x') colIA = colLabels.index('I/A') colU11 = colLabels.index('U11') colUiso = colLabels.index('Uiso') attr = wx.grid.GridCellAttr() attr.IncRef() #fix from Jim Hester attr.SetEditor(G2gd.GridFractionEditor(Atoms)) for c in range(colX,colX+3): Atoms.SetColAttr(c, attr) for i in range(colU11-1,colU11+6): Atoms.SetColSize(i,50) for row in range(Atoms.GetNumberRows()): atId = atomData[row][-1] rbExcl = rbAtmDict.get(atId,'') Atoms.SetReadOnly(row,colSS,True) #site sym Atoms.SetReadOnly(row,colSS+1,True) #Mult if Atoms.GetCellValue(row,colIA) == 'A': CSI = G2spc.GetCSuinel(atomData[row][colLabels.index('site sym')]) Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True) Atoms.SetCellTextColour(row,colUiso,VERY_LIGHT_GREY) for i in range(6): ci = colU11+i Atoms.SetCellTextColour(row,ci,BLACK) Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True) if CSI[2][i] and 'U' not in rbExcl: Atoms.SetCellStyle(row,ci,WHITE,False) else: Atoms.SetCellStyle(row,colUiso,WHITE,False) Atoms.SetCellTextColour(row,colUiso,BLACK) if 'U' in rbExcl: Atoms.SetCellStyle(row,colUiso,VERY_LIGHT_GREY,True) for i in range(6): ci = colU11+i Atoms.SetCellStyle(row,ci,VERY_LIGHT_GREY,True) Atoms.SetCellTextColour(row,ci,VERY_LIGHT_GREY) if 'X' in rbExcl: for c in range(0,colX+3): if c != colR: Atoms.SetCellStyle(row,c,VERY_LIGHT_GREY,True) Atoms.AutoSizeColumns(False) # FillAtomsGrid executable code starts here generalData = data['General'] atomData = data['Atoms'] DData = data['Drawing'] resRBData = data['RBModels'].get('Residue',[]) vecRBData = data['RBModels'].get('Vector',[]) rbAtmDict = {} for rbObj in resRBData+vecRBData: exclList = ['X' for i in range(len(rbObj['Ids']))] rbAtmDict.update(dict(zip(rbObj['Ids'],exclList))) if rbObj['ThermalMotion'][0] != 'None': for id in rbObj['Ids']: rbAtmDict[id] += 'U' # exclList will be 'x' or 'xu' if TLS used in RB Items = [G2gd.wxID_ATOMSEDITINSERT,G2gd.wxID_ATOMSEDITDELETE,G2gd.wxID_ATOMSREFINE, G2gd.wxID_ATOMSMODIFY,G2gd.wxID_ATOMSTRANSFORM,G2gd.wxID_ATOMVIEWINSERT,G2gd.wxID_ATOMMOVE] if atomData: for item in Items: G2frame.dataFrame.AtomsMenu.Enable(item,True) else: for item in Items: G2frame.dataFrame.AtomsMenu.Enable(item,False) Items = [G2gd.wxID_ATOMVIEWINSERT, G2gd.wxID_ATOMSVIEWADD,G2gd.wxID_ATOMMOVE] if 'showABC' in data['Drawing']: for item in Items: G2frame.dataFrame.AtomsMenu.Enable(item,True) else: for item in Items: G2frame.dataFrame.AtomsMenu.Enable(item,False) AAchoice = ": ,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR,VAL,MSE,HOH,UNK" Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,X,XU,U,F,FX,FXU,FU",]+ \ 3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_FLOAT+':10,4', #x,y,z,frac wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+":I,A",] Types += 7*[wg.GRID_VALUE_FLOAT+':10,5',] colLabels = ['Name','Type','refine','x','y','z','frac','site sym','mult','I/A','Uiso','U11','U22','U33','U12','U13','U23'] if generalData['Type'] == 'magnetic': colLabels += ['Mx','My','Mz'] Types[2] = wg.GRID_VALUE_CHOICE+": ,X,XU,U,M,MX,MXU,MU,F,FX,FXU,FU,FM,FMX,FMU," Types += 3*[wg.GRID_VALUE_FLOAT+':10,4',] elif generalData['Type'] == 'macromolecular': colLabels = ['res no','residue','chain'] + colLabels Types = [wg.GRID_VALUE_STRING, wg.GRID_VALUE_CHOICE+AAchoice, wg.GRID_VALUE_STRING] + Types elif generalData['Type'] == 'modulated': Types += [] colLabels += [] SGData = data['General']['SGData'] G2frame.dataFrame.SetStatusText('') if SGData['SGPolax']: G2frame.dataFrame.SetStatusText('Warning: The location of the origin is arbitrary in '+SGData['SGPolax']) Atoms.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeAtomCell) Atoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, AtomTypeSelect) Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid) Atoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect) Atoms.Bind(wg.EVT_GRID_LABEL_RIGHT_CLICK, ChangeSelection) Atoms.SetMargins(0,0) if G2frame.dataFrame.PhaseUserSize is None: G2frame.dataFrame.setSizePosLeft([700,300]) else: G2frame.dataFrame.Update() Paint() def OnAtomAdd(event): AtomAdd(0,0,0) FillAtomsGrid(Atoms) event.StopPropagation() def OnAtomViewAdd(event): try: drawData = data['Drawing'] x,y,z = drawData['viewPoint'][0] AtomAdd(x,y,z) except: AtomAdd(0,0,0) FillAtomsGrid(Atoms) event.StopPropagation() def AtomAdd(x,y,z,El='H',Name='UNK'): atomData = data['Atoms'] generalData = data['General'] Ncol = Atoms.GetNumberCols() atId = ran.randint(0,sys.maxint) E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp']) Sytsym,Mult = G2spc.SytSym([x,y,z],SGData) if generalData['Type'] == 'macromolecular': atomData.append([0,Name,'',Name,El,'',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId]) elif generalData['Type'] == 'nuclear': atomData.append([Name,El,'',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId]) elif generalData['Type'] == 'magnetic': atomData.append([Name,El,'',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId]) SetupGeneral() if 'Atoms' in data['Drawing']: DrawAtomAdd(data['Drawing'],atomData[-1]) G2plt.PlotStructure(G2frame,data) def OnAtomInsert(event): AtomInsert(0,0,0) FillAtomsGrid(Atoms) event.StopPropagation() def OnAtomViewInsert(event): if 'Drawing' in data: drawData = data['Drawing'] x,y,z = drawData['viewPoint'][0] AtomAdd(x,y,z) FillAtomsGrid(Atoms) event.StopPropagation() def OnRBAppend(event): #unfinished! rbData = G2frame.PatternTree.GetItemPyData( G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Rigid bodies')) general = data['General'] atomData = data['Atoms'] Amat,Bmat = G2lat.cell2AB(general['Cell'][1:7]) rbNames = {} for rbVec in rbData['Vector']: if rbVec != 'AtInfo': rbNames[rbData['Vector'][rbVec]['RBname']] = ['Vector',rbVec] for rbRes in rbData['Residue']: if rbRes != 'AtInfo': rbNames[rbData['Residue'][rbRes]['RBname']] = ['Residue',rbRes] if not rbNames: print '**** ERROR - no rigid bodies defined ****' return def OnAtomMove(event): drawData = data['Drawing'] atomData = data['Atoms'] x,y,z = drawData['viewPoint'][0] colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] cx = colLabels.index('x') indx = Atoms.GetSelectedRows() if len(indx) != 1: print '**** ERROR - only one atom can be moved ****' elif atomData[indx[0]][-1] in rbAtmDict: print '**** ERROR - Atoms in rigid bodies can not be moved ****' else: atomData[indx[0]][cx:cx+3] = [x,y,z] SetupGeneral() FillAtomsGrid(Atoms) ID = atomData[indx[0]][-1] DrawAtomsReplaceByID(data['Drawing'],atomData[indx[0]],ID) G2plt.PlotStructure(G2frame,data) event.StopPropagation() def DrawAtomsReplaceByID(drawingData,atom,ID): IDs = [ID,] atomData = drawingData['Atoms'] indx = G2mth.FindAtomIndexByIDs(atomData,IDs) for ind in indx: atomData[ind] = MakeDrawAtom(atom,atomData[ind]) def MakeDrawAtom(atom,oldatom=None): AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE', 'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK'] AA1letter = ['A','R','N','D','C','Q','E','G','H','I', 'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' '] generalData = data['General'] SGData = generalData['SGData'] if generalData['Type'] == 'nuclear': if oldatom: opr = oldatom[5] if atom[9] == 'A': X,U = G2spc.ApplyStringOps(opr,SGData,atom[3:6],atom[11:17]) atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:11]+list(U)+oldatom[17:]][0] else: X = G2spc.ApplyStringOps(opr,SGData,atom[3:6]) atomInfo = [atom[:2]+list(X)+oldatom[5:9]+atom[9:]+oldatom[17:]][0] else: atomInfo = [atom[:2]+atom[3:6]+['1',]+['vdW balls',]+ ['',]+[[255,255,255],]+atom[9:]+[[],[]]][0] ct,cs = [1,8] #type & color elif generalData['Type'] == 'macromolecular': try: oneLetter = AA3letter.index(atom[1]) except ValueError: oneLetter = -1 atomInfo = [[atom[1].strip()+atom[0],]+ [AA1letter[oneLetter]+atom[0],]+atom[2:5]+ atom[6:9]+['1',]+['sticks',]+['',]+[[255,255,255],]+atom[12:]+[[],[]]][0] ct,cs = [4,11] #type & color elif generalData['Type'] == 'magnetic': if oldatom: atomInfo = [atom[:2]+oldatom[3:]][0] else: atomInfo = [atom[:2]+atom[3:6]+['vdW balls',]+['',]+atom[9:]+[[],[]]][0] ct,cs = [1,8] #type & color # elif generalData['Type'] == 'modulated': # ????? for future atNum = generalData['AtomTypes'].index(atom[ct]) atomInfo[cs] = list(generalData['Color'][atNum]) return atomInfo def AtomInsert(x,y,z): indx = Atoms.GetSelectedRows() if indx: indx = indx[0] atomData = data['Atoms'] generalData = data['General'] Ncol = Atoms.GetNumberCols() E,SGData = G2spc.SpcGroup(generalData['SGData']['SpGrp']) Sytsym,Mult = G2spc.SytSym([0,0,0],SGData) atId = ran.randint(0,sys.maxint) if generalData['Type'] == 'macromolecular': atomData.insert(indx,[0,'UNK','','UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.10,0,0,0,0,0,0,atId]) elif generalData['Type'] == 'nuclear': atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,'I',0.01,0,0,0,0,0,0,atId]) elif generalData['Type'] == 'magnetic': atomData.insert(indx,['UNK','UNK','',x,y,z,1,Sytsym,Mult,0,'I',0.01,0,0,0,0,0,0,0,0,0,atId]) SetupGeneral() def AtomDelete(event): indx = Atoms.GetSelectedRows() IDs = [] if indx: atomData = data['Atoms'] indx.reverse() for ind in indx: atom = atomData[ind] if atom[-1] in rbAtmDict: G2frame.dataFrame.SetStatusText('**** ERROR - atom is in a rigid body and can not be deleted ****') else: IDs.append(atom[-1]) del atomData[ind] if 'Atoms' in data['Drawing']: DrawAtomsDeleteByIDs(IDs) wx.CallAfter(FillAtomsGrid,Atoms) G2plt.PlotStructure(G2frame,data) SetupGeneral() event.StopPropagation() def AtomRefine(event): colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] c = colLabels.index('refine') indx = Atoms.GetSelectedRows() if indx: atomData = data['Atoms'] generalData = data['General'] Type = generalData['Type'] if Type in ['nuclear','macromolecular']: choice = ['F - site fraction','X - coordinates','U - thermal parameters'] elif Type == 'magnetic': choice = ['F - site fraction','X - coordinates','U - thermal parameters','M - magnetic moment'] dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',choice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelections() parms = '' for x in sel: parms += choice[x][0] for r in indx: if not Atoms.IsReadOnly(r,c): atomData[r][c] = parms Atoms.ForceRefresh() dlg.Destroy() def AtomModify(event): indx = Atoms.GetSelectedRows() if indx: atomData = data['Atoms'] generalData = data['General'] colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] choices = ['Type','Name','x','y','z','frac','I/A','Uiso'] dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom parameter',choices) parm = '' if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parm = choices[sel] cid = colLabels.index(parm) dlg.Destroy() if parm in ['Type']: dlg = G2elemGUI.PickElement(G2frame) if dlg.ShowModal() == wx.ID_OK: if dlg.Elem not in ['None']: El = dlg.Elem.strip() for r in indx: if not Atoms.IsReadOnly(r,cid): atomData[r][cid] = El if len(El) in [2,4]: atomData[r][cid-1] = El[:2]+'(%d)'%(r+1) else: atomData[r][cid-1] = El[:1]+'(%d)'%(r+1) SetupGeneral() if 'Atoms' in data['Drawing']: for r in indx: ID = atomData[r][-1] DrawAtomsReplaceByID(data['Drawing'],atomData[r],ID) FillAtomsGrid(Atoms) dlg.Destroy() elif parm in ['Name',]: dlg = wx.MessageDialog(G2frame,'Do you really want to rename the selected atoms?','Rename', wx.YES_NO | wx.ICON_QUESTION) try: result = dlg.ShowModal() if result == wx.ID_YES: for r in indx: if not Atoms.IsReadOnly(r,cid+1): El = atomData[r][cid+1] if len(El) in [2,4]: atomData[r][cid] = El[:2]+'(%d)'%(r+1) else: atomData[r][cid] = El[:1]+'(%d)'%(r+1) FillAtomsGrid(Atoms) finally: dlg.Destroy() elif parm in ['I/A']: choices = ['Isotropic','Anisotropic'] dlg = wx.SingleChoiceDialog(G2frame,'Select','Thermal parameter model',choices) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parm = choices[sel][0] for r in indx: if not Atoms.IsReadOnly(r,cid): atomData[r][cid] = parm FillAtomsGrid(Atoms) dlg.Destroy() elif parm in ['frac','Uiso']: limits = [0.,1.] val = 1.0 if parm in ['Uiso']: limits = [0.,0.25] val = 0.01 dlg = G2gd.SingleFloatDialog(G2frame,'New value','Enter new value for '+parm,val,limits) if dlg.ShowModal() == wx.ID_OK: parm = dlg.GetValue() for r in indx: if not Atoms.IsReadOnly(r,cid): atomData[r][cid] = parm SetupGeneral() FillAtomsGrid(Atoms) dlg.Destroy() elif parm in ['x','y','z']: limits = [-1.,1.] val = 0. dlg = G2gd.SingleFloatDialog(G2frame,'Atom shift','Enter shift for '+parm,val,limits) if dlg.ShowModal() == wx.ID_OK: parm = dlg.GetValue() for r in indx: if not Atoms.IsReadOnly(r,cid): atomData[r][cid] += parm SetupGeneral() FillAtomsGrid(Atoms) dlg.Destroy() def AtomTransform(event): indx = Atoms.GetSelectedRows() if indx: generalData = data['General'] colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] cx = colLabels.index('x') cuia = colLabels.index('I/A') cuij = colLabels.index('U11') css = colLabels.index('site sym') atomData = data['Atoms'] generalData = data['General'] SGData = generalData['SGData'] dlg = G2gd.SymOpDialog(G2frame,SGData,True,True) New = False try: if dlg.ShowModal() == wx.ID_OK: Inv,Cent,Opr,Cell,New,Force = dlg.GetSelection() Cell = np.array(Cell) cent = SGData['SGCen'][Cent] M,T = SGData['SGOps'][Opr] for ind in indx: XYZ = np.array(atomData[ind][cx:cx+3]) XYZ = np.inner(M,XYZ)+T if Inv: XYZ = -XYZ XYZ = XYZ+cent+Cell if Force: XYZ = G2spc.MoveToUnitCell(XYZ) if New: atom = copy.copy(atomData[ind]) else: atom = atomData[ind] atom[cx:cx+3] = XYZ atom[css:css+2] = G2spc.SytSym(XYZ,SGData) if atom[cuia] == 'A': Uij = atom[cuij:cuij+6] U = G2spc.Uij2U(Uij) U = np.inner(np.inner(M,U),M) Uij = G2spc.U2Uij(U) atom[cuij:cuij+6] = Uij if New: atomData.append(atom) finally: dlg.Destroy() Atoms.ClearSelection() if New: FillAtomsGrid(Atoms) else: Atoms.ForceRefresh() def OnDistAngle(event): indx = Atoms.GetSelectedRows() Oxyz = [] xyz = [] DisAglData = {} DisAglCtls = {} if indx: generalData = data['General'] DisAglData['OrigIndx'] = indx if 'DisAglCtls' in generalData: DisAglCtls = generalData['DisAglCtls'] dlg = G2gd.DisAglDialog(G2frame,DisAglCtls,generalData) if dlg.ShowModal() == wx.ID_OK: DisAglCtls = dlg.GetData() dlg.Destroy() generalData['DisAglCtls'] = DisAglCtls atomData = data['Atoms'] colLabels = [Atoms.GetColLabelValue(c) for c in range(Atoms.GetNumberCols())] cx = colLabels.index('x') cn = colLabels.index('Name') for i,atom in enumerate(atomData): xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3]) if i in indx: Oxyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3]) DisAglData['OrigAtoms'] = Oxyz DisAglData['TargAtoms'] = xyz generalData = data['General'] DisAglData['SGData'] = generalData['SGData'] DisAglData['Cell'] = generalData['Cell'][1:] #+ volume if 'pId' in data: DisAglData['pId'] = data['pId'] DisAglData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance')) try: G2str.DistAngle(DisAglCtls,DisAglData) except KeyError: # inside DistAngle for missing atom types in DisAglCtls print '**** ERROR - try again but do "Reset" to fill in missing atom types ****' def OnReImport(event): print 'reimport atoms from file to be developed' reqrdr = G2frame.dataFrame.ReImportMenuId.get(event.GetId()) rdlist = G2frame.OnImportGeneric(reqrdr, G2frame.ImportPhaseReaderlist, 'phase') if len(rdlist) == 0: return # for now rdlist is only expected to have one element # for now always use the first phase for when multiple phases are ever implemented # but it would be better to loop until we find a phase that matches the one in data for rd in rdlist: # rd contains all info for a phase PhaseName = rd.Phase['General']['Name'] print 'Read phase '+str(PhaseName)+' from file '+str(G2frame.lastimport) print rd.Phase['Atoms'] return ################################################################################ #Structure drawing GUI stuff ################################################################################ def SetupDrawingData(): generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) atomData = data['Atoms'] AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE', 'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE','HOH','WAT','UNK'] AA1letter = ['A','R','N','D','C','Q','E','G','H','I', 'L','K','M','F','P','S','T','W','Y','V','M',' ',' ',' '] defaultDrawing = {'Atoms':[],'viewPoint':[[0.5,0.5,0.5],[]],'showHydrogen':True, 'backColor':[0,0,0],'depthFog':False,'Zclip':50.0,'cameraPos':50.,'Zstep':0.5, 'radiusFactor':0.85,'contourLevel':1.,'bondRadius':0.1,'ballScale':0.33, 'vdwScale':0.67,'ellipseProb':50,'sizeH':0.50,'unitCellBox':True, 'showABC':True,'selectedAtoms':[],'Atoms':[],'oldxy':[], 'bondList':{},'viewDir':[1,0,0]} V0 = np.array([0,0,1]) V = np.inner(Amat,V0) V /= np.sqrt(np.sum(V**2)) A = np.arccos(np.sum(V*V0)) defaultDrawing['Quaternion'] = G2mth.AV2Q(A,[0,1,0]) try: drawingData = data['Drawing'] except KeyError: data['Drawing'] = {} drawingData = data['Drawing'] if not drawingData: #fill with defaults if empty drawingData.update(defaultDrawing) if 'Zstep' not in drawingData: drawingData['Zstep'] = 0.5 if 'contourLevel' not in drawingData: drawingData['contourLevel'] = 1. if 'viewDir' not in drawingData: drawingData['viewDir'] = [0,0,1] if 'Quaternion' not in drawingData: drawingData['Quaternion'] = G2mth.AV2Q(2*np.pi,np.inner(Amat,[0,0,1])) if 'showRigidBodies' not in drawingData: drawingData['showRigidBodies'] = True cx,ct,cs,ci = [0,0,0,0] if generalData['Type'] == 'nuclear': cx,ct,cs,ci = [2,1,6,17] #x, type, style & index elif generalData['Type'] == 'macromolecular': cx,ct,cs,ci = [5,4,9,20] #x, type, style & index elif generalData['Type'] == 'magnetic': cx,ct,cs,ci = [2,1,6,20] #x, type, style & index # elif generalData['Type'] == 'modulated': # ????? for future drawingData['atomPtrs'] = [cx,ct,cs,ci] if not drawingData.get('Atoms'): for atom in atomData: DrawAtomAdd(drawingData,atom) data['Drawing'] = drawingData def DrawAtomAdd(drawingData,atom): drawingData['Atoms'].append(MakeDrawAtom(atom)) def OnRestraint(event): indx = drawAtoms.GetSelectedRows() restData = G2frame.PatternTree.GetItemPyData( G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Restraints')) drawingData = data['Drawing'] generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) cx,ct,cs,ci = drawingData['atomPtrs'] atomData = drawingData['Atoms'] atNames = [] atXYZ = [] atSymOp = [] atIndx = [] for item in indx: atXYZ.append(np.array(atomData[item][cx:cx+3])) atSymOp.append(atomData[item][cs-1]) atIndx.append(atomData[item][ci]) if event.GetId() == G2gd.wxID_DRAWRESTRBOND and len(indx) == 2: try: bondData = restData[PhaseName]['Bond'] except KeyError: bondData = {'wtFactor':1.0,'Bonds':[],'Use':True} restData[PhaseName] = {} restData[PhaseName]['Bond'] = bondData dist = G2mth.getRestDist(atXYZ,Amat) bondData['Bonds'].append([atIndx,atSymOp,1.54,0.01]) elif event.GetId() == G2gd.wxID_DRAWRESTRANGLE and len(indx) == 3: try: angleData = restData[PhaseName]['Angle'] except KeyError: angleData = {'wtFactor':1.0,'Angles':[],'Use':True} restData[PhaseName] = {} restData[PhaseName]['Angle'] = angleData angle = G2mth.getRestAngle(atXYZ,Amat) angleData['Angles'].append([atIndx,atSymOp,109.5,1.0]) elif event.GetId() == G2gd.wxID_DRAWRESTRPLANE and len(indx) > 3: try: planeData = restData[PhaseName]['Plane'] except KeyError: planeData = {'wtFactor':1.0,'Planes':[],'Use':True} restData[PhaseName] = {} restData[PhaseName]['Plane'] = planeData plane = G2mth.getRestPlane(atXYZ,Amat) planeData['Planes'].append([atIndx,atSymOp,0.0,0.01]) elif event.GetId() == G2gd.wxID_DRAWRESTRCHIRAL and len(indx) == 4: try: chiralData = restData[PhaseName]['Chiral'] except KeyError: chiralData = {'wtFactor':1.0,'Volumes':[],'Use':True} restData[PhaseName] = {} restData[PhaseName]['Chiral'] = chiralData volume = G2mth.getRestChiral(atXYZ,Amat) chiralData['Volumes'].append([atIndx,atSymOp,2.5,0.1]) else: print '**** ERROR wrong number of atoms selected for this restraint' return G2frame.PatternTree.SetItemPyData( G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Restraints'),restData) def OnDefineRB(event): indx = drawAtoms.GetSelectedRows() indx.sort() RBData = G2frame.PatternTree.GetItemPyData( G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Rigid bodies')) drawingData = data['Drawing'] generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) cx,ct,cs,ci = drawingData['atomPtrs'] atomData = drawingData['Atoms'] rbXYZ = [] rbType = [] atNames = [] AtInfo = RBData['Residue']['AtInfo'] for i,item in enumerate(indx): rbtype = atomData[item][ct] atNames.append(rbtype+str(i)) rbType.append(rbtype) if rbtype not in AtInfo: Info = G2elem.GetAtomInfo(rbtype) AtInfo[rbtype] = [Info['Drad'],Info['Color']] rbXYZ.append(np.inner(np.array(atomData[item][cx:cx+3]),Amat)) rbXYZ = np.array(rbXYZ) rbXYZ -= rbXYZ[0] rbId = ran.randint(0,sys.maxint) rbName = 'UNKRB' dlg = wx.TextEntryDialog(G2frame,'Enter the name for the new rigid body', 'Edit rigid body name',rbName ,style=wx.OK) if dlg.ShowModal() == wx.ID_OK: rbName = dlg.GetValue() dlg.Destroy() RBData['Residue'][rbId] = {'RBname':rbName,'rbXYZ':rbXYZ,'rbTypes':rbType, 'atNames':atNames,'rbRef':[0,1,2,False],'rbSeq':[],'SelSeq':[0,0],'useCount':0} RBData['RBIds']['Residue'].append(rbId) G2frame.dataFrame.SetStatusText('New rigid body UNKRB added to set of Residue rigid bodies') ################################################################################ ##### Atom draw routines ################################################################################ def UpdateDrawAtoms(atomStyle=''): def RefreshAtomGrid(event): def SetChoice(name,c,n=0): choice = [] for r in range(len(atomData)): if n: srchStr = str(atomData[r][c][:n]) else: srchStr = str(atomData[r][c]) if srchStr not in choice: if n: choice.append(str(atomData[r][c][:n])) else: choice.append(str(atomData[r][c])) choice.sort() dlg = wx.MultiChoiceDialog(G2frame,'Select',name,choice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelections() parms = [] for x in sel: parms.append(choice[x]) noSkip = False drawAtoms.ClearSelection() drawingData['selectedAtoms'] = [] for row in range(len(atomData)): test = atomData[row][c] if n: test = test[:n] if test in parms: drawAtoms.SelectRow(row,True) drawingData['selectedAtoms'].append(row) G2plt.PlotStructure(G2frame,data) dlg.Destroy() r,c = event.GetRow(),event.GetCol() if r < 0 and c < 0: for row in range(drawAtoms.GetNumberRows()): drawingData['selectedAtoms'].append(row) drawAtoms.SelectRow(row,True) elif r < 0: #dclick on col label sel = -1 Parms = False noSkip = True if drawAtoms.GetColLabelValue(c) == 'Style': dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = styleChoice[sel] for r in range(len(atomData)): atomData[r][c] = parms drawAtoms.SetCellValue(r,c,parms) FindBondsDraw() G2plt.PlotStructure(G2frame,data) dlg.Destroy() elif drawAtoms.GetColLabelValue(c) == 'Label': dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom labelling style',labelChoice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = labelChoice[sel] for r in range(len(atomData)): atomData[r][c] = parms drawAtoms.SetCellValue(r,c,parms) dlg.Destroy() elif drawAtoms.GetColLabelValue(c) == 'Color': dlg = wx.ColourDialog(G2frame) if dlg.ShowModal() == wx.ID_OK: color = dlg.GetColourData().GetColour() attr = wg.GridCellAttr() #needs to be here - gets lost if outside loop! attr.SetReadOnly(True) attr.SetBackgroundColour(color) for r in range(len(atomData)): atomData[r][c] = color drawingData['Atoms'][r][c] = color drawAtoms.SetAttr(r,c,attr) UpdateDrawAtoms() dlg.Destroy() elif drawAtoms.GetColLabelValue(c) == 'Residue': SetChoice('Residue',c,3) elif drawAtoms.GetColLabelValue(c) == '1-letter': SetChoice('1-letter',c,1) elif drawAtoms.GetColLabelValue(c) == 'Chain': SetChoice('Chain',c) elif drawAtoms.GetColLabelValue(c) == 'Name': SetChoice('Name',c) elif drawAtoms.GetColLabelValue(c) == 'Sym Op': SetChoice('Name',c) elif drawAtoms.GetColLabelValue(c) == 'Type': SetChoice('Type',c) elif drawAtoms.GetColLabelValue(c) in ['x','y','z','I/A']: drawAtoms.ClearSelection() else: if drawAtoms.GetColLabelValue(c) in ['Style','Label']: atomData[r][c] = drawAtoms.GetCellValue(r,c) FindBondsDraw() elif drawAtoms.GetColLabelValue(c) == 'Color': dlg = wx.ColourDialog(G2frame) if dlg.ShowModal() == wx.ID_OK: color = dlg.GetColourData().GetColour() attr = wg.GridCellAttr() #needs to be here - gets lost if outside loop! attr.SetReadOnly(True) attr.SetBackgroundColour(color) atomData[r][c] = color drawingData['Atoms'][r][c] = color drawAtoms.SetAttr(i,cs+2,attr) dlg.Destroy() UpdateDrawAtoms() G2plt.PlotStructure(G2frame,data) def RowSelect(event): r,c = event.GetRow(),event.GetCol() if r < 0 and c < 0: if drawAtoms.IsSelection(): drawAtoms.ClearSelection() elif c < 0: #only row clicks if event.ControlDown(): if r in drawAtoms.GetSelectedRows(): drawAtoms.DeselectRow(r) else: drawAtoms.SelectRow(r,True) elif event.ShiftDown(): indxs = drawAtoms.GetSelectedRows() drawAtoms.ClearSelection() ibeg = 0 if indxs: ibeg = indxs[-1] for row in range(ibeg,r+1): drawAtoms.SelectRow(row,True) else: drawAtoms.ClearSelection() drawAtoms.SelectRow(r,True) drawingData['selectedAtoms'] = [] drawingData['selectedAtoms'] = drawAtoms.GetSelectedRows() G2plt.PlotStructure(G2frame,data) # UpdateDrawAtoms executable code starts here G2frame.dataFrame.SetStatusText('') generalData = data['General'] SetupDrawingData() drawingData = data['Drawing'] cx,ct,cs,ci = drawingData['atomPtrs'] atomData = drawingData['Atoms'] if atomStyle: for atom in atomData: atom[cs] = atomStyle Types = [wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',]+ \ [wg.GRID_VALUE_STRING,wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,polyhedra", wg.GRID_VALUE_CHOICE+": ,type,name,number",wg.GRID_VALUE_STRING,wg.GRID_VALUE_STRING,] styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra'] labelChoice = [' ','type','name','number'] colLabels = ['Name','Type','x','y','z','Sym Op','Style','Label','Color','I/A'] if generalData['Type'] == 'macromolecular': colLabels = ['Residue','1-letter','Chain'] + colLabels Types = 3*[wg.GRID_VALUE_STRING,]+Types Types[8] = wg.GRID_VALUE_CHOICE+": ,lines,vdW balls,sticks,balls & sticks,ellipsoids,backbone,ribbons,schematic" styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','backbone','ribbons','schematic'] labelChoice = [' ','type','name','number','residue','1-letter','chain'] Types[9] = wg.GRID_VALUE_CHOICE+": ,type,name,number,residue,1-letter,chain" # elif generalData['Type'] == 'modulated': # Types += [] # colLabels += [] table = [] rowLabels = [] for i,atom in enumerate(drawingData['Atoms']): table.append(atom[:colLabels.index('I/A')+1]) rowLabels.append(str(i)) atomTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types) drawAtoms.SetTable(atomTable, True) drawAtoms.SetMargins(0,0) drawAtoms.AutoSizeColumns(True) drawAtoms.SetColSize(colLabels.index('Style'),80) drawAtoms.SetColSize(colLabels.index('Color'),50) drawAtoms.Bind(wg.EVT_GRID_CELL_CHANGE, RefreshAtomGrid) drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, RefreshAtomGrid) drawAtoms.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, RefreshAtomGrid) drawAtoms.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect) for i,atom in enumerate(drawingData['Atoms']): attr = wg.GridCellAttr() #needs to be here - gets lost if outside loop! attr.SetReadOnly(True) attr.SetBackgroundColour(atom[cs+2]) drawAtoms.SetAttr(i,cs+2,attr) drawAtoms.SetCellValue(i,cs+2,'') indx = drawingData['selectedAtoms'] if indx: for r in range(len(atomData)): if r in indx: drawAtoms.SelectRow(r) for c in range(len(colLabels)): attr = wg.GridCellAttr() #needs to be here - gets lost if outside loop! attr.SetReadOnly(True) attr.SetBackgroundColour(VERY_LIGHT_GREY) if colLabels[c] not in ['Style','Label','Color']: drawAtoms.SetColAttr(c,attr) if G2frame.dataFrame.PhaseUserSize is None: G2frame.dataFrame.setSizePosLeft([600,300]) else: G2frame.dataFrame.Update() FindBondsDraw() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def DrawAtomStyle(event): indx = drawAtoms.GetSelectedRows() if indx: generalData = data['General'] atomData = data['Drawing']['Atoms'] cx,ct,cs,ci = data['Drawing']['atomPtrs'] styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids','polyhedra'] if generalData['Type'] == 'macromolecular': styleChoice = [' ','lines','vdW balls','sticks','balls & sticks','ellipsoids', 'backbone','ribbons','schematic'] dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom drawing style',styleChoice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = styleChoice[sel] for r in indx: atomData[r][cs] = parms drawAtoms.SetCellValue(r,cs,parms) dlg.Destroy() FindBondsDraw() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def DrawAtomLabel(event): indx = drawAtoms.GetSelectedRows() if indx: generalData = data['General'] atomData = data['Drawing']['Atoms'] cx,ct,cs,ci = data['Drawing']['atomPtrs'] styleChoice = [' ','type','name','number'] if generalData['Type'] == 'macromolecular': styleChoice = [' ','type','name','number','residue','1-letter','chain'] dlg = wx.SingleChoiceDialog(G2frame,'Select','Atom label style',styleChoice) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() parms = styleChoice[sel] for r in indx: atomData[r][cs+1] = parms drawAtoms.SetCellValue(r,cs+1,parms) dlg.Destroy() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def DrawAtomColor(event): indx = drawAtoms.GetSelectedRows() if indx: if len(indx) > 1: G2frame.dataFrame.SetStatusText('Select Custom Color, change color, Add to Custom Colors, then OK') else: G2frame.dataFrame.SetStatusText('Change color, Add to Custom Colors, then OK') generalData = data['General'] atomData = data['Drawing']['Atoms'] cx,ct,cs,ci = data['Drawing']['atomPtrs'] atmColors = [] atmTypes = [] for r in indx: if atomData[r][cs+2] not in atmColors: atmColors.append(atomData[r][cs+2]) atmTypes.append(atomData[r][ct]) if len(atmColors) > 16: break colors = wx.ColourData() colors.SetChooseFull(True) dlg = wx.ColourDialog(G2frame) if dlg.ShowModal() == wx.ID_OK: for i in range(len(atmColors)): atmColors[i] = dlg.GetColourData().GetColour() colorDict = dict(zip(atmTypes,atmColors)) for r in indx: color = colorDict[atomData[r][ct]] atomData[r][cs+2] = color attr = wg.GridCellAttr() #needs to be here - gets lost if outside loop! attr.SetBackgroundColour(color) drawAtoms.SetAttr(r,cs+2,attr) data['Drawing']['Atoms'][r][cs+2] = color drawAtoms.ClearSelection() dlg.Destroy() G2frame.dataFrame.SetStatusText('') G2plt.PlotStructure(G2frame,data) def ResetAtomColors(event): generalData = data['General'] atomData = data['Drawing']['Atoms'] cx,ct,cs,ci = data['Drawing']['atomPtrs'] for atom in atomData: atNum = generalData['AtomTypes'].index(atom[ct]) atom[cs+2] = list(generalData['Color'][atNum]) UpdateDrawAtoms() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def SetViewPoint(event): indx = drawAtoms.GetSelectedRows() if indx: atomData = data['Drawing']['Atoms'] cx = data['Drawing']['atomPtrs'][0] data['Drawing']['viewPoint'] = [atomData[indx[0]][cx:cx+3],[indx[0],0]] drawAtoms.ClearSelection() #do I really want to do this? G2plt.PlotStructure(G2frame,data) def noDuplicate(xyz,atomData): #be careful where this is used - it's slow cx = data['Drawing']['atomPtrs'][0] if True in [np.allclose(np.array(xyz),np.array(atom[cx:cx+3]),atol=0.0002) for atom in atomData]: return False else: return True def AddSymEquiv(event): indx = drawAtoms.GetSelectedRows() indx.sort() if indx: colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] cx = colLabels.index('x') cuia = colLabels.index('I/A') cuij = cuia+2 atomData = data['Drawing']['Atoms'] generalData = data['General'] SGData = generalData['SGData'] dlg = G2gd.SymOpDialog(G2frame,SGData,False,True) try: if dlg.ShowModal() == wx.ID_OK: Inv,Cent,Opr,Cell,New,Force = dlg.GetSelection() Cell = np.array(Cell) cent = SGData['SGCen'][Cent] M,T = SGData['SGOps'][Opr] for ind in indx: XYZ = np.array(atomData[ind][cx:cx+3]) XYZ = np.inner(M,XYZ)+T if Inv: XYZ = -XYZ XYZ = XYZ+cent+Cell if Force: XYZ = G2spc.MoveToUnitCell(XYZ) if noDuplicate(XYZ,atomData): atom = copy.copy(atomData[ind]) atom[cx:cx+3] = XYZ atomOp = atom[cx+3] newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \ str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2])) atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData) if atom[cuia] == 'A': Uij = atom[cuij:cuij+6] U = G2spc.Uij2U(Uij) U = np.inner(np.inner(M,U),M) Uij = G2spc.U2Uij(U) atom[cuij:cuij+6] = Uij atomData.append(atom) finally: dlg.Destroy() UpdateDrawAtoms() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def TransformSymEquiv(event): indx = drawAtoms.GetSelectedRows() indx.sort() if indx: atomData = data['Drawing']['Atoms'] colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] cx = colLabels.index('x') cuia = colLabels.index('I/A') cuij = cuia+2 atomData = data['Drawing']['Atoms'] generalData = data['General'] SGData = generalData['SGData'] dlg = G2gd.SymOpDialog(G2frame,SGData,False,True) try: if dlg.ShowModal() == wx.ID_OK: Inv,Cent,Opr,Cell,New,Force = dlg.GetSelection() Cell = np.array(Cell) cent = SGData['SGCen'][Cent] M,T = SGData['SGOps'][Opr] for ind in indx: XYZ = np.array(atomData[ind][cx:cx+3]) XYZ = np.inner(M,XYZ)+T if Inv: XYZ = -XYZ XYZ = XYZ+cent+Cell if Force: XYZ = G2spc.MoveToUnitCell(XYZ) atom = atomData[ind] atom[cx:cx+3] = XYZ atomOp = atom[cx+3] newOp = str(((Opr+1)+100*Cent)*(1-2*Inv))+'+'+ \ str(int(Cell[0]))+','+str(int(Cell[1]))+','+str(int(Cell[2])) atom[cx+3] = G2spc.StringOpsProd(atomOp,newOp,SGData) if atom[cuia] == 'A': Uij = atom[cuij:cuij+6] U = G2spc.Uij2U(Uij) U = np.inner(np.inner(M,U),M) Uij = G2spc.U2Uij(U) atom[cuij:cuij+6] = Uij data['Drawing']['Atoms'] = atomData finally: dlg.Destroy() UpdateDrawAtoms() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def FillCoordSphere(event): generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) radii = generalData['BondRadii'] atomTypes = generalData['AtomTypes'] try: indH = atomTypes.index('H') radii[indH] = 0.5 except: pass indx = drawAtoms.GetSelectedRows() if indx: indx.sort() atomData = data['Drawing']['Atoms'] numAtoms = len(atomData) cx,ct,cs,ci = data['Drawing']['atomPtrs'] generalData = data['General'] SGData = generalData['SGData'] cellArray = G2lat.CellBlock(1) wx.BeginBusyCursor() try: for ind in indx: atomA = atomData[ind] xyzA = np.array(atomA[cx:cx+3]) indA = atomTypes.index(atomA[ct]) for atomB in atomData[:numAtoms]: indB = atomTypes.index(atomB[ct]) sumR = radii[indA]+radii[indB] xyzB = np.array(atomB[cx:cx+3]) for xyz in cellArray+xyzB: dist = np.sqrt(np.sum(np.inner(Amat,xyz-xyzA)**2)) if 0 < dist <= data['Drawing']['radiusFactor']*sumR: if noDuplicate(xyz,atomData): oprB = atomB[cx+3] C = xyz-xyzB newOp = '1+'+str(int(round(C[0])))+','+str(int(round(C[1])))+','+str(int(round(C[2]))) newAtom = atomB[:] newAtom[cx:cx+3] = xyz newAtom[cx+3] = G2spc.StringOpsProd(oprB,newOp,SGData) atomData.append(newAtom) finally: wx.EndBusyCursor() data['Drawing']['Atoms'] = atomData UpdateDrawAtoms() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def FillUnitCell(event): indx = drawAtoms.GetSelectedRows() indx.sort() if indx: atomData = data['Drawing']['Atoms'] colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] cx = colLabels.index('x') cuia = colLabels.index('I/A') cuij = cuia+2 generalData = data['General'] SGData = generalData['SGData'] wx.BeginBusyCursor() try: for ind in indx: atom = atomData[ind] XYZ = np.array(atom[cx:cx+3]) if atom[cuia] == 'A': Uij = atom[cuij:cuij+6] result = G2spc.GenAtom(XYZ,SGData,False,Uij,False) for item in result: atom = copy.copy(atomData[ind]) atom[cx:cx+3] = item[0] atom[cx+3] = str(item[2])+'+' \ +str(item[3][0])+','+str(item[3][1])+','+str(item[3][2]) atom[cuij:cuij+6] = item[1] Opp = G2spc.Opposite(item[0]) for xyz in Opp: if noDuplicate(xyz,atomData): cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32) cell = '1'+'+'+ \ str(cell[0])+','+str(cell[1])+','+str(cell[2]) atom[cx:cx+3] = xyz atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData) atomData.append(atom[:]) else: result = G2spc.GenAtom(XYZ,SGData,False,Move=False) for item in result: atom = copy.copy(atomData[ind]) atom[cx:cx+3] = item[0] atom[cx+3] = str(item[1])+'+' \ +str(item[2][0])+','+str(item[2][1])+','+str(item[2][2]) Opp = G2spc.Opposite(item[0]) for xyz in Opp: if noDuplicate(xyz,atomData): cell = np.asarray(np.rint(xyz-atom[cx:cx+3]),dtype=np.int32) cell = '1'+'+'+ \ str(cell[0])+','+str(cell[1])+','+str(cell[2]) atom[cx:cx+3] = xyz atom[cx+3] = G2spc.StringOpsProd(cell,atom[cx+3],SGData) atomData.append(atom[:]) data['Drawing']['Atoms'] = atomData finally: wx.EndBusyCursor() UpdateDrawAtoms() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def FindBondsToo(): #works but slow for large structures - keep as reference cx,ct,cs,ci = data['Drawing']['atomPtrs'] atomData = data['Drawing']['Atoms'] generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) radii = generalData['BondRadii'] atomTypes = generalData['AtomTypes'] try: indH = atomTypes.index('H') radii[indH] = 0.5 except: pass for atom in atomData: atom[-1] = [] Atoms = [] for i,atom in enumerate(atomData): Atoms.append([i,np.array(atom[cx:cx+3]),atom[cs],radii[atomTypes.index(atom[ct])]]) for atomA in Atoms: if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']: for atomB in Atoms: Dx = atomB[1]-atomA[1] DX = np.inner(Amat,Dx) dist = np.sqrt(np.sum(DX**2)) sumR = atomA[3]+atomB[3] if 0.5 < dist <= 0.85*sumR: i = atomA[0] if atomA[2] == 'polyhedra': atomData[i][-1].append(DX) elif atomB[1] != 'polyhedra': j = atomB[0] atomData[i][-1].append(Dx*atomA[3]/sumR) atomData[j][-1].append(-Dx*atomB[3]/sumR) def FindBondsDraw(): #uses numpy & masks - very fast even for proteins! import numpy.ma as ma cx,ct,cs,ci = data['Drawing']['atomPtrs'] hydro = data['Drawing']['showHydrogen'] atomData = data['Drawing']['Atoms'] generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) radii = generalData['BondRadii'] atomTypes = generalData['AtomTypes'] try: indH = atomTypes.index('H') radii[indH] = 0.5 except: pass for atom in atomData: atom[-2] = [] #clear out old bonds/polyhedra atom[-1] = [] Indx = range(len(atomData)) Atoms = [] Styles = [] Radii = [] for atom in atomData: Atoms.append(np.array(atom[cx:cx+3])) Styles.append(atom[cs]) try: if not hydro and atom[ct] == 'H': Radii.append(0.0) else: Radii.append(radii[atomTypes.index(atom[ct])]) except ValueError: #changed atom type! Radii.append(0.20) Atoms = np.array(Atoms) Radii = np.array(Radii) IASR = zip(Indx,Atoms,Styles,Radii) for atomA in IASR: if atomA[2] in ['lines','sticks','ellipsoids','balls & sticks','polyhedra']: Dx = Atoms-atomA[1] dist = ma.masked_less(np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)),0.5) #gets rid of G2frame & disorder "bonds" < 0.5A sumR = atomA[3]+Radii IndB = ma.nonzero(ma.masked_greater(dist-data['Drawing']['radiusFactor']*sumR,0.)) #get indices of bonded atoms i = atomA[0] for j in IndB[0]: if Styles[i] == 'polyhedra': atomData[i][-2].append(np.inner(Amat,Dx[j])) elif Styles[j] != 'polyhedra' and j > i: atomData[i][-2].append(Dx[j]*Radii[i]/sumR[j]) atomData[j][-2].append(-Dx[j]*Radii[j]/sumR[j]) if Styles[i] == 'polyhedra': Bonds = atomData[i][-2] Faces = [] if len(Bonds) > 2: FaceGen = G2lat.uniqueCombinations(Bonds,3) #N.B. this is a generator for face in FaceGen: vol = nl.det(face) if abs(vol) > 1. or len(Bonds) == 3: if vol < 0.: face = [face[0],face[2],face[1]] face = np.array(face) if not np.array([np.array(nl.det(face-bond))+0.0001 < 0 for bond in Bonds]).any(): norm = np.cross(face[1]-face[0],face[2]-face[0]) norm /= np.sqrt(np.sum(norm**2)) Faces.append([face,norm]) atomData[i][-1] = Faces def DrawAtomsDelete(event): indx = drawAtoms.GetSelectedRows() indx.sort() if indx: atomData = data['Drawing']['Atoms'] indx.reverse() for ind in indx: del atomData[ind] UpdateDrawAtoms() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) event.StopPropagation() def OnReloadDrawAtoms(event): data['Drawing']['Atoms'] = [] UpdateDrawAtoms() drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) event.StopPropagation() def DrawAtomsDeleteByIDs(IDs): atomData = data['Drawing']['Atoms'] indx = G2mth.FindAtomIndexByIDs(atomData,IDs) indx.reverse() for ind in indx: del atomData[ind] def ChangeDrawAtomsByIDs(colName,IDs,value): atomData = data['Drawing']['Atoms'] cx,ct,cs,ci = data['Drawing']['atomPtrs'] if colName == 'Name': col = ct-1 elif colName == 'Type': col = ct elif colName == 'I/A': col = cs indx = G2mth.FindAtomIndexByIDs(atomData,IDs) for ind in indx: atomData[ind][col] = value def OnDrawPlane(event): indx = drawAtoms.GetSelectedRows() if len(indx) < 4: print '**** ERROR - need 4+ atoms for plane calculation' return PlaneData = {} drawingData = data['Drawing'] atomData = drawingData['Atoms'] colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] cx = colLabels.index('x') cn = colLabels.index('Name') xyz = [] for i,atom in enumerate(atomData): if i in indx: xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+3]) generalData = data['General'] PlaneData['Name'] = generalData['Name'] PlaneData['Atoms'] = xyz PlaneData['Cell'] = generalData['Cell'][1:] #+ volume G2str.BestPlane(PlaneData) def OnDrawDistVP(event): # distance to view point indx = drawAtoms.GetSelectedRows() if not indx: print '***** ERROR - no atoms selected' return generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) drawingData = data['Drawing'] viewPt = np.array(drawingData['viewPoint'][0]) print ' Distance from view point at %.3f %.3f %.3f to:'%(viewPt[0],viewPt[1],viewPt[2]) atomDData = drawingData['Atoms'] colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] cx = colLabels.index('x') cn = colLabels.index('Name') for i in indx: atom = atomDData[i] Dx = np.array(atom[cx:cx+3])-viewPt dist = np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)) print 'Atom: %8s (%12s) distance = %.3f'%(atom[cn],atom[cx+3],dist) def OnDrawDAT(event): #distance, angle, torsion indx = drawAtoms.GetSelectedRows() if len(indx) not in [2,3,4]: print '**** ERROR - wrong number of atoms for distance, angle or torsion calculation' return DATData = {} ocx,oct,ocs,cia = data['General']['AtomPtrs'] drawingData = data['Drawing'] atomData = data['Atoms'] atomDData = drawingData['Atoms'] colLabels = [drawAtoms.GetColLabelValue(c) for c in range(drawAtoms.GetNumberCols())] cx = colLabels.index('x') cn = colLabels.index('Name') cid = colLabels.index('I/A')+8 xyz = [] Oxyz = [] DATData['Natoms'] = len(indx) for i in indx: atom = atomDData[i] xyz.append([i,]+atom[cn:cn+2]+atom[cx:cx+4]) #also gets Sym Op id = G2mth.FindAtomIndexByIDs(atomData,[atom[cid],],False)[0] Oxyz.append([id,]+atomData[id][cx+1:cx+4]) DATData['Datoms'] = xyz DATData['Oatoms'] = Oxyz generalData = data['General'] DATData['Name'] = generalData['Name'] DATData['SGData'] = generalData['SGData'] DATData['Cell'] = generalData['Cell'][1:] #+ volume if 'pId' in data: DATData['pId'] = data['pId'] DATData['covData'] = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,G2frame.root, 'Covariance')) G2str.DisAglTor(DATData) ################################################################################ #### Draw Options page ################################################################################ def UpdateDrawOptions(): import copy import wx.lib.colourselect as wcs def SlopSizer(): def OnCameraPos(event): drawingData['cameraPos'] = cameraPos.GetValue() cameraPosTxt.SetLabel(' Camera Distance: '+'%.2f'%(drawingData['cameraPos'])) ZclipTxt.SetLabel(' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.)) G2plt.PlotStructure(G2frame,data) def OnZclip(event): drawingData['Zclip'] = Zclip.GetValue() ZclipTxt.SetLabel(' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.)) G2plt.PlotStructure(G2frame,data) def OnZstep(event): try: step = float(Zstep.GetValue()) if not (0.01 <= step <= 1.0): raise ValueError except ValueError: step = drawingData['Zstep'] drawingData['Zstep'] = step Zstep.SetValue('%.2fA'%(drawingData['Zstep'])) def OnMoveZ(event): move = MoveZ.GetValue()*drawingData['Zstep'] MoveZ.SetValue(0) VP = np.inner(Amat,np.array(drawingData['viewPoint'][0])) VD = np.inner(Amat,np.array(drawingData['viewDir'])) VD /= np.sqrt(np.sum(VD**2)) VP += move*VD VP = np.inner(Bmat,VP) drawingData['viewPoint'][0] = VP panel = drawOptions.GetChildren() names = [child.GetName() for child in panel] panel[names.index('viewPoint')].SetValue('%.3f %.3f %.3f'%(VP[0],VP[1],VP[2])) G2plt.PlotStructure(G2frame,data) def OnVdWScale(event): drawingData['vdwScale'] = vdwScale.GetValue()/100. vdwScaleTxt.SetLabel(' van der Waals scale: '+'%.2f'%(drawingData['vdwScale'])) G2plt.PlotStructure(G2frame,data) def OnEllipseProb(event): drawingData['ellipseProb'] = ellipseProb.GetValue() ellipseProbTxt.SetLabel(' Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb'])) G2plt.PlotStructure(G2frame,data) def OnBallScale(event): drawingData['ballScale'] = ballScale.GetValue()/100. ballScaleTxt.SetLabel(' Ball scale: '+'%.2f'%(drawingData['ballScale'])) G2plt.PlotStructure(G2frame,data) def OnBondRadius(event): drawingData['bondRadius'] = bondRadius.GetValue()/100. bondRadiusTxt.SetLabel(' Bond radius, A: '+'%.2f'%(drawingData['bondRadius'])) G2plt.PlotStructure(G2frame,data) def OnContourLevel(event): drawingData['contourLevel'] = contourLevel.GetValue()/100. contourLevelTxt.SetLabel(' Contour level: '+'%.2f'%(drawingData['contourLevel']*generalData['Map']['rhoMax'])) G2plt.PlotStructure(G2frame,data) def OnMapSize(event): drawingData['mapSize'] = mapSize.GetValue()/10. mapSizeTxt.SetLabel(' Map radius, A: '+'%.1f'%(drawingData['mapSize'])) G2plt.PlotStructure(G2frame,data) slopSizer = wx.BoxSizer(wx.HORIZONTAL) slideSizer = wx.FlexGridSizer(7,2) slideSizer.AddGrowableCol(1,1) cameraPosTxt = wx.StaticText(drawOptions,-1, ' Camera Distance: '+'%.2f'%(drawingData['cameraPos']),name='cameraPos') G2frame.dataDisplay.cameraPosTxt = cameraPosTxt slideSizer.Add(cameraPosTxt,0,wx.ALIGN_CENTER_VERTICAL) cameraPos = wx.Slider(drawOptions,style=wx.SL_HORIZONTAL,value=drawingData['cameraPos'],name='cameraSlider') cameraPos.SetRange(10,500) cameraPos.Bind(wx.EVT_SLIDER, OnCameraPos) G2frame.dataDisplay.cameraSlider = cameraPos slideSizer.Add(cameraPos,1,wx.EXPAND|wx.RIGHT) ZclipTxt = wx.StaticText(drawOptions,-1,' Z clipping: '+'%.2fA'%(drawingData['Zclip']*drawingData['cameraPos']/100.)) slideSizer.Add(ZclipTxt,0,wx.ALIGN_CENTER_VERTICAL) Zclip = wx.Slider(drawOptions,style=wx.SL_HORIZONTAL,value=drawingData['Zclip']) Zclip.SetRange(1,99) Zclip.Bind(wx.EVT_SLIDER, OnZclip) slideSizer.Add(Zclip,1,wx.EXPAND|wx.RIGHT) ZstepSizer = wx.BoxSizer(wx.HORIZONTAL) ZstepSizer.Add(wx.StaticText(drawOptions,-1,' Z step:'),0,wx.ALIGN_CENTER_VERTICAL) Zstep = wx.TextCtrl(drawOptions,value='%.2f'%(drawingData['Zstep']), style=wx.TE_PROCESS_ENTER) Zstep.Bind(wx.EVT_TEXT_ENTER,OnZstep) Zstep.Bind(wx.EVT_KILL_FOCUS,OnZstep) ZstepSizer.Add(Zstep,0,wx.ALIGN_CENTER_VERTICAL) slideSizer.Add(ZstepSizer) MoveSizer = wx.BoxSizer(wx.HORIZONTAL) MoveSizer.Add(wx.StaticText(drawOptions,-1,' Press to step:'),0,wx.ALIGN_CENTER_VERTICAL) MoveZ = wx.SpinButton(drawOptions,style=wx.SP_HORIZONTAL,size=wx.Size(100,20)) MoveZ.SetValue(0) MoveZ.SetRange(-1,1) MoveZ.Bind(wx.EVT_SPIN, OnMoveZ) MoveSizer.Add(MoveZ) slideSizer.Add(MoveSizer,1,wx.EXPAND|wx.RIGHT) vdwScaleTxt = wx.StaticText(drawOptions,-1,' van der Waals scale: '+'%.2f'%(drawingData['vdwScale'])) slideSizer.Add(vdwScaleTxt,0,wx.ALIGN_CENTER_VERTICAL) vdwScale = wx.Slider(drawOptions,style=wx.SL_HORIZONTAL,value=int(100*drawingData['vdwScale'])) vdwScale.Bind(wx.EVT_SLIDER, OnVdWScale) slideSizer.Add(vdwScale,1,wx.EXPAND|wx.RIGHT) ellipseProbTxt = wx.StaticText(drawOptions,-1,' Ellipsoid probability: '+'%d%%'%(drawingData['ellipseProb'])) slideSizer.Add(ellipseProbTxt,0,wx.ALIGN_CENTER_VERTICAL) ellipseProb = wx.Slider(drawOptions,style=wx.SL_HORIZONTAL,value=drawingData['ellipseProb']) ellipseProb.SetRange(1,99) ellipseProb.Bind(wx.EVT_SLIDER, OnEllipseProb) slideSizer.Add(ellipseProb,1,wx.EXPAND|wx.RIGHT) ballScaleTxt = wx.StaticText(drawOptions,-1,' Ball scale: '+'%.2f'%(drawingData['ballScale'])) slideSizer.Add(ballScaleTxt,0,wx.ALIGN_CENTER_VERTICAL) ballScale = wx.Slider(drawOptions,style=wx.SL_HORIZONTAL,value=int(100*drawingData['ballScale'])) ballScale.Bind(wx.EVT_SLIDER, OnBallScale) slideSizer.Add(ballScale,1,wx.EXPAND|wx.RIGHT) bondRadiusTxt = wx.StaticText(drawOptions,-1,' Bond radius, A: '+'%.2f'%(drawingData['bondRadius'])) slideSizer.Add(bondRadiusTxt,0,wx.ALIGN_CENTER_VERTICAL) bondRadius = wx.Slider(drawOptions,style=wx.SL_HORIZONTAL,value=int(100*drawingData['bondRadius'])) bondRadius.SetRange(1,25) bondRadius.Bind(wx.EVT_SLIDER, OnBondRadius) slideSizer.Add(bondRadius,1,wx.EXPAND|wx.RIGHT) if generalData['Map']['rhoMax']: contourLevelTxt = wx.StaticText(drawOptions,-1,' Contour level: '+'%.2f'%(drawingData['contourLevel']*generalData['Map']['rhoMax'])) slideSizer.Add(contourLevelTxt,0,wx.ALIGN_CENTER_VERTICAL) contourLevel = wx.Slider(drawOptions,style=wx.SL_HORIZONTAL,value=int(100*drawingData['contourLevel'])) contourLevel.SetRange(1,100) contourLevel.Bind(wx.EVT_SLIDER, OnContourLevel) slideSizer.Add(contourLevel,1,wx.EXPAND|wx.RIGHT) mapSizeTxt = wx.StaticText(drawOptions,-1,' Map radius, A: '+'%.1f'%(drawingData['mapSize'])) slideSizer.Add(mapSizeTxt,0,wx.ALIGN_CENTER_VERTICAL) mapSize = wx.Slider(drawOptions,style=wx.SL_HORIZONTAL,value=int(10*drawingData['mapSize'])) mapSize.SetRange(1,100) mapSize.Bind(wx.EVT_SLIDER, OnMapSize) slideSizer.Add(mapSize,1,wx.EXPAND|wx.RIGHT) slopSizer.Add(slideSizer,1,wx.EXPAND|wx.RIGHT) slopSizer.Add((10,5),0) slopSizer.SetMinSize(wx.Size(350,10)) return slopSizer def ShowSizer(): def OnBackColor(event): drawingData['backColor'] = event.GetValue() G2plt.PlotStructure(G2frame,data) def OnShowABC(event): drawingData['showABC'] = showABC.GetValue() G2plt.PlotStructure(G2frame,data) def OnShowUnitCell(event): drawingData['unitCellBox'] = unitCellBox.GetValue() G2plt.PlotStructure(G2frame,data) def OnShowHyd(event): drawingData['showHydrogen'] = showHydrogen.GetValue() FindBondsDraw() G2plt.PlotStructure(G2frame,data) def OnShowRB(event): drawingData['showRigidBodies'] = showRB.GetValue() FindBondsDraw() G2plt.PlotStructure(G2frame,data) def OnViewPoint(event): Obj = event.GetEventObject() viewPt = Obj.GetValue().split() try: VP = [float(viewPt[i]) for i in range(3)] except (ValueError,IndexError): VP = drawingData['viewPoint'][0] Obj.SetValue('%.3f %.3f %.3f'%(VP[0],VP[1],VP[2])) drawingData['viewPoint'][0] = VP G2plt.PlotStructure(G2frame,data) def OnViewDir(event): Obj = event.GetEventObject() viewDir = Obj.GetValue().split() try: Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) VD = np.array([float(viewDir[i]) for i in range(3)]) VC = np.inner(Amat,VD) VC /= np.sqrt(np.sum(VC**2)) V = np.array(drawingData['viewDir']) VB = np.inner(Amat,V) VB /= np.sqrt(np.sum(VB**2)) VX = np.cross(VC,VB) A = acosd(max((2.-np.sum((VB-VC)**2))/2.,-1.)) QV = G2mth.AVdeg2Q(A,VX) Q = drawingData['Quaternion'] drawingData['Quaternion'] = G2mth.prodQQ(Q,QV) except (ValueError,IndexError): VD = drawingData['viewDir'] Obj.SetValue('%.3f %.3f %.3f'%(VD[0],VD[1],VD[2])) drawingData['viewDir'] = VD G2plt.PlotStructure(G2frame,data) showSizer = wx.BoxSizer(wx.VERTICAL) lineSizer = wx.BoxSizer(wx.HORIZONTAL) lineSizer.Add(wx.StaticText(drawOptions,-1,' Background color:'),0,wx.ALIGN_CENTER_VERTICAL) backColor = wcs.ColourSelect(drawOptions, -1,colour=drawingData['backColor'],size=wx.Size(25,25)) backColor.Bind(wcs.EVT_COLOURSELECT, OnBackColor) lineSizer.Add(backColor,0,wx.ALIGN_CENTER_VERTICAL) lineSizer.Add(wx.StaticText(drawOptions,-1,' View Dir.:'),0,wx.ALIGN_CENTER_VERTICAL) VD = drawingData['viewDir'] viewDir = wx.TextCtrl(drawOptions,value='%.3f %.3f %.3f'%(VD[0],VD[1],VD[2]), style=wx.TE_PROCESS_ENTER,size=wx.Size(140,20),name='viewDir') viewDir.Bind(wx.EVT_TEXT_ENTER,OnViewDir) viewDir.Bind(wx.EVT_KILL_FOCUS,OnViewDir) G2frame.dataDisplay.viewDir = viewDir lineSizer.Add(viewDir,0,wx.ALIGN_CENTER_VERTICAL) showSizer.Add(lineSizer) showSizer.Add((0,5),0) lineSizer = wx.BoxSizer(wx.HORIZONTAL) showABC = wx.CheckBox(drawOptions,-1,label=' Show view point?') showABC.Bind(wx.EVT_CHECKBOX, OnShowABC) showABC.SetValue(drawingData['showABC']) lineSizer.Add(showABC,0,wx.ALIGN_CENTER_VERTICAL) lineSizer.Add(wx.StaticText(drawOptions,-1,' View Point:'),0,wx.ALIGN_CENTER_VERTICAL) VP = drawingData['viewPoint'][0] viewPoint = wx.TextCtrl(drawOptions,value='%.3f %.3f %.3f'%(VP[0],VP[1],VP[2]), style=wx.TE_PROCESS_ENTER,size=wx.Size(140,20),name='viewPoint') G2frame.dataDisplay.viewPoint = viewPoint viewPoint.Bind(wx.EVT_TEXT_ENTER,OnViewPoint) viewPoint.Bind(wx.EVT_KILL_FOCUS,OnViewPoint) lineSizer.Add(viewPoint,0,wx.ALIGN_CENTER_VERTICAL) showSizer.Add(lineSizer) showSizer.Add((0,5),0) line2Sizer = wx.BoxSizer(wx.HORIZONTAL) unitCellBox = wx.CheckBox(drawOptions,-1,label=' Show unit cell?') unitCellBox.Bind(wx.EVT_CHECKBOX, OnShowUnitCell) unitCellBox.SetValue(drawingData['unitCellBox']) line2Sizer.Add(unitCellBox,0,wx.ALIGN_CENTER_VERTICAL) showHydrogen = wx.CheckBox(drawOptions,-1,label=' Show hydrogens?') showHydrogen.Bind(wx.EVT_CHECKBOX, OnShowHyd) showHydrogen.SetValue(drawingData['showHydrogen']) line2Sizer.Add(showHydrogen,0,wx.ALIGN_CENTER_VERTICAL) showRB = wx.CheckBox(drawOptions,-1,label=' Show rigid Bodies?') showRB.Bind(wx.EVT_CHECKBOX, OnShowRB) showRB.SetValue(drawingData['showRigidBodies']) line2Sizer.Add(showRB,0,wx.ALIGN_CENTER_VERTICAL) showSizer.Add(line2Sizer) return showSizer def RadSizer(): def OnSizeHatoms(event): try: value = max(0.1,min(1.2,float(sizeH.GetValue()))) except ValueError: value = 0.5 drawingData['sizeH'] = value sizeH.SetValue("%.2f"%(value)) G2plt.PlotStructure(G2frame,data) def OnRadFactor(event): try: value = max(0.1,min(1.2,float(radFactor.GetValue()))) except ValueError: value = 0.85 drawingData['radiusFactor'] = value radFactor.SetValue("%.2f"%(value)) FindBondsDraw() G2plt.PlotStructure(G2frame,data) radSizer = wx.BoxSizer(wx.HORIZONTAL) radSizer.Add(wx.StaticText(drawOptions,-1,' Hydrogen radius, A: '),0,wx.ALIGN_CENTER_VERTICAL) sizeH = wx.TextCtrl(drawOptions,-1,value='%.2f'%(drawingData['sizeH']),size=wx.Size(60,20),style=wx.TE_PROCESS_ENTER) sizeH.Bind(wx.EVT_TEXT_ENTER,OnSizeHatoms) sizeH.Bind(wx.EVT_KILL_FOCUS,OnSizeHatoms) radSizer.Add(sizeH,0,wx.ALIGN_CENTER_VERTICAL) radSizer.Add(wx.StaticText(drawOptions,-1,' Bond search factor: '),0,wx.ALIGN_CENTER_VERTICAL) radFactor = wx.TextCtrl(drawOptions,value='%.2f'%(drawingData['radiusFactor']),size=wx.Size(60,20),style=wx.TE_PROCESS_ENTER) radFactor.Bind(wx.EVT_TEXT_ENTER,OnRadFactor) radFactor.Bind(wx.EVT_KILL_FOCUS,OnRadFactor) radSizer.Add(radFactor,0,wx.ALIGN_CENTER_VERTICAL) return radSizer # UpdateDrawOptions exectable code starts here generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) SetupDrawingData() drawingData = data['Drawing'] if generalData['Type'] == 'nuclear': pickChoice = ['Atoms','Bonds','Torsions','Planes'] elif generalData['Type'] == 'macromolecular': pickChoice = ['Atoms','Residues','Chains','Bonds','Torsions','Planes','phi/psi'] G2frame.dataFrame.SetStatusText('') if drawOptions.GetSizer(): drawOptions.GetSizer().Clear(True) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add((5,5),0) mainSizer.Add(wx.StaticText(drawOptions,-1,' Drawing controls:'),0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((5,5),0) mainSizer.Add(SlopSizer(),0) mainSizer.Add((5,5),0) mainSizer.Add(ShowSizer(),0,) mainSizer.Add((5,5),0) mainSizer.Add(RadSizer(),0,) drawOptions.SetSizer(mainSizer) if G2frame.dataFrame.PhaseUserSize is None: Size = mainSizer.Fit(G2frame.dataFrame) Size[0] = max(Size[0]+35,500) # leave some extra room and don't get too small Size[1] = max(Size[1]+35,350) #compensate for status bar drawOptions.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) G2frame.dataFrame.setSizePosLeft(Size) else: Size = G2frame.dataFrame.PhaseUserSize drawOptions.SetSize(G2frame.dataFrame.GetClientSize()) Size = mainSizer.ComputeFittingWindowSize(G2frame.dataFrame) drawOptions.SetVirtualSize(Size) drawOptions.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) G2frame.dataFrame.Update() drawOptions.SetSize(G2frame.dataFrame.GetClientSize()) ################################################################################ #### Texture routines ################################################################################ def UpdateTexture(): def SetSHCoef(): cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],SamSym[textureData['Model']],textureData['Order']) newSHCoef = dict(zip(cofNames,np.zeros(len(cofNames)))) SHCoeff = textureData['SH Coeff'][1] for cofName in SHCoeff: if cofName in cofNames: newSHCoef[cofName] = SHCoeff[cofName] return newSHCoef def OnShOrder(event): Obj = event.GetEventObject() textureData['Order'] = int(Obj.GetValue()) textureData['SH Coeff'][1] = SetSHCoef() wx.CallAfter(UpdateTexture) G2plt.PlotTexture(G2frame,data) def OnShModel(event): Obj = event.GetEventObject() textureData['Model'] = Obj.GetValue() textureData['SH Coeff'][1] = SetSHCoef() wx.CallAfter(UpdateTexture) G2plt.PlotTexture(G2frame,data) def OnSHRefine(event): Obj = event.GetEventObject() textureData['SH Coeff'][0] = Obj.GetValue() def OnSHShow(event): Obj = event.GetEventObject() textureData['SHShow'] = Obj.GetValue() wx.CallAfter(UpdateTexture) def OnProjSel(event): Obj = event.GetEventObject() G2frame.Projection = Obj.GetValue() G2plt.PlotTexture(G2frame,data) def OnColorSel(event): Obj = event.GetEventObject() G2frame.ContourColor = Obj.GetValue() G2plt.PlotTexture(G2frame,data) def OnAngRef(event): Obj = event.GetEventObject() textureData[angIndx[Obj.GetId()]][0] = Obj.GetValue() def OnAngValue(event): Obj = event.GetEventObject() try: value = float(Obj.GetValue()) except ValueError: value = textureData[valIndx[Obj.GetId()]][1] Obj.SetValue('%8.2f'%(value)) textureData[valIndx[Obj.GetId()]][1] = value def OnODFValue(event): Obj = event.GetEventObject() try: value = float(Obj.GetValue()) except ValueError: value = textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] Obj.SetValue('%8.3f'%(value)) textureData['SH Coeff'][1][ODFIndx[Obj.GetId()]] = value G2plt.PlotTexture(G2frame,data) def OnPfType(event): Obj = event.GetEventObject() textureData['PlotType'] = Obj.GetValue() wx.CallAfter(UpdateTexture) G2plt.PlotTexture(G2frame,data) def OnPFValue(event): Obj = event.GetEventObject() Saxis = Obj.GetValue().split() if textureData['PlotType'] in ['Pole figure','Axial pole distribution']: try: hkl = [int(Saxis[i]) for i in range(3)] except (ValueError,IndexError): hkl = textureData['PFhkl'] if not np.any(np.array(hkl)): #can't be all zeros! hkl = textureData['PFhkl'] Obj.SetValue('%d %d %d'%(hkl[0],hkl[1],hkl[2])) textureData['PFhkl'] = hkl else: try: xyz = [float(Saxis[i]) for i in range(3)] except (ValueError,IndexError): xyz = textureData['PFxyz'] if not np.any(np.array(xyz)): #can't be all zeros! xyz = textureData['PFxyz'] Obj.SetValue('%3.1f %3.1f %3.1f'%(xyz[0],xyz[1],xyz[2])) textureData['PFxyz'] = xyz G2plt.PlotTexture(G2frame,data) # UpdateTexture executable starts here G2frame.dataFrame.SetStatusText('') generalData = data['General'] SGData = generalData['SGData'] try: textureData = generalData['SH Texture'] except KeyError: #fix old files! textureData = generalData['SH Texture'] = {'Order':0,'Model':'cylindrical', 'Sample omega':[False,0.0],'Sample chi':[False,0.0],'Sample phi':[False,0.0], 'SH Coeff':[False,{}],'SHShow':False,'PFhkl':[0,0,1], 'PFxyz':[0,0,1.],'PlotType':'Pole figure'} if 'SHShow' not in textureData: #another fix textureData.update({'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1.],'PlotType':'Pole figure'}) try: #another fix! x = textureData['PlotType'] except KeyError: textureData.update({'PFxyz':[0,0,1.],'PlotType':'Pole figure'}) shModels = ['cylindrical','none','shear - 2/m','rolling - mmm'] SamSym = dict(zip(shModels,['0','-1','2/m','mmm'])) if generalData['doPawley'] and G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequental results'): G2frame.dataFrame.RefineTexture.Enable(True) shAngles = ['omega','chi','phi'] if Texture.GetSizer(): Texture.GetSizer().Clear(True) mainSizer = wx.BoxSizer(wx.VERTICAL) titleSizer = wx.BoxSizer(wx.HORIZONTAL) titleSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonics texture data for '+PhaseName+':'),0,wx.ALIGN_CENTER_VERTICAL) titleSizer.Add(wx.StaticText(Texture,-1, ' Texture Index J = %7.3f'%(G2lat.textureIndex(textureData['SH Coeff'][1]))), 0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add(titleSizer,0) mainSizer.Add((0,5),0) shSizer = wx.FlexGridSizer(1,6,5,5) shSizer.Add(wx.StaticText(Texture,-1,'Texture model: '),0,wx.ALIGN_CENTER_VERTICAL) shModel = wx.ComboBox(Texture,-1,value=textureData['Model'],choices=shModels, style=wx.CB_READONLY|wx.CB_DROPDOWN) shModel.Bind(wx.EVT_COMBOBOX,OnShModel) shSizer.Add(shModel,0,wx.ALIGN_CENTER_VERTICAL) shSizer.Add(wx.StaticText(Texture,-1,' Harmonic order: '),0,wx.ALIGN_CENTER_VERTICAL) shOrder = wx.ComboBox(Texture,-1,value=str(textureData['Order']),choices=[str(2*i) for i in range(18)], style=wx.CB_READONLY|wx.CB_DROPDOWN) shOrder.Bind(wx.EVT_COMBOBOX,OnShOrder) shSizer.Add(shOrder,0,wx.ALIGN_CENTER_VERTICAL) shRef = wx.CheckBox(Texture,-1,label=' Refine texture?') shRef.SetValue(textureData['SH Coeff'][0]) shRef.Bind(wx.EVT_CHECKBOX, OnSHRefine) shSizer.Add(shRef,0,wx.ALIGN_CENTER_VERTICAL) shShow = wx.CheckBox(Texture,-1,label=' Show coeff.?') shShow.SetValue(textureData['SHShow']) shShow.Bind(wx.EVT_CHECKBOX, OnSHShow) shSizer.Add(shShow,0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add(shSizer,0,0) mainSizer.Add((0,5),0) PTSizer = wx.FlexGridSizer(2,4,5,5) PTSizer.Add(wx.StaticText(Texture,-1,' Texture plot type: '),0,wx.ALIGN_CENTER_VERTICAL) choices = ['Axial pole distribution','Pole figure','Inverse pole figure'] pfType = wx.ComboBox(Texture,-1,value=str(textureData['PlotType']),choices=choices, style=wx.CB_READONLY|wx.CB_DROPDOWN) pfType.Bind(wx.EVT_COMBOBOX,OnPfType) PTSizer.Add(pfType,0,wx.ALIGN_CENTER_VERTICAL) if 'Axial' not in textureData['PlotType']: PTSizer.Add(wx.StaticText(Texture,-1,' Projection type: '),0,wx.ALIGN_CENTER_VERTICAL) projSel = wx.ComboBox(Texture,-1,value=G2frame.Projection,choices=['equal area','stereographic','3D display'], style=wx.CB_READONLY|wx.CB_DROPDOWN) projSel.Bind(wx.EVT_COMBOBOX,OnProjSel) PTSizer.Add(projSel,0,wx.ALIGN_CENTER_VERTICAL) if textureData['PlotType'] in ['Pole figure','Axial pole distribution']: PTSizer.Add(wx.StaticText(Texture,-1,' Pole figure HKL: '),0,wx.ALIGN_CENTER_VERTICAL) PH = textureData['PFhkl'] pfVal = wx.TextCtrl(Texture,-1,'%d %d %d'%(PH[0],PH[1],PH[2]),style=wx.TE_PROCESS_ENTER) else: PTSizer.Add(wx.StaticText(Texture,-1,' Inverse pole figure XYZ: '),0,wx.ALIGN_CENTER_VERTICAL) PX = textureData['PFxyz'] pfVal = wx.TextCtrl(Texture,-1,'%3.1f %3.1f %3.1f'%(PX[0],PX[1],PX[2]),style=wx.TE_PROCESS_ENTER) pfVal.Bind(wx.EVT_TEXT_ENTER,OnPFValue) pfVal.Bind(wx.EVT_KILL_FOCUS,OnPFValue) PTSizer.Add(pfVal,0,wx.ALIGN_CENTER_VERTICAL) if 'Axial' not in textureData['PlotType']: PTSizer.Add(wx.StaticText(Texture,-1,' Color scheme'),0,wx.ALIGN_CENTER_VERTICAL) choice = [m for m in mpl.cm.datad.keys() if not m.endswith("_r")] choice.sort() colorSel = wx.ComboBox(Texture,-1,value=G2frame.ContourColor,choices=choice, style=wx.CB_READONLY|wx.CB_DROPDOWN) colorSel.Bind(wx.EVT_COMBOBOX,OnColorSel) PTSizer.Add(colorSel,0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add(PTSizer,0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((0,5),0) if textureData['SHShow']: mainSizer.Add(wx.StaticText(Texture,-1,'Spherical harmonic coefficients: '),0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((0,5),0) ODFSizer = wx.FlexGridSizer(2,8,2,2) ODFIndx = {} ODFkeys = textureData['SH Coeff'][1].keys() ODFkeys.sort() for item in ODFkeys: ODFSizer.Add(wx.StaticText(Texture,-1,item),0,wx.ALIGN_CENTER_VERTICAL) ODFval = wx.TextCtrl(Texture,wx.ID_ANY,'%8.3f'%(textureData['SH Coeff'][1][item]),style=wx.TE_PROCESS_ENTER) ODFIndx[ODFval.GetId()] = item ODFval.Bind(wx.EVT_TEXT_ENTER,OnODFValue) ODFval.Bind(wx.EVT_KILL_FOCUS,OnODFValue) ODFSizer.Add(ODFval,0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add(ODFSizer,0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((0,5),0) mainSizer.Add((0,5),0) mainSizer.Add(wx.StaticText(Texture,-1,'Sample orientation angles: '),0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((0,5),0) angSizer = wx.BoxSizer(wx.HORIZONTAL) angIndx = {} valIndx = {} for item in ['Sample omega','Sample chi','Sample phi']: angRef = wx.CheckBox(Texture,-1,label=item+': ') angRef.SetValue(textureData[item][0]) angIndx[angRef.GetId()] = item angRef.Bind(wx.EVT_CHECKBOX, OnAngRef) angSizer.Add(angRef,0,wx.ALIGN_CENTER_VERTICAL) angVal = wx.TextCtrl(Texture,wx.ID_ANY,'%8.2f'%(textureData[item][1]),style=wx.TE_PROCESS_ENTER) valIndx[angVal.GetId()] = item angVal.Bind(wx.EVT_TEXT_ENTER,OnAngValue) angVal.Bind(wx.EVT_KILL_FOCUS,OnAngValue) angSizer.Add(angVal,0,wx.ALIGN_CENTER_VERTICAL) angSizer.Add((5,0),0) mainSizer.Add(angSizer,0,wx.ALIGN_CENTER_VERTICAL) Texture.SetSizer(mainSizer,True) if G2frame.dataFrame.PhaseUserSize is None: mainSizer.Fit(G2frame.dataFrame) Size = mainSizer.GetMinSize() Size[0] += 40 Size[1] = max(Size[1],250) + 35 Texture.SetSize(Size) Texture.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) Size[1] = min(Size[1],450) G2frame.dataFrame.setSizePosLeft(Size) else: Size = G2frame.dataFrame.PhaseUserSize Texture.SetSize(G2frame.dataFrame.GetClientSize()) Texture.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) G2frame.dataFrame.Update() ################################################################################ ##### DData routines - GUI stuff in GSASIIddataGUI.py ################################################################################ def OnHklfAdd(event): UseList = data['Histograms'] keyList = UseList.keys() TextList = [] if G2frame.PatternTree.GetCount(): item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root) while item: name = G2frame.PatternTree.GetItemText(item) if name not in keyList and 'HKLF' in name: TextList.append(name) item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie) dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE) try: if dlg.ShowModal() == wx.ID_OK: result = dlg.GetSelections() for i in result: histoName = TextList[i] UseList[histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True], 'Babinet':{'BabA':[0.0,False],'BabU':[0.0,False]}, 'Extinction':['Lorentzian','None', {'Tbar':0.1,'Cos2TM':0.955,'Eg':[1.e-10,False],'Es':[1.e-10,False],'Ep':[1.e-10,False]},]} wx.BeginBusyCursor() UpdateHKLFdata(histoName) wx.EndBusyCursor() data['Histograms'] = UseList wx.CallAfter(G2ddG.UpdateDData,G2frame,DData,data) finally: dlg.Destroy() def UpdateHKLFdata(histoName): generalData = data['General'] Id = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName) reflData = G2frame.PatternTree.GetItemPyData(Id)[1] SGData = generalData['SGData'] Cell = generalData['Cell'][1:7] G,g = G2lat.cell2Gmat(Cell) for ref in reflData: H = ref[:3] ref[4] = np.sqrt(1./G2lat.calc_rDsq2(H,G)) iabsnt,ref[3],ref[11],ref[12] = G2spc.GenHKLf(H,SGData) G2frame.PatternTree.SetItemPyData(Id,[histoName,reflData]) def OnPwdrAdd(event): generalData = data['General'] SGData = generalData['SGData'] UseList = data['Histograms'] newList = [] NShkl = len(G2spc.MustrainNames(SGData)) NDij = len(G2spc.HStrainNames(SGData)) keyList = UseList.keys() TextList = ['All PWDR'] if G2frame.PatternTree.GetCount(): item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root) while item: name = G2frame.PatternTree.GetItemText(item) if name not in keyList and 'PWDR' in name: TextList.append(name) item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie) dlg = wx.MultiChoiceDialog(G2frame, 'Which new data to use?', 'Use data', TextList, wx.CHOICEDLG_STYLE) try: if dlg.ShowModal() == wx.ID_OK: result = dlg.GetSelections() for i in result: newList.append(TextList[i]) if 'All PWDR' in newList: newList = TextList[1:] for histoName in newList: pId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,histoName) UseList[histoName] = {'Histogram':histoName,'Show':False, 'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{}], 'Size':['isotropic',[1.,1.,1.],[False,False,False],[0,0,1], [1.,1.,1.,0.,0.,0.],6*[False,]], 'Mustrain':['isotropic',[1000.0,1000.0,1.0],[False,False,False],[0,0,1], NShkl*[0.01,],NShkl*[False,]], 'HStrain':[NDij*[0.0,],NDij*[False,]], 'Extinction':[0.0,False],'Babinet':{'BabA':[0.0,False],'BabU':[0.0,False]}} refList = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,pId,'Reflection Lists')) refList[generalData['Name']] = [] data['Histograms'] = UseList wx.CallAfter(G2ddG.UpdateDData,G2frame,DData,data) finally: dlg.Destroy() def OnDataDelete(event): UseList = data['Histograms'] keyList = ['All',]+UseList.keys() keyList.sort() DelList = [] if UseList: DelList = [] dlg = wx.MultiChoiceDialog(G2frame, 'Which histogram to delete from this phase?', 'Delete histogram', keyList, wx.CHOICEDLG_STYLE) try: if dlg.ShowModal() == wx.ID_OK: result = dlg.GetSelections() for i in result: DelList.append(keyList[i]) if 'All' in DelList: DelList = keyList[1:] for i in DelList: del UseList[i] wx.CallAfter(G2ddG.UpdateDData,G2frame,DData,data) finally: dlg.Destroy() ################################################################################ ##### Rigid bodies ################################################################################ def FillRigidBodyGrid(refresh=True): '''Fill the Rigid Body Phase information tab page. Note that the page is a ScrolledWindow, not a Grid ''' def OnThermSel(event): #needs to be seen by VecRbSizer! Obj = event.GetEventObject() RBObj = Indx[Obj.GetId()] val = Obj.GetValue() if val == 'Uiso': RBObj['ThermalMotion'][0] = 'Uiso' elif val == 'T': RBObj['ThermalMotion'][0] = 'T' elif val == 'TL': RBObj['ThermalMotion'][0] = 'TL' elif val == 'TLS': RBObj['ThermalMotion'][0] = 'TLS' wx.CallAfter(FillRigidBodyGrid,True) def ThermDataSizer(RBObj): def OnThermval(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] try: val = float(Obj.GetValue()) RBObj['ThermalMotion'][1][item] = val except ValueError: pass Obj.SetValue('%8.4f'%(RBObj['ThermalMotion'][1][item])) G2plt.PlotStructure(G2frame,data) def OnTLSRef(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] RBObj['ThermalMotion'][2][item] = Obj.GetValue() thermSizer = wx.FlexGridSizer(1,9,5,5) model = RBObj['ThermalMotion'] if model[0] == 'Uiso': names = ['Uiso',] elif 'T' in model[0]: names = ['T11','T22','T33','T12','T13','T23'] if 'L' in model[0]: names += ['L11','L22','L33','L12','L13','L23'] if 'S' in model[0]: names += ['S12','S13','S21','S23','S31','S32','SAA','SBB'] for i,name in enumerate(names): thermSizer.Add(wx.StaticText(RigidBodies,-1,name+': '),0,wx.ALIGN_CENTER_VERTICAL) thermVal = wx.TextCtrl(RigidBodies,-1,value='%8.4f'%(model[1][i]), style=wx.TE_PROCESS_ENTER) thermVal.Bind(wx.EVT_TEXT_ENTER,OnThermval) thermVal.Bind(wx.EVT_KILL_FOCUS,OnThermval) Indx[thermVal.GetId()] = i thermSizer.Add(thermVal) Tcheck = wx.CheckBox(RigidBodies,-1,'Refine?') Tcheck.Bind(wx.EVT_CHECKBOX,OnTLSRef) Tcheck.SetValue(model[2][i]) Indx[Tcheck.GetId()] = i thermSizer.Add(Tcheck,0,wx.ALIGN_CENTER_VERTICAL) return thermSizer def LocationSizer(RBObj,rbType): def OnOrigRef(event): RBObj['Orig'][1] = Ocheck.GetValue() def OnOrienRef(event): RBObj['Orient'][1] = Qcheck.GetValue() def OnOrigX(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] try: val = float(Obj.GetValue()) RBObj['Orig'][0][item] = val Obj.SetValue('%8.5f'%(val)) newXYZ = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,rbType)[0] for i,id in enumerate(RBObj['Ids']): data['Atoms'][AtLookUp[id]][cx:cx+3] = newXYZ[i] data['Drawing']['Atoms'] = [] UpdateDrawAtoms(atomStyle) G2plt.PlotStructure(G2frame,data) except ValueError: pass def OnOrien(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] A,V = G2mth.Q2AVdeg(RBObj['Orient'][0]) V = np.inner(Bmat,V) try: val = float(Obj.GetValue()) if item: V[item-1] = val else: A = val Obj.SetValue('%8.5f'%(val)) V = np.inner(Amat,V) Q = G2mth.AVdeg2Q(A,V) if not any(Q): raise ValueError RBObj['Orient'][0] = Q newXYZ = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,rbType)[0] for i,id in enumerate(RBObj['Ids']): data['Atoms'][AtLookUp[id]][cx:cx+3] = newXYZ[i] data['Drawing']['Atoms'] = [] UpdateDrawAtoms(atomStyle) G2plt.PlotStructure(G2frame,data) except ValueError: pass topSizer = wx.FlexGridSizer(2,6,5,5) Orig = RBObj['Orig'][0] Orien,OrienV = G2mth.Q2AVdeg(RBObj['Orient'][0]) Orien = [Orien,] Orien.extend(OrienV/nl.norm(OrienV)) topSizer.Add(wx.StaticText(RigidBodies,-1,'Origin x,y,z:'),0,wx.ALIGN_CENTER_VERTICAL) for ix,x in enumerate(Orig): origX = wx.TextCtrl(RigidBodies,-1,value='%8.5f'%(x),style=wx.TE_PROCESS_ENTER) origX.Bind(wx.EVT_TEXT_ENTER,OnOrigX) origX.Bind(wx.EVT_KILL_FOCUS,OnOrigX) Indx[origX.GetId()] = ix topSizer.Add(origX,0,wx.ALIGN_CENTER_VERTICAL) topSizer.Add((5,0),) Ocheck = wx.CheckBox(RigidBodies,-1,'Refine?') Ocheck.Bind(wx.EVT_CHECKBOX,OnOrigRef) Ocheck.SetValue(RBObj['Orig'][1]) topSizer.Add(Ocheck,0,wx.ALIGN_CENTER_VERTICAL) topSizer.Add(wx.StaticText(RigidBodies,-1,'Rotation angle, vector:'),0,wx.ALIGN_CENTER_VERTICAL) for ix,x in enumerate(Orien): orien = wx.TextCtrl(RigidBodies,-1,value='%8.4f'%(x),style=wx.TE_PROCESS_ENTER) orien.Bind(wx.EVT_TEXT_ENTER,OnOrien) orien.Bind(wx.EVT_KILL_FOCUS,OnOrien) Indx[orien.GetId()] = ix topSizer.Add(orien,0,wx.ALIGN_CENTER_VERTICAL) Qcheck = wx.ComboBox(RigidBodies,-1,value='',choices=[' ','A','AV'], style=wx.CB_READONLY|wx.CB_DROPDOWN) Qcheck.Bind(wx.EVT_COMBOBOX,OnOrienRef) Qcheck.SetValue(RBObj['Orient'][1]) topSizer.Add(Qcheck) return topSizer def ResrbSizer(RBObj): G2frame.dataFrame.SetStatusText('NB: Rotation vector is in crystallographic space') def OnTorsionRef(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] RBObj['Torsions'][item][1] = Obj.GetValue() def OnTorsion(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] try: val = float(Obj.GetValue()) RBObj['Torsions'][item][0] = val newXYZ = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Residue')[0] for i,id in enumerate(RBObj['Ids']): data['Atoms'][AtLookUp[id]][cx:cx+3] = newXYZ[i] except ValueError: pass Obj.SetValue("%10.3f"%(RBObj['Torsions'][item][0])) data['Drawing']['Atoms'] = [] UpdateDrawAtoms(atomStyle) drawAtoms.ClearSelection() G2plt.PlotStructure(G2frame,data) def OnDelResRB(event): Obj = event.GetEventObject() RBId = Indx[Obj.GetId()] RBData['Residue'][RBId]['useCount'] -= 1 RBObjs = data['RBModels']['Residue'] for rbObj in RBObjs: if RBId == rbObj['RBId']: data['RBModels']['Residue'].remove(rbObj) G2plt.PlotStructure(G2frame,data) wx.CallAfter(FillRigidBodyGrid,True) resrbSizer = wx.BoxSizer(wx.VERTICAL) resrbSizer.Add(wx.StaticText(RigidBodies,-1,120*'-')) topLine = wx.BoxSizer(wx.HORIZONTAL) topLine.Add(wx.StaticText(RigidBodies,-1, 'Name: '+RBObj['RBname']+RBObj['numChain']+' '),0,wx.ALIGN_CENTER_VERTICAL) rbId = RBObj['RBId'] delRB = wx.CheckBox(RigidBodies,-1,'Delete?') delRB.Bind(wx.EVT_CHECKBOX,OnDelResRB) Indx[delRB.GetId()] = rbId topLine.Add(delRB,0,wx.ALIGN_CENTER_VERTICAL) resrbSizer.Add(topLine) resrbSizer.Add(LocationSizer(RBObj,'Residue')) resrbSizer.Add(wx.StaticText(RigidBodies,-1,'Torsions:'),0,wx.ALIGN_CENTER_VERTICAL) torSizer = wx.FlexGridSizer(1,6,5,5) for itors,tors in enumerate(RBObj['Torsions']): torSizer.Add(wx.StaticText(RigidBodies,-1,'Torsion '+'%d'%(itors)),0,wx.ALIGN_CENTER_VERTICAL) torsTxt = wx.TextCtrl(RigidBodies,-1,value='%.3f'%(tors[0]),style=wx.TE_PROCESS_ENTER) torsTxt.Bind(wx.EVT_TEXT_ENTER,OnTorsion) torsTxt.Bind(wx.EVT_KILL_FOCUS,OnTorsion) Indx[torsTxt.GetId()] = itors torSizer.Add(torsTxt) torCheck = wx.CheckBox(RigidBodies,-1,'Refine?') torCheck.Bind(wx.EVT_CHECKBOX,OnTorsionRef) torCheck.SetValue(tors[1]) Indx[torCheck.GetId()] = itors torSizer.Add(torCheck,0,wx.ALIGN_CENTER_VERTICAL) resrbSizer.Add(torSizer) tchoice = ['None','Uiso','T','TL','TLS'] thermSizer = wx.BoxSizer(wx.HORIZONTAL) thermSizer.Add(wx.StaticText(RigidBodies,-1,'Rigid body thermal motion model: '),0,wx.ALIGN_CENTER_VERTICAL) thermSel = wx.ComboBox(RigidBodies,-1,value=RBObj['ThermalMotion'][0],choices=tchoice, style=wx.CB_READONLY|wx.CB_DROPDOWN) Indx[thermSel.GetId()] = RBObj thermSel.Bind(wx.EVT_COMBOBOX,OnThermSel) thermSizer.Add(thermSel,0,wx.ALIGN_CENTER_VERTICAL) thermSizer.Add(wx.StaticText(RigidBodies,-1,' Units: T A^2, L deg^2, S deg-A'),0,wx.ALIGN_CENTER_VERTICAL) resrbSizer.Add(thermSizer) if RBObj['ThermalMotion'][0] != 'None': resrbSizer.Add(ThermDataSizer(RBObj)) return resrbSizer def VecrbSizer(RBObj): G2frame.dataFrame.SetStatusText('NB: Rotation vector is in crystallographic space') def OnDelVecRB(event): Obj = event.GetEventObject() RBId = Indx[Obj.GetId()] RBData['Vector'][RBId]['useCount'] -= 1 RBObjs = data['RBModels']['Vector'] for rbObj in RBObjs: if RBId == rbObj['RBId']: data['RBModels']['Vector'].remove(rbObj) G2plt.PlotStructure(G2frame,data) wx.CallAfter(FillRigidBodyGrid,True) vecrbSizer = wx.BoxSizer(wx.VERTICAL) vecrbSizer.Add(wx.StaticText(RigidBodies,-1,120*'-')) topLine = wx.BoxSizer(wx.HORIZONTAL) topLine.Add(wx.StaticText(RigidBodies,-1, 'Name: '+RBObj['RBname']+' '),0,wx.ALIGN_CENTER_VERTICAL) rbId = RBObj['RBId'] delRB = wx.CheckBox(RigidBodies,-1,'Delete?') delRB.Bind(wx.EVT_CHECKBOX,OnDelVecRB) Indx[delRB.GetId()] = rbId topLine.Add(delRB,0,wx.ALIGN_CENTER_VERTICAL) vecrbSizer.Add(topLine) vecrbSizer.Add(LocationSizer(RBObj,'Vector')) tchoice = ['None','Uiso','T','TL','TLS'] thermSizer = wx.BoxSizer(wx.HORIZONTAL) thermSizer.Add(wx.StaticText(RigidBodies,-1,'Rigid body thermal motion model: '),0,wx.ALIGN_CENTER_VERTICAL) thermSel = wx.ComboBox(RigidBodies,-1,value=RBObj['ThermalMotion'][0],choices=tchoice, style=wx.CB_READONLY|wx.CB_DROPDOWN) Indx[thermSel.GetId()] = RBObj thermSel.Bind(wx.EVT_COMBOBOX,OnThermSel) thermSizer.Add(thermSel,0,wx.ALIGN_CENTER_VERTICAL) thermSizer.Add(wx.StaticText(RigidBodies,-1,' Units: T A^2, L deg^2, S deg-A'),0,wx.ALIGN_CENTER_VERTICAL) vecrbSizer.Add(thermSizer) if RBObj['ThermalMotion'][0] != 'None': vecrbSizer.Add(ThermDataSizer(RBObj)) return vecrbSizer # FillRigidBodyGrid executable code starts here if refresh: RigidBodies.DestroyChildren() AtLookUp = G2mth.FillAtomLookUp(data['Atoms']) general = data['General'] cx = general['AtomPtrs'][0] Amat,Bmat = G2lat.cell2AB(general['Cell'][1:7]) RBData = G2frame.PatternTree.GetItemPyData( G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Rigid bodies')) Indx = {} atomStyle = 'balls & sticks' if 'macro' in general['Type']: atomStyle = 'sticks' G2frame.dataFrame.SetStatusText('') mainSizer = wx.BoxSizer(wx.VERTICAL) if not data['RBModels']: mainSizer.Add((5,5),0) mainSizer.Add(wx.StaticText(RigidBodies,-1,'No rigid body models:'),0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((5,5),0) if 'Residue' in data['RBModels']: mainSizer.Add((5,5),0) mainSizer.Add(wx.StaticText(RigidBodies,-1,'Residue rigid bodies:'),0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((5,5),0) for RBObj in data['RBModels']['Residue']: mainSizer.Add(ResrbSizer(RBObj)) if 'Vector' in data['RBModels']: mainSizer.Add((5,5),0) mainSizer.Add(wx.StaticText(RigidBodies,-1,'Vector rigid bodies:'),0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((5,5),0) for RBObj in data['RBModels']['Vector']: mainSizer.Add(VecrbSizer(RBObj)) RigidBodies.SetSizer(mainSizer) if G2frame.dataFrame.PhaseUserSize is None: mainSizer.FitInside(G2frame.dataFrame) Size = mainSizer.GetMinSize() Size[0] += 40 Size[1] = max(Size[1],290) + 35 RigidBodies.SetSize(Size) RigidBodies.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) Size[1] = min(Size[1],450) G2frame.dataFrame.setSizePosLeft(Size) else: Size = G2frame.dataFrame.PhaseUserSize RigidBodies.SetSize(Size) RigidBodies.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) G2frame.dataFrame.Update() def OnRBCopyParms(event): RBObjs = [] for rbType in ['Vector','Residue']: RBObjs += data['RBModels'].get(rbType,[]) if not len(RBObjs): print '**** ERROR - no rigid bodies defined ****' return if len(RBObjs) == 1: print '**** INFO - only one rigid body defined; nothing to copy to ****' return Source = [] sourceRB = {} for RBObj in RBObjs: Source.append(RBObj['RBname']) dlg = wx.SingleChoiceDialog(G2frame,'Select source','Copy rigid body parameters',Source) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelection() name = Source[sel] for item in ['Orig','Orient','ThermalMotion']: sourceRB.update({item:RBObjs[sel][item],}) dlg.Destroy() if not sourceRB: return dlg = wx.MultiChoiceDialog(G2frame,'Select targets','Copy rigid body parameters',Source) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelections() for x in sel: RBObjs[x].update(copy.copy(sourceRB)) G2plt.PlotStructure(G2frame,data) wx.CallAfter(FillRigidBodyGrid(True)) def OnRBAssign(event): G2frame.dataFrame.SetStatusText('') RBData = G2frame.PatternTree.GetItemPyData( G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Rigid bodies')) rbNames = {} for rbVec in RBData['Vector']: if rbVec != 'AtInfo': rbNames[RBData['Vector'][rbVec]['RBname']] =['Vector',rbVec] for rbRes in RBData['Residue']: if rbRes != 'AtInfo': rbNames[RBData['Residue'][rbRes]['RBname']] = ['Residue',rbRes] if not rbNames: print '**** ERROR - no rigid bodies defined ****' return general = data['General'] Amat,Bmat = G2lat.cell2AB(general['Cell'][1:7]) cx,ct = general['AtomPtrs'][:2] atomData = data['Atoms'] Indx = {} atInd = [-1,-1,-1] data['testRBObj'] = {} def Draw(): def OnOk(event): rbType = data['testRBObj']['rbType'] RBObjs = data['RBModels'].get(rbType,[]) rbObj = data['testRBObj']['rbObj'] rbId = rbObj['RBId'] newXYZ = G2mth.UpdateRBXYZ(Bmat,rbObj,RBData,rbType)[0] Ids = [] dmax = 0.0 oldXYZ = G2mth.getAtomXYZ(atomData,cx) for xyz in newXYZ: dist = G2mth.GetXYZDist(xyz,oldXYZ,Amat) dmax = max(dmax,np.min(dist)) id = np.argmin(dist) Ids.append(atomData[id][-1]) atomData[id][cx:cx+3] = xyz if dmax > 0.5: print '**** WARNING - some atoms not found or misidentified ****' print '**** check torsion angles & try again ****' OkBtn.SetLabel('Not Ready') OkBtn.Enable(False) return rbObj['Ids'] = Ids rbObj['ThermalMotion'] = ['None',[0. for i in range(21)],[False for i in range(21)]] #type,values,flags rbObj['RBname'] += ':'+str(RBData[rbType][rbId]['useCount']) RBObjs.append(rbObj) data['RBModels'][rbType] = RBObjs RBData[rbType][rbId]['useCount'] += 1 del data['testRBObj'] G2plt.PlotStructure(G2frame,data) FillRigidBodyGrid(True) def OnCancel(event): del data['testRBObj'] FillRigidBodyGrid(True) def OnRBSel(event): selection = rbSel.GetValue() rbType,rbId = rbNames[selection] data['testRBObj']['rbAtTypes'] = RBData[rbType][rbId]['rbTypes'] data['testRBObj']['AtInfo'] = RBData[rbType]['AtInfo'] data['testRBObj']['rbType'] = rbType data['testRBObj']['rbData'] = RBData data['testRBObj']['Sizers'] = {} rbRef = RBData[rbType][rbId]['rbRef'] data['testRBObj']['rbRef'] = rbRef refType = [] refName = [] for ref in rbRef[:3]: reftype = data['testRBObj']['rbAtTypes'][ref] refType.append(reftype) refName.append(reftype+' '+str(rbRef[0])) atNames,AtNames = fillAtNames(refType,atomData,ct) data['testRBObj']['atNames'] = atNames data['testRBObj']['AtNames'] = AtNames data['testRBObj']['rbObj'] = {'Orig':[[0,0,0],False], 'Orient':[[0.,0.,0.,1.],' '],'Ids':[],'RBId':rbId,'Torsions':[], 'numChain':'','RBname':RBData[rbType][rbId]['RBname']} data['testRBObj']['torAtms'] = [] for item in RBData[rbType][rbId].get('rbSeq',[]): data['testRBObj']['rbObj']['Torsions'].append([item[2],False]) data['testRBObj']['torAtms'].append([-1,-1,-1]) Draw() def fillAtNames(refType,atomData,ct): atNames = [{},{},{}] AtNames = {} for iatm,atom in enumerate(atomData): AtNames[atom[ct-1]] = iatm for i,reftype in enumerate(refType): if atom[ct] == reftype: atNames[i][atom[ct-1]] = iatm return atNames,AtNames def OnAtOrigPick(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] atName = Obj.GetValue() rbType = data['testRBObj']['rbType'] atInd[0] = atNames[item][atName] if 'Vector' in rbType: rbObj = data['testRBObj']['rbObj'] rbId = rbObj['RBId'] rbRef = data['testRBObj']['rbRef'] rbXYZ = -RBData[rbType][rbId]['rbXYZ'] nref = atNames[item][atName] Oxyz = np.inner(Bmat,np.array(rbXYZ[rbRef[0]])) Nxyz = np.array(atomData[nref][cx:cx+3]) Orig = Nxyz-Oxyz data['testRBObj']['rbObj']['Orig'][0] = Orig else: Orig = atomData[atNames[item][atName]][cx:cx+3] data['testRBObj']['rbObj']['Orig'][0] = Orig for x,item in zip(Orig,Xsizers): item.SetLabel('%10.5f'%(x)) G2plt.PlotStructure(G2frame,data) def OnAtQPick(event): Obj = event.GetEventObject() item = Indx[Obj.GetId()] atName = Obj.GetValue() atInd[item] = atNames[item][atName] if any([x<0 for x in atInd]): return OkBtn.SetLabel('OK') OkBtn.Enable(True) rbType = data['testRBObj']['rbType'] rbObj = data['testRBObj']['rbObj'] rbId = rbObj['RBId'] rbRef = data['testRBObj']['rbRef'] rbXYZ = RBData[rbType][rbId]['rbXYZ'] rbOrig = rbXYZ[rbRef[0]] VAR = rbXYZ[rbRef[1]]-rbOrig VBR = rbXYZ[rbRef[2]]-rbOrig if rbType == 'Vector': Orig = np.array(atomData[atInd[0]][cx:cx+3]) else: Orig = np.array(data['testRBObj']['rbObj']['Orig'][0]) VAC = np.inner(Amat,np.array(atomData[atInd[1]][cx:cx+3])-Orig) VBC = np.inner(Amat,np.array(atomData[atInd[2]][cx:cx+3])-Orig) VCC = np.cross(VAR,VAC) QuatA = G2mth.makeQuat(VAR,VAC,VCC)[0] VAR = G2mth.prodQVQ(QuatA,VAR) VBR = G2mth.prodQVQ(QuatA,VBR) QuatB = G2mth.makeQuat(VBR,VBC,VAR)[0] QuatC = G2mth.prodQQ(QuatB,QuatA) data['testRBObj']['rbObj']['Orient'] = [QuatC,' '] for x,item in zip(QuatC,Osizers): item.SetLabel('%10.4f'%(x)) if rbType == 'Vector': Oxyz = np.inner(Bmat,G2mth.prodQVQ(QuatC,rbOrig)) Nxyz = np.array(atomData[atInd[0]][cx:cx+3]) Orig = Nxyz-Oxyz data['testRBObj']['rbObj']['Orig'][0] = Orig for x,item in zip(Orig,Xsizers): item.SetLabel('%10.5f'%(x)) G2plt.PlotStructure(G2frame,data) def OnTorAngle(event): OkBtn.SetLabel('OK') OkBtn.Enable(True) Obj = event.GetEventObject() [tor,torSlide] = Indx[Obj.GetId()] Tors = data['testRBObj']['rbObj']['Torsions'][tor] try: value = float(Obj.GetValue()) except ValueError: value = Tors[0] Tors[0] = value Obj.SetValue('%8.3f'%(value)) torSlide.SetValue(int(value*10)) G2plt.PlotStructure(G2frame,data) def OnTorSlide(event): OkBtn.SetLabel('OK') OkBtn.Enable(True) Obj = event.GetEventObject() tor,ang = Indx[Obj.GetId()] Tors = data['testRBObj']['rbObj']['Torsions'][tor] val = float(Obj.GetValue())/10. Tors[0] = val ang.SetValue('%8.3f'%(val)) G2plt.PlotStructure(G2frame,data) if len(data['testRBObj']): G2plt.PlotStructure(G2frame,data) RigidBodies.DestroyChildren() mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add((5,5),0) if data['testRBObj']: Xsizers = [] Osizers = [] rbObj = data['testRBObj']['rbObj'] rbName = rbObj['RBname'] rbId = rbObj['RBId'] Orig = rbObj['Orig'][0] Orien = rbObj['Orient'][0] rbRef = data['testRBObj']['rbRef'] Torsions = rbObj['Torsions'] refName = [] for ref in rbRef: refName.append(data['testRBObj']['rbAtTypes'][ref]+str(ref)) atNames = data['testRBObj']['atNames'] mainSizer.Add(wx.StaticText(RigidBodies,-1,'Locate rigid body : '+rbName), 0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((5,5),0) OriSizer = wx.FlexGridSizer(1,5,5,5) OriSizer.Add(wx.StaticText(RigidBodies,-1,'Origin x,y,z: '),0,wx.ALIGN_CENTER_VERTICAL) for ix,x in enumerate(Orig): origX = wx.StaticText(RigidBodies,-1,'%10.5f'%(x)) OriSizer.Add(origX,0,wx.ALIGN_CENTER_VERTICAL) Xsizers.append(origX) OriSizer.Add((5,0),) if len(atomData): choice = atNames[0].keys() choice.sort() data['testRBObj']['Sizers']['Xsizers'] = Xsizers OriSizer.Add(wx.StaticText(RigidBodies,-1,'Orientation quaternion: '),0,wx.ALIGN_CENTER_VERTICAL) for ix,x in enumerate(Orien): orien = wx.StaticText(RigidBodies,-1,'%10.4f'%(x)) OriSizer.Add(orien,0,wx.ALIGN_CENTER_VERTICAL) Osizers.append(orien) data['testRBObj']['Sizers']['Osizers'] = Osizers mainSizer.Add(OriSizer) mainSizer.Add((5,5),0) RefSizer = wx.FlexGridSizer(1,7,5,5) if len(atomData): RefSizer.Add(wx.StaticText(RigidBodies,-1,'Location setting: Select match to'),0,wx.ALIGN_CENTER_VERTICAL) for i in [0,1,2]: choice = ['',]+atNames[i].keys() choice.sort() RefSizer.Add(wx.StaticText(RigidBodies,-1,' '+refName[i]+': '),0,wx.ALIGN_CENTER_VERTICAL) atPick = wx.ComboBox(RigidBodies,-1,value='', choices=choice[1:],style=wx.CB_READONLY|wx.CB_DROPDOWN) if i: atPick.Bind(wx.EVT_COMBOBOX, OnAtQPick) else: atPick.Bind(wx.EVT_COMBOBOX, OnAtOrigPick) Indx[atPick.GetId()] = i RefSizer.Add(atPick,0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add(RefSizer) mainSizer.Add((5,5),0) if Torsions: AtNames = data['testRBObj']['AtNames'] rbAtTypes = data['testRBObj']['rbAtTypes'] rbSeq = RBData['Residue'][rbId]['rbSeq'] TorSizer = wx.FlexGridSizer(1,4) TorSizer.AddGrowableCol(1,1) for t,[torsion,seq] in enumerate(zip(Torsions,rbSeq)): torName = '' for item in [seq[0],seq[1],seq[3][0]]: torName += data['testRBObj']['rbAtTypes'][item]+str(item)+' ' TorSizer.Add(wx.StaticText(RigidBodies,-1,'Side chain torsion for rb seq: '+torName),0,wx.ALIGN_CENTER_VERTICAL) torSlide = wx.Slider(RigidBodies,style=wx.SL_HORIZONTAL) torSlide.SetRange(0,3600) torSlide.SetValue(int(torsion[0]*10.)) torSlide.Bind(wx.EVT_SLIDER, OnTorSlide) TorSizer.Add(torSlide,1,wx.EXPAND|wx.RIGHT) TorSizer.Add(wx.StaticText(RigidBodies,-1,' Angle: '),0,wx.ALIGN_CENTER_VERTICAL) ang = wx.TextCtrl(RigidBodies,-1,value='%8.3f'%(torsion[0]),style=wx.TE_PROCESS_ENTER) ang.Bind(wx.EVT_TEXT_ENTER,OnTorAngle) ang.Bind(wx.EVT_KILL_FOCUS,OnTorAngle) Indx[torSlide.GetId()] = [t,ang] Indx[ang.GetId()] = [t,torSlide] TorSizer.Add(ang,0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add(TorSizer,1,wx.EXPAND|wx.RIGHT) else: mainSizer.Add(wx.StaticText(RigidBodies,-1,'No side chain torsions'),0,wx.ALIGN_CENTER_VERTICAL) else: mainSizer.Add(wx.StaticText(RigidBodies,-1,'Assign rigid body:'),0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add((5,5),0) topSizer = wx.BoxSizer(wx.HORIZONTAL) topSizer.Add(wx.StaticText(RigidBodies,-1,'Select rigid body model'),0,wx.ALIGN_CENTER_VERTICAL) rbSel = wx.ComboBox(RigidBodies,-1,value='',choices=rbNames.keys(), style=wx.CB_READONLY|wx.CB_DROPDOWN) rbSel.Bind(wx.EVT_COMBOBOX, OnRBSel) topSizer.Add((5,5),0) topSizer.Add(rbSel,0,wx.ALIGN_CENTER_VERTICAL) mainSizer.Add(topSizer) OkBtn = wx.Button(RigidBodies,-1,"Not ready") OkBtn.Bind(wx.EVT_BUTTON, OnOk) OkBtn.Enable(False) CancelBtn = wx.Button(RigidBodies,-1,'Cancel') CancelBtn.Bind(wx.EVT_BUTTON, OnCancel) btnSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer.Add((20,20),1) btnSizer.Add(OkBtn) btnSizer.Add(CancelBtn) btnSizer.Add((20,20),1) mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10) RigidBodies.SetSizer(mainSizer) Size = mainSizer.Fit(RigidBodies) Size[0] += 40 Size[1] = min(max(Size[1],290) + 35,560) RigidBodies.SetSize(Size) RigidBodies.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1) G2frame.dataFrame.setSizePosLeft(Size) Draw() def OnAutoFindResRB(event): RBData = G2frame.PatternTree.GetItemPyData( G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Rigid bodies')) rbKeys = RBData['Residue'].keys() rbKeys.remove('AtInfo') if not len(rbKeys): print '**** ERROR - no residue rigid bodies are defined ****' return RBNames = [RBData['Residue'][k]['RBname'] for k in rbKeys] RBIds = dict(zip(RBNames,rbKeys)) general = data['General'] Amat,Bmat = G2lat.cell2AB(general['Cell'][1:7]) Atoms = data['Atoms'] AtLookUp = G2mth.FillAtomLookUp(Atoms) if 'macro' not in general['Type']: print '**** ERROR - this phase is not a macromolecule ****' return if not len(Atoms): print '**** ERROR - this phase has no atoms ****' return RBObjs = [] cx,ct = general['AtomPtrs'][:2] iatm = 0 wx.BeginBusyCursor() try: while iatm < len(Atoms): atom = Atoms[iatm] res = atom[1].strip() numChain = ' %s %s'%(atom[0],atom[2]) if res not in RBIds or atom[ct-1] == 'OXT': iatm += 1 continue #skip for OXT, water molecules, etc. rbRes = RBData['Residue'][RBIds[res]] rbRef = rbRes['rbRef'] VAR = rbRes['rbXYZ'][rbRef[1]]-rbRes['rbXYZ'][rbRef[0]] VBR = rbRes['rbXYZ'][rbRef[2]]-rbRes['rbXYZ'][rbRef[0]] rbObj = {'RBname':rbRes['RBname']+':'+str(rbRes['useCount']),'numChain':numChain} rbAtoms = [] rbIds = [] for iratm in range(len(rbRes['atNames'])): rbAtoms.append(np.array(Atoms[iatm][cx:cx+3])) rbIds.append(Atoms[iatm][20]) iatm += 1 #puts this at beginning of next residue? Orig = rbAtoms[rbRef[0]] rbObj['RBId'] = RBIds[res] rbObj['Ids'] = rbIds rbObj['Orig'] = [Orig,False] # print ' residue '+rbRes['RBname']+str(atom[0]).strip()+ \ # ' origin at: ','%.5f %.5f %.5f'%(Orig[0],Orig[1],Orig[2]) VAC = np.inner(Amat,rbAtoms[rbRef[1]]-Orig) VBC = np.inner(Amat,rbAtoms[rbRef[2]]-Orig) VCC = np.cross(VAR,VAC) QuatA = G2mth.makeQuat(VAR,VAC,VCC)[0] VAR = G2mth.prodQVQ(QuatA,VAR) VBR = G2mth.prodQVQ(QuatA,VBR) QuatB = G2mth.makeQuat(VBR,VBC,VAR)[0] QuatC = G2mth.prodQQ(QuatB,QuatA) rbObj['Orient'] = [QuatC,' '] rbObj['ThermalMotion'] = ['None',[0. for i in range(21)],[False for i in range(21)]] #type,values,flags SXYZ = [] TXYZ = [] rbObj['Torsions'] = [] for i,xyz in enumerate(rbRes['rbXYZ']): SXYZ.append(G2mth.prodQVQ(QuatC,xyz)) TXYZ.append(np.inner(Amat,rbAtoms[i]-Orig)) for Oatm,Patm,x,Riders in rbRes['rbSeq']: VBR = SXYZ[Oatm]-SXYZ[Patm] VAR = SXYZ[Riders[0]]-SXYZ[Patm] VAC = TXYZ[Riders[0]]-TXYZ[Patm] QuatA,D = G2mth.makeQuat(VAR,VAC,VBR) ang = 180.*D/np.pi rbObj['Torsions'].append([ang,False]) for ride in Riders: SXYZ[ride] = G2mth.prodQVQ(QuatA,SXYZ[ride]-SXYZ[Patm])+SXYZ[Patm] rbRes['useCount'] += 1 RBObjs.append(rbObj) data['RBModels']['Residue'] = RBObjs for RBObj in RBObjs: newXYZ = G2mth.UpdateRBXYZ(Bmat,RBObj,RBData,'Residue')[0] for i,id in enumerate(RBObj['Ids']): data['Atoms'][AtLookUp[id]][cx:cx+3] = newXYZ[i] finally: wx.EndBusyCursor() wx.CallAfter(FillRigidBodyGrid,True) def OnRBRemoveAll(event): data['RBModels']['Residue'] = [] data['RBModels']['Vector'] = [] RBData = G2frame.PatternTree.GetItemPyData( G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Rigid bodies')) for RBType in ['Vector','Residue']: for rbId in RBData[RBType]: RBData[RBType][rbId]['useCount'] = 0 FillRigidBodyGrid(True) def OnGlobalResRBRef(event): RBObjs = data['RBModels']['Residue'] names = ['Origin','Orient. angle','Full Orient.'] nTor = 0 for rbObj in RBObjs: nTor = max(nTor,len(rbObj['Torsions'])) names += ['Torsion '+str(i) for i in range(nTor)] dlg = wx.MultiChoiceDialog(G2frame,'Select','Refinement controls',names) if dlg.ShowModal() == wx.ID_OK: sel = dlg.GetSelections() parms = [] for x in sel: parms.append(names[x]) wx.BeginBusyCursor() try: for rbObj in RBObjs: if 'Origin' in parms: rbObj['Orig'][1] = True else: rbObj['Orig'][1] = False if 'Full Orient.' in parms: rbObj['Orient'][1] = 'AV' elif 'Orient. angle' in parms: rbObj['Orient'][1] = 'A' else: rbObj['Orient'][1] = ' ' for i in range(len(rbObj['Torsions'])): if 'Torsion '+str(i) in parms: rbObj['Torsions'][i][1] = True else: rbObj['Torsions'][i][1] = False finally: wx.EndBusyCursor() FillRigidBodyGrid() ################################################################################ ##### Pawley routines ################################################################################ def FillPawleyReflectionsGrid(): def KeyEditPawleyGrid(event): colList = G2frame.PawleyRefl.GetSelectedCols() PawleyPeaks = data['Pawley ref'] if event.GetKeyCode() == wx.WXK_RETURN: event.Skip(True) elif event.GetKeyCode() == wx.WXK_CONTROL: event.Skip(True) elif event.GetKeyCode() == wx.WXK_SHIFT: event.Skip(True) elif colList: G2frame.PawleyRefl.ClearSelection() key = event.GetKeyCode() for col in colList: if PawleyTable.GetTypeName(0,col) == wg.GRID_VALUE_BOOL: if key == 89: #'Y' for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=True elif key == 78: #'N' for row in range(PawleyTable.GetNumberRows()): PawleyPeaks[row][col]=False FillPawleyReflectionsGrid() # FillPawleyReflectionsGrid executable starts here G2frame.dataFrame.SetStatusText('') if 'Pawley ref' in data: PawleyPeaks = data['Pawley ref'] rowLabels = [] for i in range(len(PawleyPeaks)): rowLabels.append(str(i)) colLabels = ['h','k','l','mul','d','refine','Fsq(hkl)','sig(Fsq)'] Types = 4*[wg.GRID_VALUE_LONG,]+[wg.GRID_VALUE_FLOAT+':10,4',wg.GRID_VALUE_BOOL,]+ \ 2*[wg.GRID_VALUE_FLOAT+':10,2',] PawleyTable = G2gd.Table(PawleyPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types) G2frame.PawleyRefl.SetTable(PawleyTable, True) G2frame.PawleyRefl.Bind(wx.EVT_KEY_DOWN, KeyEditPawleyGrid) for r in range(G2frame.PawleyRefl.GetNumberRows()): for c in range(G2frame.PawleyRefl.GetNumberCols()): if c in [5,6]: G2frame.PawleyRefl.SetReadOnly(r,c,isReadOnly=False) else: G2frame.PawleyRefl.SetCellStyle(r,c,VERY_LIGHT_GREY,True) G2frame.PawleyRefl.SetMargins(0,0) G2frame.PawleyRefl.AutoSizeColumns(False) if G2frame.dataFrame.PhaseUserSize is None: G2frame.dataFrame.setSizePosLeft([500,300]) else: G2frame.dataFrame.Update() def OnPawleyLoad(event): generalData = data['General'] dmin = generalData['Pawley dmin'] cell = generalData['Cell'][1:7] A = G2lat.cell2A(cell) SGData = generalData['SGData'] HKLd = np.array(G2lat.GenHLaue(dmin,SGData,A)) PawleyPeaks = [] wx.BeginBusyCursor() try: for h,k,l,d in HKLd: ext,mul = G2spc.GenHKLf([h,k,l],SGData)[:2] if not ext: mul *= 2 #for powder multiplicity PawleyPeaks.append([h,k,l,mul,d,False,100.0,1.0]) finally: wx.EndBusyCursor() data['Pawley ref'] = PawleyPeaks FillPawleyReflectionsGrid() def OnPawleyEstimate(event): try: Refs = data['Pawley ref'] Histograms = data['Histograms'] except KeyError: print '**** Error - no histograms defined for this phase ****' return HistoNames = Histograms.keys() PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,HistoNames[0]) xdata = G2frame.PatternTree.GetItemPyData(PatternId)[1] Inst = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Instrument Parameters'))[0] Sample = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Sample Parameters')) wave = G2mth.getWave(Inst) posCorr = Inst['Zero'][1] const = 9.e-2/(np.pi*Sample['Gonio. radius']) #shifts in microns wx.BeginBusyCursor() try: for ref in Refs: pos = 2.0*asind(wave/(2.0*ref[4])) if 'Bragg' in Sample['Type']: pos -= const*(4.*Sample['Shift'][0]*cosd(pos/2.0)+ \ Sample['Transparency'][0]*sind(pos)*100.0) #trans(=1/mueff) in cm else: #Debye-Scherrer - simple but maybe not right pos -= const*(Sample['DisplaceX'][0]*cosd(pos)+Sample['DisplaceY'][0]*sind(pos)) indx = np.searchsorted(xdata[0],pos) try: FWHM = max(0.001,G2pwd.getFWHM(pos,Inst))/2. dx = xdata[0][indx+1]-xdata[0][indx] ref[6] = FWHM*(xdata[1][indx]-xdata[4][indx])*cosd(pos/2.)**3/dx Lorenz = 1./(2.*sind(xdata[0][indx]/2.)**2*cosd(xdata[0][indx]/2.)) #Lorentz correction pola,dIdPola = G2pwd.Polarization(Inst['Polariz.'][1],xdata[0][indx],Inst['Azimuth'][1]) ref[6] /= (Lorenz*pola*ref[3]) except IndexError: pass finally: wx.EndBusyCursor() FillPawleyReflectionsGrid() def OnPawleyUpdate(event): try: Refs = data['Pawley ref'] Histograms = data['Histograms'] except KeyError: print '**** Error - no histograms defined for this phase ****' return HistoNames = Histograms.keys() PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root,HistoNames[0]) refData = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists'))[PhaseName] wx.BeginBusyCursor() try: for iref,ref in enumerate(Refs): try: if refData[iref][9] < 0.: ref[6] = abs(refData[iref][9]) ref[7] = 1.0 except IndexError: pass finally: wx.EndBusyCursor() FillPawleyReflectionsGrid() def OnPawleyDelete(event): #doesn't work dlg = wx.MessageDialog(G2frame,'Do you really want to delete selected Pawley reflections?','Delete', wx.YES_NO | wx.ICON_QUESTION) try: result = dlg.ShowModal() if result == wx.ID_YES: Refs = data['Pawley ref'] Ind = G2frame.PawleyRefl.GetSelectedRows() Ind.sort() Ind.reverse() for ind in Ind: Refs = np.delete(Refs,ind,0) data['Pawley ref'] = Refs FillPawleyReflectionsGrid() finally: dlg.Destroy() ################################################################################ ##### Fourier routines ################################################################################ def FillMapPeaksGrid(): def RowSelect(event): r,c = event.GetRow(),event.GetCol() if r < 0 and c < 0: if MapPeaks.IsSelection(): MapPeaks.ClearSelection() else: for row in range(MapPeaks.GetNumberRows()): MapPeaks.SelectRow(row,True) elif c < 0: #only row clicks if event.ControlDown(): if r in MapPeaks.GetSelectedRows(): MapPeaks.DeselectRow(r) else: MapPeaks.SelectRow(r,True) elif event.ShiftDown(): indxs = MapPeaks.GetSelectedRows() MapPeaks.ClearSelection() ibeg = 0 if indxs: ibeg = indxs[-1] for row in range(ibeg,r+1): MapPeaks.SelectRow(row,True) else: MapPeaks.ClearSelection() MapPeaks.SelectRow(r,True) elif r < 0: #a column pick mapPeaks = data['Map Peaks'] c = event.GetCol() if colLabels[c] == 'mag': mapPeaks = G2mth.sortArray(mapPeaks,c,reverse=True) elif colLabels[c] in ['x','y','z','dzero']: mapPeaks = G2mth.sortArray(mapPeaks,c) else: return data['Map Peaks'] = mapPeaks wx.CallAfter(FillMapPeaksGrid) G2plt.PlotStructure(G2frame,data) if G2frame.dataFrame.PhaseUserSize is None: G2frame.dataFrame.setSizePosLeft([450,300]) else: G2frame.dataFrame.Update() G2frame.dataFrame.SetStatusText('') if 'Map Peaks' in data: G2frame.dataFrame.SetStatusText('Select mag or dzero columns to sort') mapPeaks = data['Map Peaks'] rowLabels = [] for i in range(len(mapPeaks)): rowLabels.append(str(i)) colLabels = ['mag','x','y','z','dzero'] Types = 5*[wg.GRID_VALUE_FLOAT+':10,4',] G2frame.MapPeaksTable = G2gd.Table(mapPeaks,rowLabels=rowLabels,colLabels=colLabels,types=Types) MapPeaks.SetTable(G2frame.MapPeaksTable, True) MapPeaks.Bind(wg.EVT_GRID_LABEL_LEFT_CLICK, RowSelect) for r in range(MapPeaks.GetNumberRows()): for c in range(MapPeaks.GetNumberCols()): MapPeaks.SetCellStyle(r,c,VERY_LIGHT_GREY,True) MapPeaks.SetMargins(0,0) MapPeaks.AutoSizeColumns(False) def OnPeaksMove(event): if 'Map Peaks' in data: mapPeaks = np.array(data['Map Peaks']) peakMax = np.max(mapPeaks.T[0]) Ind = MapPeaks.GetSelectedRows() for ind in Ind: mag,x,y,z,d = mapPeaks[ind] AtomAdd(x,y,z,'H',Name='M '+'%d'%(int(100*mag/peakMax))) def OnPeaksClear(event): data['Map Peaks'] = [] FillMapPeaksGrid() G2plt.PlotStructure(G2frame,data) def OnPeaksDelete(event): if 'Map Peaks' in data: mapPeaks = data['Map Peaks'] Ind = MapPeaks.GetSelectedRows() Ind.sort() Ind.reverse() for ind in Ind: mapPeaks = np.delete(mapPeaks,ind,0) data['Map Peaks'] = mapPeaks FillMapPeaksGrid() G2plt.PlotStructure(G2frame,data) def OnPeaksEquiv(event): if 'Map Peaks' in data: mapPeaks = data['Map Peaks'] Ind = MapPeaks.GetSelectedRows() if Ind: wx.BeginBusyCursor() try: Ind = G2mth.PeaksEquiv(data,Ind) for r in range(MapPeaks.GetNumberRows()): if r in Ind: MapPeaks.SelectRow(r,addToSelected=True) else: MapPeaks.DeselectRow(r) finally: wx.EndBusyCursor() G2plt.PlotStructure(G2frame,data) def OnShowBonds(event): generalData = data['General'] if generalData['Map'].get('Show bonds',False): generalData['Map']['Show bonds'] = False G2frame.dataFrame.MapPeaksEdit.SetLabel(G2gd.wxID_SHOWBONDS,'Show bonds') else: generalData['Map']['Show bonds'] = True G2frame.dataFrame.MapPeaksEdit.SetLabel(G2gd.wxID_SHOWBONDS,'Hide bonds') FillMapPeaksGrid() G2plt.PlotStructure(G2frame,data) def OnPeaksUnique(event): if 'Map Peaks' in data: mapPeaks = data['Map Peaks'] Ind = MapPeaks.GetSelectedRows() if Ind: wx.BeginBusyCursor() try: Ind = G2mth.PeaksUnique(data,Ind) for r in range(MapPeaks.GetNumberRows()): if r in Ind: MapPeaks.SelectRow(r,addToSelected=True) else: MapPeaks.DeselectRow(r) finally: wx.EndBusyCursor() G2plt.PlotStructure(G2frame,data) def OnPeaksViewPoint(event): # set view point indx = MapPeaks.GetSelectedRows() if not indx: print '***** ERROR - no peaks selected' return mapPeaks = data['Map Peaks'] drawingData = data['Drawing'] drawingData['viewPoint'][0] = mapPeaks[indx[0]][1:4] G2plt.PlotStructure(G2frame,data) def OnPeaksDistVP(event): # distance to view point indx = MapPeaks.GetSelectedRows() if not indx: print '***** ERROR - no peaks selected' return generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) mapPeaks = data['Map Peaks'] drawingData = data['Drawing'] viewPt = np.array(drawingData['viewPoint'][0]) print ' Distance from view point at %.3f %.3f %.3f to:'%(viewPt[0],viewPt[1],viewPt[2]) colLabels = [MapPeaks.GetColLabelValue(c) for c in range(MapPeaks.GetNumberCols())] cx = colLabels.index('x') cm = colLabels.index('mag') for i in indx: peak = mapPeaks[i] Dx = np.array(peak[cx:cx+3])-viewPt dist = np.sqrt(np.sum(np.inner(Amat,Dx)**2,axis=0)) print 'Peak: %5d mag= %8.2f distance = %.3f'%(i,peak[cm],dist) def OnPeaksDA(event): #distance, angle indx = MapPeaks.GetSelectedRows() if len(indx) not in [2,3]: print '**** ERROR - wrong number of atoms for distance or angle calculation' return generalData = data['General'] Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7]) mapPeaks = data['Map Peaks'] xyz = [] for i in indx: xyz.append(mapPeaks[i][1:4]) if len(indx) == 2: print ' distance for atoms %s = %.3f'%(str(indx),G2mth.getRestDist(xyz,Amat)) else: print ' angle for atoms %s = %.2f'%(str(indx),G2mth.getRestAngle(xyz,Amat)) def OnFourierMaps(event): generalData = data['General'] mapData = generalData['Map'] reflName = mapData['RefList'] phaseName = generalData['Name'] if 'PWDR' in reflName: PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName) reflSets = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists')) reflData = reflSets[phaseName] elif 'HKLF' in reflName: PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName) reflData = G2frame.PatternTree.GetItemPyData(PatternId)[1] if mapData['MapType'] == 'Omit': mapData.update(G2mth.OmitMap(data,reflData)) else: mapData.update(G2mth.FourierMap(data,reflData)) mapData['Flip'] = False mapSig = np.std(mapData['rho']) if not data['Drawing']: #if new drawing - no drawing data! SetupDrawingData() data['Drawing']['contourLevel'] = 1. data['Drawing']['mapSize'] = 10. print mapData['MapType']+' computed: rhomax = %.3f rhomin = %.3f sigma = %.3f'%(np.max(mapData['rho']),np.min(mapData['rho']),mapSig) UpdateDrawAtoms() G2plt.PlotStructure(G2frame,data) def OnFourClear(event): generalData = data['General'] generalData['Map'] = mapDefault G2plt.PlotStructure(G2frame,data) def printRho(SGLaue,rho,rhoMax): # map printing for testing purposes dim = len(rho.shape) if dim == 2: ix,jy = rho.shape for j in range(jy): line = '' if SGLaue in ['3','3m1','31m','6/m','6/mmm']: line += (jy-j)*' ' for i in range(ix): r = int(100*rho[i,j]/rhoMax) line += '%4d'%(r) print line+'\n' else: ix,jy,kz = rho.shape for k in range(kz): print 'k = ',k for j in range(jy): line = '' if SGLaue in ['3','3m1','31m','6/m','6/mmm']: line += (jy-j)*' ' for i in range(ix): r = int(100*rho[i,j,k]/rhoMax) line += '%4d'%(r) print line+'\n' ## keep this def OnSearchMaps(event): peaks = [] mags = [] print ' Begin fourier map search - can take some time' time0 = time.time() generalData = data['General'] mapData = generalData['Map'] if len(mapData['rho']): wx.BeginBusyCursor() try: peaks,mags,dzeros = G2mth.SearchMap(data) finally: wx.EndBusyCursor() if len(peaks): mapPeaks = np.concatenate((mags,peaks,dzeros),axis=1) data['Map Peaks'] = G2mth.sortArray(mapPeaks,0,reverse=True) print ' Map search finished, time = %.2fs'%(time.time()-time0) print ' No.peaks found:',len(peaks) Page = G2frame.dataDisplay.FindPage('Map peaks') G2frame.dataDisplay.ChangeSelection(Page) G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.MapPeaksMenu) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksMove, id=G2gd.wxID_PEAKSMOVE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDA, id=G2gd.wxID_PEAKSDA) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksUnique, id=G2gd.wxID_PEAKSUNIQUE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDelete, id=G2gd.wxID_PEAKSDELETE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksClear, id=G2gd.wxID_PEAKSCLEAR) UpdateDrawAtoms() FillMapPeaksGrid() else: print 'No map available' def OnChargeFlip(event): generalData = data['General'] mapData = generalData['Map'] flipData = generalData['Flip'] reflName = flipData['RefList'] phaseName = generalData['Name'] if 'PWDR' in reflName: PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName) reflSets = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,PatternId,'Reflection Lists')) reflData = reflSets[phaseName] elif 'HKLF' in reflName: PatternId = G2gd.GetPatternTreeItemId(G2frame,G2frame.root, reflName) reflData = G2frame.PatternTree.GetItemPyData(PatternId)[1] else: print '**** ERROR - No data defined for charge flipping' return pgbar = wx.ProgressDialog('Charge flipping','Residual Rcf =',101.0, style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT) screenSize = wx.ClientDisplayRect() Size = pgbar.GetSize() Size = (int(Size[0]*1.2),Size[1]) # increase size a bit along x pgbar.SetPosition(wx.Point(screenSize[2]-Size[0]-305,screenSize[1]+5)) pgbar.SetSize(Size) try: mapData.update(G2mth.ChargeFlip(data,reflData,pgbar)) finally: pgbar.Destroy() mapData['Flip'] = True mapSig = np.std(mapData['rho']) if not data['Drawing']: #if new drawing - no drawing data! SetupDrawingData() data['Drawing']['contourLevel'] = 1. data['Drawing']['mapSize'] = 10. print ' Charge flip map computed: rhomax = %.3f rhomin = %.3f sigma = %.3f'%(np.max(mapData['rho']),np.min(mapData['rho']),mapSig) if mapData['Rcf'] < 99.: OnSearchMaps(event) #does a plot structure at end else: print 'Bad charge flip map - no peak search done' def OnTextureRefine(event): print 'refine texture?' event.Skip() def OnTextureClear(event): print 'clear texture?' event.Skip() def OnDataResize(event): 'Called when the data item window is resized by the user.' G2frame.dataFrame.PhaseUserSize = G2frame.dataFrame.GetSize() event.Skip() def OnPageChanged(event): '''This is called every time that a Notebook tab button is pressed on a Phase data item window ''' wx.Frame.Unbind(G2frame.dataFrame,wx.EVT_SIZE) # ignore size events during this routine page = event.GetSelection() text = G2frame.dataDisplay.GetPageText(page) if text == 'Atoms': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.AtomsMenu) G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomAdd, id=G2gd.wxID_ATOMSEDITADD) G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomViewAdd, id=G2gd.wxID_ATOMSVIEWADD) G2frame.dataFrame.Bind(wx.EVT_MENU, OnRBAppend, id=G2gd.wxID_RBAPPEND) G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomInsert, id=G2gd.wxID_ATOMSEDITINSERT) G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomViewInsert, id=G2gd.wxID_ATOMVIEWINSERT) G2frame.dataFrame.Bind(wx.EVT_MENU, OnAtomMove, id=G2gd.wxID_ATOMMOVE) G2frame.dataFrame.Bind(wx.EVT_MENU, AtomDelete, id=G2gd.wxID_ATOMSEDITDELETE) G2frame.dataFrame.Bind(wx.EVT_MENU, AtomRefine, id=G2gd.wxID_ATOMSREFINE) G2frame.dataFrame.Bind(wx.EVT_MENU, AtomModify, id=G2gd.wxID_ATOMSMODIFY) G2frame.dataFrame.Bind(wx.EVT_MENU, AtomTransform, id=G2gd.wxID_ATOMSTRANSFORM) G2frame.dataFrame.Bind(wx.EVT_MENU, OnReloadDrawAtoms, id=G2gd.wxID_RELOADDRAWATOMS) G2frame.dataFrame.Bind(wx.EVT_MENU, OnDistAngle, id=G2gd.wxID_ATOMSDISAGL) for id in G2frame.dataFrame.ReImportMenuId: #loop over submenu items G2frame.dataFrame.Bind(wx.EVT_MENU, OnReImport, id=id) FillAtomsGrid(Atoms) elif text == 'General': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.DataGeneral) G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourierMaps, id=G2gd.wxID_FOURCALC) G2frame.dataFrame.Bind(wx.EVT_MENU, OnSearchMaps, id=G2gd.wxID_FOURSEARCH) G2frame.dataFrame.Bind(wx.EVT_MENU, OnChargeFlip, id=G2gd.wxID_CHARGEFLIP) G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourClear, id=G2gd.wxID_FOURCLEAR) UpdateGeneral() elif text == 'Data': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.DataMenu) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2gd.wxID_PWDRADD) G2frame.dataFrame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2gd.wxID_HKLFADD) G2frame.dataFrame.Bind(wx.EVT_MENU, OnDataDelete, id=G2gd.wxID_DATADELETE) G2ddG.UpdateDData(G2frame,DData,data) G2plt.PlotSizeStrainPO(G2frame,data,Start=True) elif text == 'Draw Options': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.DataDrawOptions) UpdateDrawOptions() #G2plt.PlotStructure(G2frame,data) wx.CallAfter(G2plt.PlotStructure,G2frame,data) elif text == 'Draw Atoms': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.DrawAtomsMenu) G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomStyle, id=G2gd.wxID_DRAWATOMSTYLE) G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomLabel, id=G2gd.wxID_DRAWATOMLABEL) G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomColor, id=G2gd.wxID_DRAWATOMCOLOR) G2frame.dataFrame.Bind(wx.EVT_MENU, ResetAtomColors, id=G2gd.wxID_DRAWATOMRESETCOLOR) G2frame.dataFrame.Bind(wx.EVT_MENU, SetViewPoint, id=G2gd.wxID_DRAWVIEWPOINT) G2frame.dataFrame.Bind(wx.EVT_MENU, AddSymEquiv, id=G2gd.wxID_DRAWADDEQUIV) G2frame.dataFrame.Bind(wx.EVT_MENU, TransformSymEquiv, id=G2gd.wxID_DRAWTRANSFORM) G2frame.dataFrame.Bind(wx.EVT_MENU, FillCoordSphere, id=G2gd.wxID_DRAWFILLCOORD) G2frame.dataFrame.Bind(wx.EVT_MENU, FillUnitCell, id=G2gd.wxID_DRAWFILLCELL) G2frame.dataFrame.Bind(wx.EVT_MENU, DrawAtomsDelete, id=G2gd.wxID_DRAWDELETE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawDistVP, id=G2gd.wxID_DRAWDISTVP) G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawDAT, id=G2gd.wxID_DRAWDISAGLTOR) G2frame.dataFrame.Bind(wx.EVT_MENU, OnDrawPlane, id=G2gd.wxID_DRAWPLANE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRBOND) G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRANGLE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRPLANE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRCHIRAL) G2frame.dataFrame.Bind(wx.EVT_MENU, OnDefineRB, id=G2gd.wxID_DRAWDEFINERB) UpdateDrawAtoms() G2plt.PlotStructure(G2frame,data) elif text == 'RB Models': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RigidBodiesMenu) G2frame.dataFrame.Bind(wx.EVT_MENU, OnAutoFindResRB, id=G2gd.wxID_AUTOFINDRESRB) G2frame.dataFrame.Bind(wx.EVT_MENU, OnRBAssign, id=G2gd.wxID_ASSIGNATMS2RB) G2frame.dataFrame.Bind(wx.EVT_MENU, OnRBCopyParms, id=G2gd.wxID_COPYRBPARMS) G2frame.dataFrame.Bind(wx.EVT_MENU, OnGlobalResRBRef, id=G2gd.wxID_GLOBALRESREFINE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnRBRemoveAll, id=G2gd.wxID_RBREMOVEALL) FillRigidBodyGrid() elif text == 'Pawley reflections': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.PawleyMenu) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyLoad, id=G2gd.wxID_PAWLEYLOAD) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyEstimate, id=G2gd.wxID_PAWLEYESTIMATE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyUpdate, id=G2gd.wxID_PAWLEYUPDATE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPawleyDelete, id=G2gd.wxID_PAWLEYDELETE) FillPawleyReflectionsGrid() elif text == 'Map peaks': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.MapPeaksMenu) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksMove, id=G2gd.wxID_PEAKSMOVE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksViewPoint, id=G2gd.wxID_PEAKSVIEWPT) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDistVP, id=G2gd.wxID_PEAKSDISTVP) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDA, id=G2gd.wxID_PEAKSDA) G2frame.dataFrame.Bind(wx.EVT_MENU, OnShowBonds, id=G2gd.wxID_SHOWBONDS) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksEquiv, id=G2gd.wxID_FINDEQVPEAKS) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksUnique, id=G2gd.wxID_PEAKSUNIQUE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksDelete, id=G2gd.wxID_PEAKSDELETE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnPeaksClear, id=G2gd.wxID_PEAKSCLEAR) FillMapPeaksGrid() #G2plt.PlotStructure(G2frame,data) wx.CallAfter(G2plt.PlotStructure,G2frame,data) elif text == 'Texture': G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.TextureMenu) G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureRefine, id=G2gd.wxID_REFINETEXTURE) G2frame.dataFrame.Bind(wx.EVT_MENU, OnTextureClear, id=G2gd.wxID_CLEARTEXTURE) UpdateTexture() G2plt.PlotTexture(G2frame,data,Start=True) else: G2gd.SetDataMenuBar(G2frame) wx.Frame.Bind(G2frame.dataFrame,wx.EVT_SIZE,OnDataResize) # capture user resize events again event.Skip() wx.Frame.Unbind(G2frame.dataFrame,wx.EVT_SIZE) # ignore size events during this routine General = wx.ScrolledWindow(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(General,'General') DData = wx.ScrolledWindow(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(DData,'Data') Atoms = G2gd.GSGrid(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(Atoms,'Atoms') drawOptions = wx.ScrolledWindow(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(drawOptions,'Draw Options') drawAtoms = G2gd.GSGrid(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(drawAtoms,'Draw Atoms') RigidBodies = wx.ScrolledWindow(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(RigidBodies,'RB Models') MapPeaks = G2gd.GSGrid(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(MapPeaks,'Map peaks') Texture = wx.ScrolledWindow(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(Texture,'Texture') G2frame.PawleyRefl = G2gd.GSGrid(G2frame.dataDisplay) G2frame.dataDisplay.AddPage(G2frame.PawleyRefl,'Pawley reflections') G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourierMaps, id=G2gd.wxID_FOURCALC) G2frame.dataFrame.Bind(wx.EVT_MENU, OnSearchMaps, id=G2gd.wxID_FOURSEARCH) G2frame.dataFrame.Bind(wx.EVT_MENU, OnChargeFlip, id=G2gd.wxID_CHARGEFLIP) G2frame.dataFrame.Bind(wx.EVT_MENU, OnFourClear, id=G2gd.wxID_FOURCLEAR) G2frame.dataDisplay.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, OnPageChanged) G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.DataGeneral) SetupGeneral() # this is done all over the place (including in # UpdateGeneral). Why here too? GeneralData = data['General'] if oldPage is None: # when entering a Phase data item from any other item, # reset a saved size, if any. G2frame.dataFrame.PhaseUserSize = None UpdateGeneral() elif oldPage: G2frame.dataDisplay.SetSelection(oldPage) else: UpdateGeneral() wx.Frame.Bind(G2frame.dataFrame,wx.EVT_SIZE,OnDataResize) # capture user resizing