Skip to content

Commit 307316c

Browse files
committed
add the support code for the new after-refinement dialog (see #288), but not yet in use
1 parent 8b270a1 commit 307316c

2 files changed

Lines changed: 127 additions & 11 deletions

File tree

GSASII/GSASIIctrlGUI.py

Lines changed: 116 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,9 +2643,20 @@ def G2AfterFit(parent,msg,title='Error',vartbl=[],txtwidth=300):
26432643
results = SortableLstCtrl(dlg)
26442644
results.PopulateHeader(labels, just)
26452645
for i,l in enumerate(displayTable): results.PopulateLine(i,l)
2646-
for i,j in enumerate(labels): results.SetColWidth(i) # set widths to automatic
2646+
# set widths to automatic
2647+
results.SetColWidth(0)
2648+
results.SetColWidth(1,sortType='float')
2649+
results.SetColWidth(2,sortType='float')
2650+
results.SetColWidth(3,sortType='abs')
2651+
results.SetColWidth(4)
2652+
results.SetInitialSortColumn(3,False)
2653+
results.SetClientSize((450,250))
2654+
results.SetMinSize((450,250))
26472655
else:
2648-
results = wx.StaticText(dlg,wx.ID_ANY,'no results to display')
2656+
results = wx.BoxSizer(wx.VERTICAL)
2657+
results.Add((-1,-1),1,wx.EXPAND)
2658+
results.Add(wx.StaticText(dlg,wx.ID_ANY,' (no parameter changes\nto display) ',size=(350,-1),style=wx.ALIGN_CENTER))
2659+
results.Add((-1,-1),1,wx.EXPAND)
26492660
txtSizer.Add(results,1,wx.EXPAND,0)
26502661
mainSizer.Add(txtSizer,1,wx.EXPAND)
26512662

@@ -2669,7 +2680,9 @@ def G2AfterFit(parent,msg,title='Error',vartbl=[],txtwidth=300):
26692680
ans = dlg.ShowModal()
26702681
dlg.Destroy()
26712682
return ans
2672-
2683+
#ans = dlg.Show()
2684+
#breakpoint()
2685+
26732686
def ShowScrolledInfo(parent,txt,width=600,height=400,header='Warning info',
26742687
buttonlist=None):
26752688
'''Simple code to display possibly extensive error or warning text
@@ -7695,6 +7708,7 @@ class SortableLstCtrl(wx.Panel):
76957708
sortPanel.PopulateHeader([f'label{i}' for i in range(4)],4*[0])
76967709
for i,l in enumerate(data): sortPanel.PopulateLine(i,l)
76977710
for i in range(4): sortPanel.SetColWidth(i) # set width to automatic
7711+
sortPanel.SetColWidth(1,sortType='float') # sort 1st column by numeric value not str
76987712
'''
76997713
def __init__(self, parent):
77007714
wx.Panel.__init__(self, parent, wx.ID_ANY)#, style=wx.WANTS_CHARS)
@@ -7740,7 +7754,8 @@ def PopulateLine(self, key, data):
77407754
self.list.SetItemData(index, key)
77417755
self.list.itemDataMap[key] = data
77427756

7743-
def SetColWidth(self,col,width=None,auto=True,minwidth=0,maxwidth=None):
7757+
def SetColWidth(self,col,width=None,auto=True,minwidth=0,maxwidth=None,
7758+
sortType='str'):
77447759
'''Sets the column width.
77457760
77467761
:param int width: the column width in pixels
@@ -7761,6 +7776,67 @@ def SetColWidth(self,col,width=None,auto=True,minwidth=0,maxwidth=None):
77617776
self.list.SetColumnWidth(col, maxwidth)
77627777
else:
77637778
print('Error in SetColWidth: use either auto or width')
7779+
if sortType == 'float':
7780+
self.list.FloatCols.append(col)
7781+
elif sortType == 'abs':
7782+
self.list.AbsFloatCols.append(col)
7783+
elif sortType != 'str':
7784+
printf('SortableLstCtrl.SetColWidth warning: unexpected sortType value ({sortType})')
7785+
7786+
def SetInitialSortColumn(self, col, ascending=True):
7787+
'''Sets the initial column to be used for sorting when the table is first displayed.
7788+
This method should be called after all PopulateLine calls are complete.
7789+
7790+
:param int col: the column index (0-based) to sort by initially
7791+
:param bool ascending: if True (default), sort in ascending order; if False, descending
7792+
'''
7793+
# Get the sort function
7794+
sorter = self.list.GetColumnSorter()
7795+
7796+
# Get all keys from itemDataMap
7797+
keys = list(self.list.itemDataMap.keys())
7798+
7799+
# Sort the keys using the comparison function
7800+
from functools import cmp_to_key
7801+
7802+
def make_cmp(col_idx, asc):
7803+
"""Create a comparison function for the given column"""
7804+
def cmp_func(key1, key2):
7805+
data1 = self.list.itemDataMap[key1][col_idx]
7806+
data2 = self.list.itemDataMap[key2][col_idx]
7807+
7808+
# For columns designated as self.AbsFloatCols, sort by absolute numerical value
7809+
if col_idx in self.list.AbsFloatCols:
7810+
try:
7811+
val1 = abs(float(data1))
7812+
val2 = abs(float(data2))
7813+
result = (val1 > val2) - (val1 < val2)
7814+
except (ValueError, TypeError):
7815+
result = (data1 > data2) - (data1 < data2)
7816+
elif col_idx in self.list.FloatCols:
7817+
try:
7818+
val1 = float(data1)
7819+
val2 = float(data2)
7820+
result = (val1 > val2) - (val1 < val2)
7821+
except (ValueError, TypeError):
7822+
result = (data1 > data2) - (data1 < data2)
7823+
else:
7824+
# For other columns, use string comparison
7825+
result = (data1 > data2) - (data1 < data2)
7826+
7827+
return result if asc else -result
7828+
return cmp_func
7829+
7830+
sorted_keys = sorted(keys, key=cmp_to_key(make_cmp(col, ascending)))
7831+
7832+
# Rebuild the list in sorted order
7833+
self.list.DeleteAllItems()
7834+
for key in sorted_keys:
7835+
data = self.list.itemDataMap[key]
7836+
index = self.list.InsertItem(self.list.GetItemCount(), data[0])
7837+
for i, d in enumerate(data[1:]):
7838+
self.list.SetItem(index, i+1, d)
7839+
self.list.SetItemData(index, key)
77647840

77657841
try:
77667842
class G2LstCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin):
@@ -7785,12 +7861,48 @@ def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,
77857861
self.DownArrow = self.il.Add(SmallDnArrow.GetBitmap())
77867862
self.parent=parent
77877863
self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
7864+
self.FloatCols = []
7865+
self.AbsFloatCols = []
77887866

77897867
def GetListCtrl(self): # needed for sorting
77907868
return self
77917869
def GetSortImages(self):
77927870
#return (self.parent.DownArrow, self.parent.UpArrow)
77937871
return (self.DownArrow, self.UpArrow)
7872+
def GetColumnSorter(self):
7873+
"""Custom sorter that handles absolute numerical values for columns 1, 2, 3 (2nd, 3rd, 4th columns)"""
7874+
def compare_func(key1, key2):
7875+
col = self.GetSortState()[0]
7876+
ascending = self.GetSortState()[1]
7877+
7878+
# Get data for both rows
7879+
data1 = self.itemDataMap[key1][col]
7880+
data2 = self.itemDataMap[key2][col]
7881+
7882+
# For columns designated as self.AbsFloatCols, sort by absolute numerical value
7883+
if col in self.AbsFloatCols:
7884+
try:
7885+
val1 = abs(float(data1))
7886+
val2 = abs(float(data2))
7887+
result = (val1 > val2) - (val1 < val2)
7888+
except (ValueError, TypeError):
7889+
# Fall back to string comparison if conversion fails
7890+
result = (data1 > data2) - (data1 < data2)
7891+
elif col in self.FloatCols:
7892+
try:
7893+
val1 = float(data1)
7894+
val2 = float(data2)
7895+
result = (val1 > val2) - (val1 < val2)
7896+
except (ValueError, TypeError):
7897+
# Fall back to string comparison if conversion fails
7898+
result = (data1 > data2) - (data1 < data2)
7899+
else:
7900+
# For other columns, use string comparison
7901+
result = (data1 > data2) - (data1 < data2)
7902+
7903+
return result if ascending else -result
7904+
7905+
return compare_func
77947906
except TypeError:
77957907
# avoid "duplicate base class _MockObject" error in class G2LstCtrl():
77967908
# where listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin are same

GSASII/GSASIIdataGUI.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5556,18 +5556,21 @@ def OnRefine(self,event):
55565556
tbl = [] # assemble a list of changed parameters
55575557
for i in Rvals.get('parmDictAfterFit',{}):
55585558
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 = ''
5559+
try:
5560+
mag = max(abs(Rvals['parmDictAfterFit'][i]),
5561+
abs(Rvals['parmDictBeforeFit'][i]))
5562+
diff = abs(Rvals['parmDictAfterFit'][i]-Rvals['parmDictBeforeFit'][i])
5563+
if mag < 1e-5 and diff < 1e-7: continue
5564+
if diff/mag < 1e-5: continue
5565+
except:
5566+
continue
5567+
txt = '?'
55655568
v = G2obj.getVarDescr(i)
55665569
if v is not None and v[-1] is not None:
55675570
txt = G2obj.fmtVarDescr(i)
55685571
tbl.append((i,Rvals['parmDictBeforeFit'][i],Rvals['parmDictAfterFit'][i],txt))
55695572
lbl = f'Refinement results, Rw={Rw:.3f}'
5570-
#ans = G2G.G2AfterFit(self,text,lbl,tbl)
5573+
#ans = G2G.G2AfterFit(self,text,lbl,tbl) # this replaces the next 8 lines
55715574
text += '\nLoad new result?'
55725575
dlg2 = wx.MessageDialog(self,text,lbl,wx.OK|wx.CANCEL)
55735576
dlg2.CenterOnParent()
@@ -5576,6 +5579,7 @@ def OnRefine(self,event):
55765579
ans = dlg2.ShowModal()
55775580
finally:
55785581
dlg2.Destroy()
5582+
# replace above with G2G.G2AfterFit line
55795583
if ans == wx.ID_OK: # refinement has been accepted save, log & display
55805584
self.reloadFromGPX(rtext,Rvals)
55815585
G2IO.LogCellChanges(self)

0 commit comments

Comments
 (0)