Skip to content

Commit 9141ebe

Browse files
committed
new utility for HKLF data - sort HKL -puts all collected equivalent reflections together into new HKLF entry
1 parent 1c22809 commit 9141ebe

1 file changed

Lines changed: 233 additions & 1 deletion

File tree

GSASII/GSASIIdataGUI.py

Lines changed: 233 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,145 @@ def OnCancel(self,event):
255255
if parent is not None: parent.Raise()
256256
self.EndModal(wx.ID_CANCEL)
257257

258+
class HKLSortDialog(wx.Dialog):
259+
''' HKL transformation & sort dialog - no merge
260+
261+
:param wx.Frame parent: reference to parent frame (or None)
262+
:param data: HKLF data
263+
264+
'''
265+
266+
def __init__(self,parent,data):
267+
wx.Dialog.__init__(self,parent,wx.ID_ANY,'Setup HKLF sort',
268+
pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
269+
self.panel = wx.Panel(self) #just a dummy - gets destroyed in Draw!
270+
self.data = data
271+
self.Super = data[1]['Super']
272+
if self.Super:
273+
self.Trans = np.eye(4)
274+
else:
275+
self.Trans = np.eye(3)
276+
self.Type = data[0]['Type']
277+
self.Cent = 'noncentrosymmetric'
278+
self.Laue = '1'
279+
self.Class = 'triclinic'
280+
self.Common = 'abc'
281+
self.Draw()
282+
283+
def Draw(self):
284+
285+
def OnCent(event):
286+
Obj = event.GetEventObject()
287+
self.Cent = Obj.GetValue()
288+
self.Laue = ''
289+
wx.CallAfter(self.Draw)
290+
291+
def OnLaue(event):
292+
Obj = event.GetEventObject()
293+
self.Laue = Obj.GetValue()
294+
wx.CallAfter(self.Draw)
295+
296+
def OnClass(event):
297+
Obj = event.GetEventObject()
298+
self.Class = Obj.GetValue()
299+
self.Laue = ''
300+
wx.CallAfter(self.Draw)
301+
302+
def OnCommon(event):
303+
Obj = event.GetEventObject()
304+
self.Common = Obj.GetValue()
305+
self.Trans = commonTrans[self.Common]
306+
wx.CallAfter(self.Draw)
307+
308+
def OnSmart(event):
309+
self.Smart = not self.Smart
310+
311+
self.panel.Destroy()
312+
self.panel = wx.Panel(self)
313+
mainSizer = wx.BoxSizer(wx.VERTICAL)
314+
MatSizer = wx.BoxSizer(wx.HORIZONTAL)
315+
transSizer = wx.BoxSizer(wx.VERTICAL)
316+
transSizer.Add(wx.StaticText(self.panel,label=" HKL Transformation matrix: M*H = H'"))
317+
if self.Super:
318+
Trmat = wx.FlexGridSizer(4,4,0,0)
319+
else:
320+
commonSizer = wx.BoxSizer(wx.HORIZONTAL)
321+
commonSizer.Add(wx.StaticText(self.panel,label=' Common transformations: '),0,WACV)
322+
common = wx.ComboBox(self.panel,value=self.Common,choices=commonNames[:-2], #not the last two!
323+
style=wx.CB_READONLY|wx.CB_DROPDOWN)
324+
common.Bind(wx.EVT_COMBOBOX,OnCommon)
325+
commonSizer.Add(common,0,WACV)
326+
transSizer.Add(commonSizer)
327+
Trmat = wx.FlexGridSizer(3,3,0,0)
328+
for iy,line in enumerate(self.Trans):
329+
for ix,val in enumerate(line):
330+
item = G2G.ValidatedTxtCtrl(self.panel,self.Trans[iy],ix,nDig=(10,3),size=(65,25))
331+
Trmat.Add(item)
332+
transSizer.Add(Trmat)
333+
MatSizer.Add((10,0),0)
334+
MatSizer.Add(transSizer)
335+
mainSizer.Add(MatSizer)
336+
laueClass = ['triclinic','monoclinic','orthorhombic','trigonal(H)','trigonal(R)','tetragonal','hexagonal','cubic']
337+
centroLaue = {'triclinic':['-1',],'monoclinic':['2/m','1 1 2/m','2/m 1 1',],
338+
'orthorhombic':['m m m',],'trigonal(H)':['-3','-3 m 1','-3 1 m',],'trigonal(R)':['-3','-3 m'],\
339+
'tetragonal':['4/m','4/m m m',],'hexagonal':['6/m','6/m m m',],'cubic':['m 3','m 3 m']}
340+
noncentroLaue = {'triclinic':['1',],'monoclinic':['2','2 1 1','1 1 2','m','m 1 1','1 1 m',],
341+
'orthorhombic':['2 2 2','m m 2','m 2 m','2 m m',],
342+
'trigonal(H)':['3','3 1 2','3 2 1','3 m 1','3 1 m',],'trigonal(R)':['3','3 m'],
343+
'tetragonal':['4','-4','4 2 2','4 m m','-4 2 m','-4 m 2',], \
344+
'hexagonal':['6','-6','6 2 2','6 m m','-6 m 2','-6 2 m',],'cubic':['2 3','4 3 2','-4 3 m']}
345+
centChoice = ['noncentrosymmetric','centrosymmetric']
346+
mainSizer.Add(wx.StaticText(self.panel,label=' Select Laue class for new lattice:'),0)
347+
Class = wx.ComboBox(self.panel,value=self.Class,choices=laueClass,
348+
style=wx.CB_READONLY|wx.CB_DROPDOWN)
349+
Class.Bind(wx.EVT_COMBOBOX,OnClass)
350+
mainSizer.Add(Class,0)
351+
mainSizer.Add(wx.StaticText(self.panel,label=' Target Laue symmetry:'),0)
352+
Cent = wx.ComboBox(self.panel,value=self.Cent,choices=centChoice,
353+
style=wx.CB_READONLY|wx.CB_DROPDOWN)
354+
Cent.Bind(wx.EVT_COMBOBOX,OnCent)
355+
sortSizer = wx.BoxSizer(wx.HORIZONTAL)
356+
sortSizer.Add(Cent,0,WACV)
357+
sortSizer.Add((10,0),0)
358+
Choice = centroLaue[self.Class]
359+
if 'non' in self.Cent:
360+
Choice = noncentroLaue[self.Class]
361+
Laue = wx.ComboBox(self.panel,value=self.Laue,choices=Choice,
362+
style=wx.CB_READONLY|wx.CB_DROPDOWN)
363+
Laue.Bind(wx.EVT_COMBOBOX,OnLaue)
364+
sortSizer.Add(Laue,0,WACV)
365+
mainSizer.Add(sortSizer)
366+
367+
OkBtn = wx.Button(self.panel,-1,"Ok")
368+
OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
369+
cancelBtn = wx.Button(self.panel,-1,"Cancel")
370+
cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
371+
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
372+
btnSizer.Add((20,20),1)
373+
if self.Laue:
374+
btnSizer.Add(OkBtn)
375+
btnSizer.Add((20,20),1)
376+
btnSizer.Add(cancelBtn)
377+
btnSizer.Add((20,20),1)
378+
379+
mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
380+
self.panel.SetSizer(mainSizer)
381+
self.panel.Fit()
382+
self.Fit()
383+
384+
def GetSelection(self):
385+
return self.Trans,self.Cent,self.Laue
386+
387+
def OnOk(self,event):
388+
parent = self.GetParent()
389+
if parent is not None: parent.Raise()
390+
self.EndModal(wx.ID_OK)
391+
392+
def OnCancel(self,event):
393+
parent = self.GetParent()
394+
if parent is not None: parent.Raise()
395+
self.EndModal(wx.ID_CANCEL)
396+
258397
def GUIpatches():
259398
'Misc fixes that only needs to be done when running a GUI'
260399
try: # patch for LANG environment var problem on occasional OSX machines
@@ -6716,13 +6855,14 @@ def _makemenu(): # routine to create menu when first used
67166855
self.PWDRMenu = _makemenu
67176856

67186857
# HKLF - many wxIDs defined in PWDR & SASD above
6719-
G2G.Define_wxId('wxID_3DALLHKLPLOT','wxID_MERGEHKL','wxID_FIXFSQSQDATA')
6858+
G2G.Define_wxId('wxID_3DALLHKLPLOT','wxID_SORTHKL','wxID_MERGEHKL','wxID_FIXFSQSQDATA')
67206859
def _makemenu(): # routine to create menu when first used
67216860
self.HKLFMenu = wx.MenuBar()
67226861
self.PrefillDataMenu(self.HKLFMenu)
67236862
self.ErrorAnal = wx.Menu(title='')
67246863
self.HKLFMenu.Append(menu=self.ErrorAnal,title='Commands')
67256864
self.ErrorAnal.Append(G2G.wxID_PWDANALYSIS,'Error Analysis','Error analysis on single crystal data')
6865+
self.ErrorAnal.Append(G2G.wxID_SORTHKL,'Sort HKLs','Transform & sort HKLF data to new histogram')
67266866
self.ErrorAnal.Append(G2G.wxID_MERGEHKL,'Merge HKLs','Transform & merge HKLF data to new histogram')
67276867
self.ErrorAnal.Append(G2G.wxID_1DHKLSTICKPLOT,'Plot 1D HKLs','Plot of HKLs from single crystal data in 1D')
67286868
self.ErrorAnal.Append(G2G.wxID_3DALLHKLPLOT,'Plot all 3D HKLs','Plot HKLs from all single crystal data in 3D')
@@ -8146,6 +8286,7 @@ def onEditSimRange(event):
81468286

81478287
def OnPlot1DHKL(event):
81488288
'''Plots a 1D stick diagram of reflection intensities'''
8289+
data = G2frame.GPXtree.GetItemPyData(G2frame.PatternId)
81498290
refList = data[1]['RefList']
81508291
G2plt.Plot1DSngl(G2frame,newPlot=True,hklRef=refList,Super=Super,Title=phaseName)
81518292

@@ -8196,6 +8337,7 @@ def OnPlotAll3DHKL(event):
81968337

81978338
def OnMergeHKL(event):
81988339
'''Merge HKLF data sets to unique set according to Laue symmetry'''
8340+
data = G2frame.GPXtree.GetItemPyData(G2frame.PatternId)
81998341
Name = G2frame.GPXtree.GetItemText(G2frame.PatternId)
82008342
Inst = G2frame.GPXtree.GetItemPyData(GetGPXtreeItemId(G2frame,
82018343
G2frame.PatternId,'Instrument Parameters'))
@@ -8332,6 +8474,95 @@ def OnMergeHKL(event):
83328474
G2frame.GPXtree.SetItemPyData(G2frame.GPXtree.AppendItem(Id,text='Reflection List'),{}) #dummy entry for GUI use
83338475
G2frame.GPXtree.SetItemPyData(Id,newData)
83348476

8477+
def OnSortHKL(event):
8478+
'''Sort HKLF data sets to unique set according to Laue symmetry - no merge'''
8479+
data = G2frame.GPXtree.GetItemPyData(G2frame.PatternId)
8480+
Name = G2frame.GPXtree.GetItemText(G2frame.PatternId)
8481+
Inst = G2frame.GPXtree.GetItemPyData(GetGPXtreeItemId(G2frame,
8482+
G2frame.PatternId,'Instrument Parameters'))
8483+
CId = GetGPXtreeItemId(G2frame,G2frame.PatternId,'Comments')
8484+
if CId:
8485+
Comments = G2frame.GPXtree.GetItemPyData(CId)
8486+
else:
8487+
Comments = []
8488+
refList = np.copy(data[1]['RefList'])
8489+
Comments.append(' Sorting %d reflections from %s'%(len(refList),Name))
8490+
if 'Type' not in data[0]:
8491+
G2frame.ErrorDialog('Unknown data type','Define data type in Instrument Parameters first')
8492+
return
8493+
dlg = HKLSortDialog(G2frame,data)
8494+
try:
8495+
if dlg.ShowModal() == wx.ID_OK:
8496+
Trans,Cent,Laue = dlg.GetSelection()
8497+
else:
8498+
return
8499+
finally:
8500+
dlg.Destroy()
8501+
Super = data[1]['Super']
8502+
isup = 0
8503+
if Super:
8504+
isup = 1
8505+
refList,badRefs = G2lat.transposeHKLF(Trans,isup,refList)
8506+
if len(badRefs): #do I want to list badRefs?
8507+
G2frame.ErrorDialog('Failed transformation','Matrix yields fractional hkl indices')
8508+
return
8509+
Comments.append(" Transformation M*H = H' applied; M=")
8510+
Comments.append(str(Trans))
8511+
refList = G2lat.LaueUnique(Laue,refList)
8512+
dlg = wx.ProgressDialog('Build HKL dictonary','',len(refList)+1,
8513+
style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE)
8514+
HKLdict = {}
8515+
lenhkl = len(refList[0])
8516+
sumExt = 0.
8517+
Next = 0
8518+
for ih,hkl in enumerate(refList):
8519+
if hkl[3+Super] == 0:
8520+
sumExt += hkl[5+Super]
8521+
Next += 1
8522+
if str(hkl[:3+Super]) not in HKLdict:
8523+
HKLdict[str(hkl[:3+Super])] = [hkl[:3+Super],[hkl[3+Super:lenhkl],]]
8524+
else:
8525+
HKLdict[str(hkl[:3+Super])][1].append(hkl[3+Super:lenhkl])
8526+
dlg.Update(ih)
8527+
dlg.Destroy()
8528+
sortRef = []
8529+
aveExt = sumExt/Next
8530+
print('Ave extinct Fo^2: %f.2'%(aveExt))
8531+
dlg = wx.ProgressDialog('Processing sort','',len(HKLdict)+1,
8532+
style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE)
8533+
HKLs = list(HKLdict)
8534+
HKLs.sort()
8535+
for ih,hkl in enumerate(HKLs):
8536+
HKL = HKLdict[hkl]
8537+
for Hdata in HKL[1]:
8538+
sortRef.append(np.hstack((HKL[0],Hdata)))
8539+
dlg.Destroy()
8540+
sortRef = np.array(sortRef)
8541+
HKLFlist = []
8542+
newName = Name+u' '+Laue+'Sort'
8543+
if G2frame.GPXtree.GetCount():
8544+
item, cookie = G2frame.GPXtree.GetFirstChild(G2frame.root)
8545+
while item:
8546+
name = G2frame.GPXtree.GetItemText(item)
8547+
if name.startswith('HKLF ') and name not in HKLFlist:
8548+
HKLFlist.append(name)
8549+
item, cookie = G2frame.GPXtree.GetNextChild(G2frame.root, cookie)
8550+
newName = G2obj.MakeUniqueLabel(newName,HKLFlist)
8551+
newData = copy.deepcopy(data)
8552+
newData[0]['ranId'] = ran.randint(0,sys.maxsize)
8553+
newData[1]['RefList'] = sortRef
8554+
newData[0]['Nobs'] = sortRef.shape[0]
8555+
newData[0]['wR'] = 0.0
8556+
keys = list(newData[0].keys())
8557+
for item in keys:
8558+
if ':' in item:
8559+
del newData[0][item]
8560+
Id = G2frame.GPXtree.AppendItem(parent=G2frame.root,text=newName)
8561+
G2frame.GPXtree.SetItemPyData(G2frame.GPXtree.AppendItem(Id,text='Comments'),Comments)
8562+
G2frame.GPXtree.SetItemPyData(G2frame.GPXtree.AppendItem(Id,text='Instrument Parameters'),Inst)
8563+
G2frame.GPXtree.SetItemPyData(G2frame.GPXtree.AppendItem(Id,text='Reflection List'),{}) #dummy entry for GUI use
8564+
G2frame.GPXtree.SetItemPyData(Id,newData)
8565+
83358566
def OnFixFsqFsq(event):
83368567
''' Fix HKLF data that had been misimported as F instead of F^2'''
83378568
Name = G2frame.GPXtree.GetItemText(G2frame.PatternId)
@@ -8459,6 +8690,7 @@ def OnEditMag(**args):
84598690
elif kind in ['HKLF',]:
84608691
SetDataMenuBar(G2frame,G2frame.dataWindow.HKLFMenu)
84618692
G2frame.Bind(wx.EVT_MENU, OnErrorAnalysis, id=G2G.wxID_PWDANALYSIS)
8693+
G2frame.Bind(wx.EVT_MENU, OnSortHKL, id=G2G.wxID_SORTHKL)
84628694
G2frame.Bind(wx.EVT_MENU, OnMergeHKL, id=G2G.wxID_MERGEHKL)
84638695
G2frame.Bind(wx.EVT_MENU, OnPlot1DHKL, id=G2G.wxID_1DHKLSTICKPLOT)
84648696
# G2frame.Bind(wx.EVT_MENU, OnPlot3DHKL, id=G2G.wxID_PWD3DHKLPLOT)

0 commit comments

Comments
 (0)