Skip to content

Commit 68b0c08

Browse files
committed
WIP: shows table of HAP values, but can we make row labels not scroll?
1 parent 751d211 commit 68b0c08

File tree

3 files changed

+376
-22
lines changed

3 files changed

+376
-22
lines changed

GSASII/GSASIIgroupGUI.py

Lines changed: 356 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,368 @@
3838
# from . import GSASIIctrlGUI as G2G
3939
# from . import GSASIImath as G2mth
4040
# from . import GSASIIElem as G2elem
41-
# from . import GSASIIspc as G2spc
42-
# from . import GSASIIlattice as G2lat
41+
from . import GSASIIspc as G2spc
42+
from . import GSASIIlattice as G2lat
4343
# from . import GSASIIpwd as G2pwd
4444
from . import GSASIIctrlGUI as G2G
4545
from . import GSASIIpwdplot as G2pwpl
4646
WACV = wx.ALIGN_CENTER_VERTICAL
4747

4848
def UpdateGroup(G2frame,item):
4949
G2gd.SetDataMenuBar(G2frame)
50-
G2frame.dataWindow.helpKey = "Groups/PWDR"
51-
topSizer = G2frame.dataWindow.topBox
52-
parent = G2frame.dataWindow.topPanel
53-
topSizer.Add(wx.StaticText(parent,label=' Group edit goes here someday'),0,WACV)
54-
topSizer.Add((-1,-1),1,wx.EXPAND)
55-
topSizer.Add(G2G.HelpButton(parent,helpIndex=G2frame.dataWindow.helpKey))
56-
G2G.HorizontalLine(G2frame.dataWindow.GetSizer(),G2frame.dataWindow)
57-
#G2frame.dataWindow.GetSizer().Add(text,1,wx.ALL|wx.EXPAND)
50+
G2frame.dataWindow.helpKey = "Groups/Powder"
51+
# topSizer = G2frame.dataWindow.topBox
52+
# parent = G2frame.dataWindow.topPanel
53+
# topSizer.Add(wx.StaticText(parent,label=' Group edit goes here someday'),0,WACV)
54+
# topSizer.Add((-1,-1),1,wx.EXPAND)
55+
# topSizer.Add(G2G.HelpButton(parent,helpIndex=G2frame.dataWindow.helpKey))
56+
# G2G.HorizontalLine(G2frame.dataWindow.GetSizer(),G2frame.dataWindow)
57+
# #G2frame.dataWindow.GetSizer().Add(text,1,wx.ALL|wx.EXPAND)
5858
G2frame.groupName = G2frame.GPXtree.GetItemText(item)
59+
HAPframe(G2frame)
5960
G2pwpl.PlotPatterns(G2frame,plotType='GROUP')
61+
62+
def histLabels(G2frame):
63+
# find portion of hist name that is the same and different
64+
Controls = G2frame.GPXtree.GetItemPyData(G2gd.GetGPXtreeItemId(G2frame,G2frame.root, 'Controls'))
65+
groupName = G2frame.groupName
66+
groupDict = Controls.get('Groups',{}).get('groupDict',{})
67+
h0 = groupDict[groupName][0]
68+
msk = [True] * len(h0)
69+
for h in groupDict[groupName][1:]:
70+
msk = [m & (h0i == hi) for h0i,hi,m in zip(h0,h,msk)]
71+
# place rectangular box in the loc of non-common letter(s)
72+
commonltrs = ''.join([h0i if m else '\u25A1' for (h0i,m) in zip(h0,msk)])
73+
#for i,h in enumerate(groupDict[groupName]):
74+
# make list with histogram name unique letters
75+
histlbls = [''.join([hi for (hi,m) in zip(h,msk) if not m])
76+
for h in groupDict[groupName]]
77+
return commonltrs,histlbls
78+
79+
def HAPframe(G2frame):
80+
def OnPageChanged(event):
81+
'respond to a notebook tab'
82+
if event:
83+
page = event.GetSelection()
84+
print('page selected',page,phaseList[page])
85+
else:
86+
page = 0
87+
print('no page selected',phaseList[page])
88+
HAPtable = getHAPvals(G2frame,phaseList[page])
89+
#for hist in HAPtable:
90+
# showTable(phaseList[page],hist,HAPtable[hist])
91+
# clear out old widgets
92+
for panel in HAPtabs:
93+
if panel.GetSizer():
94+
panel.GetSizer().Destroy()
95+
panel = HAPtabs[page]
96+
HAPSizer = wx.FlexGridSizer(0,len(HAPtable)+1,2,10)
97+
# construct a list of row labels, attempting to keep the
98+
# order they appear in the original array
99+
rowsLbls = []
100+
lpos = 0
101+
for hist in HAPtable:
102+
prevkey = None
103+
for key in HAPtable[hist]:
104+
if key not in rowsLbls:
105+
if prevkey is None:
106+
rowsLbls.insert(lpos,key)
107+
lpos += 1
108+
else:
109+
rowsLbls.insert(rowsLbls.index(prevkey)+1,key)
110+
prevkey = key
111+
# label columns with histograms
112+
common,hLbl = histLabels(G2frame)
113+
HAPSizer.Add((-1,-1))
114+
for hist in hLbl:
115+
HAPSizer.Add(wx.StaticText(panel,label=f"\u25A1 = {hist}"),0,
116+
wx.ALIGN_CENTER)
117+
for row in rowsLbls:
118+
HAPSizer.Add(wx.StaticText(panel,label=row),0,WACV)
119+
for hist in HAPtable:
120+
if row not in HAPtable[hist]:
121+
HAPSizer.Add((-1,-1))
122+
elif 'val' in HAPtable[hist][row] and 'ref' in HAPtable[hist][row]:
123+
valrefsiz = wx.BoxSizer(wx.HORIZONTAL)
124+
arr,indx = HAPtable[hist][row]['ref']
125+
valrefsiz.Add(G2G.G2CheckBox(panel,'',arr,indx),0,WACV)
126+
arr,indx = HAPtable[hist][row]['val']
127+
valrefsiz.Add(G2G.ValidatedTxtCtrl(panel,
128+
arr,indx,size=(75,-1)),0,WACV)
129+
HAPSizer.Add(valrefsiz,0,
130+
wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
131+
elif 'val' in HAPtable[hist][row]:
132+
arr,indx = HAPtable[hist][row]['val']
133+
HAPSizer.Add(G2G.ValidatedTxtCtrl(panel,
134+
arr,indx,size=(75,-1)),0,
135+
wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
136+
137+
elif 'ref' in HAPtable[hist][row]:
138+
arr,indx = HAPtable[hist][row]['ref']
139+
HAPSizer.Add(G2G.G2CheckBox(panel,'',arr,indx),0,
140+
wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
141+
elif 'str' in HAPtable[hist][row]:
142+
HAPSizer.Add(wx.StaticText(panel,
143+
label=HAPtable[hist][row]['str']),0,
144+
wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER)
145+
# wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
146+
else:
147+
print('Should not happen',HAPtable[hist][row],hist,row)
148+
panel.SetSizer(HAPSizer)
149+
HAPSizer.Fit(panel)
150+
panel.SetScrollbars(1, 1, HAPSizer.GetMinSize().width,
151+
HAPSizer.GetMinSize().height)
152+
153+
#breakpoint()
154+
155+
#wx.CallAfter(FillDDataWindow,page)
156+
157+
G2frame.dataWindow.ClearData()
158+
159+
topSizer = G2frame.dataWindow.topBox
160+
topParent = G2frame.dataWindow.topPanel
161+
botSizer = G2frame.dataWindow.bottomBox
162+
botParent = G2frame.dataWindow.bottomPanel
163+
common,_ = histLabels(G2frame)
164+
topSizer.Add(wx.StaticText(topParent,label=f'HAP parameters for group "{common}"'),0,WACV)
165+
topSizer.Add((-1,-1),1,wx.EXPAND)
166+
topSizer.Add(G2G.HelpButton(topParent,helpIndex=G2frame.dataWindow.helpKey))
167+
168+
# based on GSASIIddataGUI.MakeHistPhaseWin
169+
midPanel = G2frame.dataWindow
170+
mainSizer = wx.BoxSizer(wx.VERTICAL)
171+
G2G.HorizontalLine(mainSizer,midPanel)
172+
midPanel.SetSizer(mainSizer)
173+
Histograms,Phases = G2frame.GetUsedHistogramsAndPhasesfromTree() # reindex
174+
if not Phases:
175+
mainSizer.Add(wx.StaticText(midPanel,label='There are no phases in use'))
176+
G2frame.dataWindow.SetDataSize()
177+
return
178+
HAPBook = G2G.GSNoteBook(parent=midPanel)
179+
mainSizer.Add(HAPBook,1,wx.ALL|wx.EXPAND,1)
180+
HAPtabs = []
181+
phaseList = []
182+
for phaseName in Phases:
183+
phaseList.append(phaseName)
184+
HAPtabs.append(wx.ScrolledWindow(HAPBook))
185+
HAPBook.AddPage(HAPtabs[-1],phaseName)
186+
HAPBook.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, OnPageChanged)
187+
#G2gd.SetDataMenuBar(G2frame,G2frame.dataWindow.DataMenu)
188+
# fill the 'Select tab' menu
189+
# mid = G2frame.dataWindow.DataMenu.FindMenu('Select tab')
190+
# menu = G2frame.dataWindow.DataMenu.GetMenu(mid)
191+
# items = menu.GetMenuItems()
192+
# for item in items:
193+
# menu.Remove(item)
194+
# if len(phaseList) == 0: return
195+
# for i,page in enumerate(phaseList):
196+
# Id = wx.NewId()
197+
# if menu.FindItem(page) >= 0: continue # is tab already in menu?
198+
# menu.Append(Id,page,'')
199+
# TabSelectionIdDict[Id] = page
200+
# G2frame.Bind(wx.EVT_MENU, OnSelectPage, id=Id)
201+
page = 0
202+
HAPBook.SetSelection(page)
203+
OnPageChanged(None)
204+
#wx.CallAfter(FillDDataWindow,page)
205+
# done
206+
G2frame.dataWindow.SetDataSize()
207+
208+
def getHAPvals(G2frame,phase=None):
209+
sub = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,'Phases')
210+
item, cookie = G2frame.GPXtree.GetFirstChild(sub)
211+
PhaseData = None
212+
while item: # loop over phases
213+
phaseName = G2frame.GPXtree.GetItemText(item)
214+
if phase is None: phase = phaseName
215+
if phase == phaseName:
216+
PhaseData = G2frame.GPXtree.GetItemPyData(item)
217+
break
218+
item, cookie = G2frame.GPXtree.GetNextChild(sub, cookie)
219+
if PhaseData is None:
220+
print(f'Unexpected: Phase {phase!r} not found')
221+
return
222+
223+
Controls = G2frame.GPXtree.GetItemPyData(G2gd.GetGPXtreeItemId(G2frame,G2frame.root, 'Controls'))
224+
groupName = G2frame.groupName
225+
groupDict = Controls.get('Groups',{}).get('groupDict',{})
226+
if groupName not in groupDict:
227+
print(f'Unexpected: {groupName} not in groupDict')
228+
return
229+
# loop over histograms in group
230+
parmDict = {}
231+
for hist in groupDict[groupName]:
232+
parmDict[hist] = makeHAPtbl(G2frame,phase,PhaseData,hist,Controls)
233+
#showTable(phase,hist,parmDict[hist])
234+
return parmDict
235+
236+
def makeHAPtbl(G2frame,phase,PhaseData,hist,Controls):
237+
'''Construct a dict pointing to the contents of the HAP
238+
variables. The contents of the dict will be:
239+
240+
'label' : innerdict
241+
242+
where innerdict can contain the following elements:
243+
244+
'val' : (array, key)
245+
'ref' : (array, key)
246+
'str' : string
247+
248+
One of these will be present.
249+
250+
The 'str' value is something that cannot be edited; If 'str' is
251+
present, it will be the only entry in innerdict.
252+
253+
The 'val' tuple provides a reference to the float value for the
254+
defined quantity, array[key]
255+
256+
The 'ref' tuple provides a reference to the bool value, array[key]
257+
for the refine flag defined quantity
258+
259+
Both 'ref' and 'val' are usually defined together, but either may
260+
occur alone.
261+
262+
:return: the dict, as described above.
263+
'''
264+
SGData = PhaseData['General']['SGData']
265+
cell = PhaseData['General']['Cell'][1:]
266+
Amat,Bmat = G2lat.cell2AB(cell[:6])
267+
G2frame.PatternId = G2gd.GetGPXtreeItemId(G2frame, G2frame.root, hist)
268+
data = G2frame.GPXtree.GetItemPyData(G2frame.PatternId)
269+
HAPdict = PhaseData['Histograms'][hist]
270+
271+
parmDict = {}
272+
# phase fraction
273+
parmDict['Phase fraction'] = {
274+
'val' : (HAPdict['Scale'],0),
275+
'ref' : (HAPdict['Scale'],1),}
276+
277+
parmDict['LeBail extraction'] = {
278+
'str' : "Yes" if HAPdict.get('LeBail') else '(off)'
279+
}
280+
281+
# size values
282+
arr = HAPdict['Size']
283+
if arr[0] == 'isotropic':
284+
parmDict['Size'] = {
285+
'val' : (arr[1],0),
286+
'ref' : (arr[2],0),}
287+
elif arr[0] == 'uniaxial':
288+
parmDict['Size/Eq'] = {
289+
'val' : (arr[1],0),
290+
'ref' : (arr[2],0),}
291+
parmDict['Size/Ax'] = {
292+
'val' : (arr[1],1),
293+
'ref' : (arr[2],1),}
294+
parmDict['Size/dir'] = {
295+
'str' : ','.join([str(i) for i in arr[3]])}
296+
else:
297+
for i,lbl in enumerate(['S11','S22','S33','S12','S13','S23']):
298+
parmDict[f'Size/{lbl}'] = {
299+
'val' : (arr[4],i),
300+
'ref' : (arr[5],i),}
301+
parmDict['Size LGmix'] = {
302+
'val' : (arr[1],2),
303+
'ref' : (arr[2],2),}
304+
305+
# microstrain values
306+
arr = HAPdict['Mustrain']
307+
if arr[0] == 'isotropic':
308+
parmDict['muStrain'] = {
309+
'val' : (arr[1],0),
310+
'ref' : (arr[2],0),}
311+
elif arr[0] == 'uniaxial':
312+
parmDict['muStrain/Eq'] = {
313+
'val' : (arr[1],0),
314+
'ref' : (arr[2],0),}
315+
parmDict['muStrain/Ax'] = {
316+
'val' : (arr[1],1),
317+
'ref' : (arr[2],1),}
318+
parmDict['muStrain/dir'] = {
319+
'str' : ','.join([str(i) for i in arr[3]])}
320+
else:
321+
Snames = G2spc.MustrainNames(SGData)
322+
for i,lbl in enumerate(Snames):
323+
if i >= len(arr[4]): break
324+
parmDict[f'muStrain/{lbl}'] = {
325+
'val' : (arr[4],i),
326+
'ref' : (arr[5],i),}
327+
muMean = G2spc.MuShklMean(SGData,Amat,arr[4][:len(Snames)])
328+
parmDict['muStrain/mean'] = {
329+
'str' : f'{muMean:.2f}'}
330+
parmDict['muStrain LGmix'] = {
331+
'val' : (arr[1],2),
332+
'ref' : (arr[2],2),}
333+
334+
# Hydrostatic terms
335+
Hsnames = G2spc.HStrainNames(SGData)
336+
arr = HAPdict['HStrain']
337+
for i,lbl in enumerate(Hsnames):
338+
if i >= len(arr[0]): break
339+
parmDict[f'Size/{lbl}'] = {
340+
'val' : (arr[0],i),
341+
'ref' : (arr[1],i),}
342+
343+
# Preferred orientation terms
344+
arr = HAPdict['Pref.Ori.']
345+
if arr[0] == 'MD':
346+
parmDict['March-Dollase'] = {
347+
'val' : (arr,1),
348+
'ref' : (arr,2),}
349+
parmDict['M-D/dir'] = {
350+
'str' : ','.join([str(i) for i in arr[3]])}
351+
else:
352+
parmDict['Spherical harmonics'] = {
353+
'ref' : (arr,2),}
354+
parmDict['SH order'] = {
355+
'str' : str(arr[4])}
356+
for lbl in arr[5]:
357+
parmDict[f'SP {lbl}']= {
358+
'val' : (arr[5],lbl),
359+
}
360+
parmDict['SH text indx'] = {
361+
'str' : f'{G2lat.textureIndex(arr[5]):.3f}'}
362+
363+
# misc: Layer Disp, Extinction
364+
try:
365+
parmDict['Layer displacement'] = {
366+
'val' : (HAPdict['Layer Disp'],0),
367+
'ref' : (HAPdict['Layer Disp'],1),}
368+
except KeyError:
369+
pass
370+
try:
371+
parmDict['Extinction'] = {
372+
'val' : (HAPdict['Extinction'],0),
373+
'ref' : (HAPdict['Extinction'],1),}
374+
except KeyError:
375+
pass
376+
try:
377+
parmDict['Babinet A'] = {
378+
'val' : (HAPdict['Babinet']['BabA'],0),
379+
'ref' : (HAPdict['Babinet']['BabA'],1),}
380+
except KeyError:
381+
pass
382+
try:
383+
parmDict['Babinet U'] = {
384+
'val' : (HAPdict['Babinet']['BabU'],0),
385+
'ref' : (HAPdict['Babinet']['BabU'],1),}
386+
except KeyError:
387+
pass
388+
return parmDict
389+
390+
def showTable(phase,hist,parmDict):
391+
# show the variables and values
392+
print(phase,hist)
393+
for sel in parmDict:
394+
arr = parmDict[sel]
395+
val = 'N/A'
396+
if 'val' in arr:
397+
val = arr['val'][0] [arr['val'][1]]
398+
if 'str' in arr:
399+
val = f'"{arr['str']}"'
400+
ref = 'N/A'
401+
if 'ref' in arr:
402+
ref = arr['ref'][0] [arr['ref'][1]]
403+
print(f'{sel!r:20s} {val} {ref}')
404+
print('\n')
405+
#break

GSASII/GSASIImiscGUI.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ def ProjFileOpen(G2frame,showProvenance=True):
577577
# GSASIIpath.IPyBreak()
578578
# insert groups before any individual PDWR items
579579
if datum[0].startswith('PWDR') and groupDict and not groupInserted:
580-
Id = G2frame.GPXtree.AppendItem(parent=G2frame.root,text='Groups/PWDR')
580+
Id = G2frame.GPXtree.AppendItem(parent=G2frame.root,text='Groups/Powder')
581581
G2frame.GPXtree.SetItemPyData(Id,{})
582582
for nam in groupDict:
583583
sub = G2frame.GPXtree.AppendItem(parent=Id,text=nam)

0 commit comments

Comments
 (0)