Skip to content

Commit 8b270a1

Browse files
committed
Start work on dialog to show refinement results; plot cell parms in Notebook; Add commmand line arg for python file
1 parent 5e1207e commit 8b270a1

3 files changed

Lines changed: 159 additions & 50 deletions

File tree

GSASII/GSASIIGUI.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,22 @@ def MacOpenFiles(self, filenames):
9292
# if GSASIIpath.HowIsG2Installed().startswith('git'):
9393
# gitCheckUpdates(None)
9494
from . import GSASIIdataGUI as G2gd
95+
GSASIIpath.InvokeDebugOpts()
96+
# debug capability. If a Python file is on the command-line import it
97+
if GSASIIpath.GetConfigValue('debug') and len(sys.argv) == 2:
98+
import os
99+
if os.path.splitext(sys.argv[1])[1] == '.py':
100+
print (f'{60*"="}\n"Importing" file {sys.argv[1]}\n{60*"="}')
101+
import importlib.util
102+
spec = importlib.util.spec_from_file_location('test_module', sys.argv[1])
103+
module = importlib.util.module_from_spec(spec)
104+
sys.modules['test_module'] = module
105+
spec.loader.exec_module(module)
106+
#test_module = module
107+
sys.exit()
95108
G2gd.GSASIImain(application) # start the GUI
96109
if sys.platform == "darwin":
97110
wx.CallLater(50,application.ClearStartup)
98-
GSASIIpath.InvokeDebugOpts()
99111
application.MainLoop()
100112

101113
if __name__ == '__main__':

GSASII/GSASIIctrlGUI.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2609,6 +2609,67 @@ def G2MessageBox(parent,msg,title='Error'):
26092609
dlg.ShowModal()
26102610
dlg.Destroy()
26112611

2612+
################################################################################
2613+
def G2AfterFit(parent,msg,title='Error',vartbl=[],txtwidth=300):
2614+
'''Shows the results from a refinement
2615+
2616+
:param wx.Frame parent: pointer to parent of window, usually G2frame
2617+
:param str msg: text from refinement results
2618+
:param str title: text to label window
2619+
:param list vartbl: a list of lists. The contents of each inner list
2620+
item will be [var-name, val-before, val-after, meaning]
2621+
:param int txtwidth: width (in pixesl) to display msg. Defaults to 300
2622+
'''
2623+
2624+
displayTable = [ # create table to show from input
2625+
(var,
2626+
f'{before:.6g}',
2627+
f'{after:.6g}',
2628+
f'{after-before:.6g}',
2629+
what) for (var,before,after,what) in vartbl]
2630+
labels = ('var','before','after','change','parameter description')
2631+
just = (0 , 1 , 1 , 1 , 0)
2632+
dlg = wx.Dialog(parent.GetTopLevelParent(), wx.ID_ANY, title,
2633+
style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
2634+
mainSizer = wx.BoxSizer(wx.VERTICAL)
2635+
2636+
txtSizer = wx.BoxSizer(wx.HORIZONTAL)
2637+
txt = wx.StaticText(dlg,wx.ID_ANY,msg)
2638+
txt.Wrap(txtwidth-20)
2639+
#txt.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
2640+
txtSizer.Add(txt,0,wx.RIGHT|wx.LEFT,5)
2641+
2642+
if displayTable:
2643+
results = SortableLstCtrl(dlg)
2644+
results.PopulateHeader(labels, just)
2645+
for i,l in enumerate(displayTable): results.PopulateLine(i,l)
2646+
for i,j in enumerate(labels): results.SetColWidth(i) # set widths to automatic
2647+
else:
2648+
results = wx.StaticText(dlg,wx.ID_ANY,'no results to display')
2649+
txtSizer.Add(results,1,wx.EXPAND,0)
2650+
mainSizer.Add(txtSizer,1,wx.EXPAND)
2651+
2652+
mainSizer.Add((-1,5))
2653+
txt = wx.StaticText(dlg,wx.ID_ANY,'Load new result?')
2654+
mainSizer.Add(txt,0,wx.CENTER)
2655+
2656+
btnsizer = wx.BoxSizer(wx.HORIZONTAL)
2657+
btn = wx.Button(dlg, wx.ID_CANCEL)
2658+
btn.Bind(wx.EVT_BUTTON,lambda event: dlg.EndModal(wx.ID_CANCEL))
2659+
btnsizer.Add(btn)
2660+
btn = wx.Button(dlg, wx.ID_OK)
2661+
btn.Bind(wx.EVT_BUTTON,lambda event: dlg.EndModal(wx.ID_OK))
2662+
btnsizer.Add(btn)
2663+
mainSizer.Add(btnsizer, 0, wx.ALIGN_CENTER|wx.ALL, 5)
2664+
dlg.SetSizer(mainSizer)
2665+
mainSizer.Fit(dlg)
2666+
2667+
dlg.Layout()
2668+
dlg.CentreOnParent()
2669+
ans = dlg.ShowModal()
2670+
dlg.Destroy()
2671+
return ans
2672+
26122673
def ShowScrolledInfo(parent,txt,width=600,height=400,header='Warning info',
26132674
buttonlist=None):
26142675
'''Simple code to display possibly extensive error or warning text
@@ -7621,6 +7682,19 @@ class SortableLstCtrl(wx.Panel):
76217682
widths.
76227683
76237684
:param wx.Frame parent: parent object for control
7685+
7686+
Example::
7687+
7688+
data = [
7689+
(':0:sig-0', '30.7906', '30.7907', 'Pwd=SNAP066555: TOF profile term'),
7690+
(':0:sig-1', '208.419', '208.419', 'Pwd=SNAP066555: TOF profile term'),
7691+
(':0:Scale', '582006', '582006', 'Pwd=SNAP066555: Scale factor'),
7692+
(':1:Scale', '592440', '592440', 'Pwd=SNAP06 (1): Scale factor'),
7693+
]
7694+
sortPanel = G2G.SortableLstCtrl(G2frame)
7695+
sortPanel.PopulateHeader([f'label{i}' for i in range(4)],4*[0])
7696+
for i,l in enumerate(data): sortPanel.PopulateLine(i,l)
7697+
for i in range(4): sortPanel.SetColWidth(i) # set width to automatic
76247698
'''
76257699
def __init__(self, parent):
76267700
wx.Panel.__init__(self, parent, wx.ID_ANY)#, style=wx.WANTS_CHARS)

GSASII/GSASIIdataGUI.py

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5552,49 +5552,52 @@ def OnRefine(self,event):
55525552
text += ('\nWARNING: Marquardt factor raised to point where steepest descents dominates fitting;'+
55535553
' minimum may not have been reached or your result may be a false minimum.'+
55545554
' You should reconsider which parameters you refine: check covariance matrix.\n')
5555-
text += '\nLoad new result?'
55565555
#breakpoint()
5557-
# assemble a list of changed parameters
5558-
# tbl = []
5559-
# for i in Rvals['parmDictAfterFit']:
5560-
# if i not in Rvals['parmDictBeforeFit']: continue
5561-
# if (Rvals['parmDictAfterFit'][i] != Rvals['parmDictBeforeFit'][i] or
5562-
# #np.isclose(Rvals['parmDictAfterFit'][i],Rvals['parmDictBeforeFit'][i])
5563-
# i in Rvals['parmDictvaryList']):
5564-
# txt = ''
5565-
# v = G2obj.getVarDescr(i)
5566-
# if v is not None and v[-1] is not None:
5567-
# txt = G2obj.fmtVarDescr(i)
5568-
# tbl.append((i,Rvals['parmDictBeforeFit'][i],Rvals['parmDictAfterFit'][i],txt))
5569-
dlg2 = wx.MessageDialog(self,text,
5570-
f'Refinement results, Rw={Rw:.3f}',
5571-
wx.OK|wx.CANCEL)
5556+
tbl = [] # assemble a list of changed parameters
5557+
for i in Rvals.get('parmDictAfterFit',{}):
5558+
if i not in Rvals['parmDictBeforeFit']: continue
5559+
mag = max(abs(Rvals['parmDictAfterFit'][i]),
5560+
abs(Rvals['parmDictBeforeFit'][i]))
5561+
diff = abs(Rvals['parmDictAfterFit'][i]-Rvals['parmDictBeforeFit'][i])
5562+
if mag < 1e-5 and diff < 1e-7: continue
5563+
if diff/mag < 1e-5: continue
5564+
txt = ''
5565+
v = G2obj.getVarDescr(i)
5566+
if v is not None and v[-1] is not None:
5567+
txt = G2obj.fmtVarDescr(i)
5568+
tbl.append((i,Rvals['parmDictBeforeFit'][i],Rvals['parmDictAfterFit'][i],txt))
5569+
lbl = f'Refinement results, Rw={Rw:.3f}'
5570+
#ans = G2G.G2AfterFit(self,text,lbl,tbl)
5571+
text += '\nLoad new result?'
5572+
dlg2 = wx.MessageDialog(self,text,lbl,wx.OK|wx.CANCEL)
55725573
dlg2.CenterOnParent()
5574+
ans = False
55735575
try:
5574-
if dlg2.ShowModal() == wx.ID_OK:
5575-
self.reloadFromGPX(rtext,Rvals)
5576-
G2IO.LogCellChanges(self)
5577-
# parameter logging into notebook
5578-
txt = ''
5579-
if Controls.get('LoggedVars') and 'parmDictAfterFit' in Rvals:
5580-
txt = ''
5581-
for i in sorted(Controls['LoggedVars']):
5582-
if i not in Rvals['parmDictAfterFit']: continue
5583-
if txt: txt += ', '
5584-
txt += (f'{i} : {Rvals["parmDictAfterFit"][i]:.7g}')
5585-
elif GSASIIpath.GetConfigValue('LogAllVars') and 'parmDictAfterFit' in Rvals:
5586-
txt = ''
5587-
for c,i in enumerate(Rvals['parmDictvaryList']):
5588-
if i not in Rvals['parmDictAfterFit']: continue
5589-
if txt: txt += ', '
5590-
txt += (f'{i} : {Rvals["parmDictAfterFit"][i]:.7g}')
5591-
if txt: self.AddToNotebook(txt,'VALS',False)
5592-
if refPlotUpdate:
5593-
refPlotUpdate({},restore=True)
5594-
refPlotUpdate = None
5595-
self.ResetPlots()
5576+
ans = dlg2.ShowModal()
55965577
finally:
55975578
dlg2.Destroy()
5579+
if ans == wx.ID_OK: # refinement has been accepted save, log & display
5580+
self.reloadFromGPX(rtext,Rvals)
5581+
G2IO.LogCellChanges(self)
5582+
# log parameters into notebook
5583+
txt = ''
5584+
if Controls.get('LoggedVars') and 'parmDictAfterFit' in Rvals:
5585+
txt = ''
5586+
for i in sorted(Controls['LoggedVars']):
5587+
if i not in Rvals['parmDictAfterFit']: continue
5588+
if txt: txt += ', '
5589+
txt += (f'{i} : {Rvals["parmDictAfterFit"][i]:.7g}')
5590+
elif GSASIIpath.GetConfigValue('LogAllVars') and 'parmDictAfterFit' in Rvals:
5591+
txt = ''
5592+
for c,i in enumerate(Rvals['parmDictvaryList']):
5593+
if i not in Rvals['parmDictAfterFit']: continue
5594+
if txt: txt += ', '
5595+
txt += (f'{i} : {Rvals["parmDictAfterFit"][i]:.7g}')
5596+
if txt: self.AddToNotebook(txt,'VALS',False)
5597+
if refPlotUpdate: # restore plot if liveplot in use
5598+
refPlotUpdate({},restore=True)
5599+
refPlotUpdate = None
5600+
self.ResetPlots() # delete any plots that have not been updated
55985601
elif 'psing' in Rvals:
55995602
if 'msg' in Rvals:
56005603
msg = 'Refinement results:\n\n'
@@ -7601,15 +7604,28 @@ def onPlotNotebook():
76017604
pos = []
76027605
for l in data:
76037606
if '[REF]' in l: c += 1
7604-
if '[VALS]' not in l: continue
7605-
v = {i.split(' : ')[0].strip() : i.split(' : ')[1]
7606-
for i in l[6:].split(',')}
7607-
if target not in v: continue
7608-
try:
7609-
vals.append(float(v[target]))
7610-
pos.append(c)
7611-
except:
7612-
pass
7607+
if '[VALS]' in l:
7608+
v = {i.split(' : ')[0].strip() : i.split(' : ')[1]
7609+
for i in l[6:].split(',')}
7610+
if target not in v:
7611+
continue
7612+
try:
7613+
vals.append(float(v[target]))
7614+
pos.append(c)
7615+
except:
7616+
pass
7617+
if '[CEL]' in l:
7618+
ph = l.split('Phase')[1].split()[0]
7619+
hst = l.split('Hist')[1].split(':')[0].strip()
7620+
vars = [i.split('=')[0] for i in l.split(':')[1].split()]
7621+
vars = [f'{v}[p{ph}_h{hst}]' for v in vars]
7622+
if target not in vars: continue
7623+
values = [i.split('=')[1].split('(')[0] for i in l.split(':')[1].split()]
7624+
try:
7625+
vals.append(float(dict(zip(vars,values))[target]))
7626+
pos.append(c)
7627+
except:
7628+
pass
76137629
X = np.array(pos)
76147630
Y = np.array(vals)
76157631
if len(Y) == 0:
@@ -7686,8 +7702,13 @@ def onPlotNotebook():
76867702
# find recorded parameters
76877703
v = []
76887704
for l in data:
7689-
if '[VALS]' not in l: continue
7690-
v += [i.split(' : ')[0].strip() for i in l[6:].split(',') if i.strip()]
7705+
if '[VALS]' in l:
7706+
v += [i.split(' : ')[0].strip() for i in l[6:].split(',') if i.strip()]
7707+
if '[CEL]' in l:
7708+
ph = l.split('Phase')[1].split()[0]
7709+
hst = l.split('Hist')[1].split(':')[0].strip()
7710+
vars = [i.split('=')[0] for i in l.split(':')[1].split()]
7711+
v += [f'{v}[p{ph}_h{hst}]' for v in vars]
76917712
plotable = ['Rw','GOF']
76927713
plotable += sorted(list(set(v)))
76937714
NBplotLbl = {'none':True}
@@ -7749,6 +7770,8 @@ def onPlotNotebook():
77497770
# indent all but timestamps
77507771
for l in line.strip().split('\n'):
77517772
if not first: textBox.AppendText("\n")
7773+
if prefix == 'VALS':
7774+
l = 'Values: '+l.replace(' : ','=')
77527775
textBox.AppendText(' '+l.strip())
77537776
first = False
77547777
else:

0 commit comments

Comments
 (0)