@@ -2610,29 +2610,90 @@ def G2MessageBox(parent,msg,title='Error'):
26102610 dlg .Destroy ()
26112611
26122612################################################################################
2613+ def findValsInNotebook (data ,target ):
2614+ 'Pull a string of values from saved values in the GSAS-II notebook'
2615+ c = 0
2616+ vals = []
2617+ pos = []
2618+ for l in data :
2619+ if '[REF]' in l : c += 1
2620+ if '[VALS]' in l :
2621+ v = {i .split (' : ' )[0 ].strip () : i .split (' : ' )[1 ]
2622+ for i in l [6 :].split (',' )}
2623+ if target not in v :
2624+ continue
2625+ try :
2626+ vals .append (float (v [target ]))
2627+ pos .append (c )
2628+ except :
2629+ pass
2630+ if '[CEL]' in l :
2631+ ph = l .split ('Phase' )[1 ].split ()[0 ]
2632+ hst = l .split ('Hist' )[1 ].split (':' )[0 ].strip ()
2633+ vars = [i .split ('=' )[0 ] for i in l .split (':' )[1 ].split ()]
2634+ vars = [f'{ v } [p{ ph } _h{ hst } ]' for v in vars ]
2635+ if target not in vars : continue
2636+ values = [i .split ('=' )[1 ].split ('(' )[0 ] for i in l .split (':' )[1 ].split ()]
2637+ try :
2638+ vals .append (float (dict (zip (vars ,values ))[target ]))
2639+ pos .append (c )
2640+ except :
2641+ pass
2642+ return pos ,vals
2643+
26132644def G2AfterFit (parent ,msg ,title = 'Error' ,vartbl = [],txtwidth = 300 ):
26142645 '''Shows the results from a refinement
26152646
26162647 :param wx.Frame parent: pointer to parent of window, usually G2frame
26172648 :param str msg: text from refinement results
26182649 :param str title: text to label window
26192650 :param list vartbl: a list of lists. The contents of each inner list
2620- item will be [var-name, val-before, val-after, meaning]
2651+ item will be [var-name, val-before, val-after, sigma, meaning]
26212652 :param int txtwidth: width (in pixesl) to display msg. Defaults to 300
26222653 '''
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 )
2654+ def OnRowSelected (event ):
2655+ '''plot the parameter results if it has been recorded
2656+ this is called when one clicks on a row in the parameter table
2657+ '''
2658+ row = event .GetIndex ()
2659+ var = results .list .GetItemText (row )
2660+ val = valDict .get (var )
2661+ G2frame = wx .App .GetMainTopWindow ()
2662+ G2frame .G2plotNB .Delete ('fit results' )
2663+ if val is None : return
2664+ nId = G2gd .GetGPXtreeItemId (G2frame ,G2frame .root , 'Notebook' )
2665+ if not nId : return
2666+ Notebook = G2frame .GPXtree .GetItemPyData (nId )
2667+ pos ,vals = findValsInNotebook (Notebook ,var )
2668+ if len (pos ) < 2 : return
2669+ pos .append (pos [- 1 ]+ 1 )
2670+ try :
2671+ vals .append (float (val ))
2672+ except :
2673+ return
2674+ XY = [np .array (pos ),np .array (vals )]
2675+ from . import GSASIIplot as G2plt
2676+ G2plt .PlotXY (G2frame ,[XY ,],Title = 'fit results' ,newPlot = True ,
2677+ labelX = 'seq' ,labelY = var ,lines = True )
2678+ # create table to show from input
2679+ displayTable = []
2680+ valDict = {}
2681+ for (var ,before ,after ,sig ,what ) in vartbl :
2682+ valDict [var ] = after # save lookup table of values
2683+ try :
2684+ d = f'{ (after - before )/ sig :.3g} '
2685+ b = G2mth .ValEsd (before ,- abs (sig )/ 10 ,True )
2686+ a = G2mth .ValEsd (after ,- abs (sig )/ 10 ,True )
2687+ except :
2688+ d = '0'
2689+ b = f'{ before :.6g} '
2690+ a = f'{ after :.6g} '
2691+ displayTable .append ((var ,b ,a ,d ,what ))
2692+ labels = ('var' ,'before' ,'after' ,'del/sig' ,'parameter description' )
2693+ just = (0 , 1 , 1 , 1 , 0 ) # 0 left, 1 right
26322694 dlg = wx .Dialog (parent .GetTopLevelParent (), wx .ID_ANY , title ,
26332695 style = wx .DEFAULT_DIALOG_STYLE | wx .RESIZE_BORDER )
26342696 mainSizer = wx .BoxSizer (wx .VERTICAL )
2635-
26362697 txtSizer = wx .BoxSizer (wx .HORIZONTAL )
26372698 txt = wx .StaticText (dlg ,wx .ID_ANY ,msg )
26382699 txt .Wrap (txtwidth - 20 )
@@ -2652,14 +2713,16 @@ def G2AfterFit(parent,msg,title='Error',vartbl=[],txtwidth=300):
26522713 results .SetInitialSortColumn (3 ,False )
26532714 results .SetClientSize ((450 ,250 ))
26542715 results .SetMinSize ((450 ,250 ))
2716+ results .Bind (wx .EVT_LIST_ITEM_SELECTED , OnRowSelected ) # plot
26552717 else :
26562718 results = wx .BoxSizer (wx .VERTICAL )
26572719 results .Add ((- 1 ,- 1 ),1 ,wx .EXPAND )
2658- results .Add (wx .StaticText (dlg ,wx .ID_ANY ,' (no parameter changes\n to display) ' ,size = (350 ,- 1 ),style = wx .ALIGN_CENTER ))
2720+ results .Add (wx .StaticText (dlg ,wx .ID_ANY ,
2721+ ' (no parameter changes\n to display) ' ,
2722+ size = (350 ,- 1 ),style = wx .ALIGN_CENTER ))
26592723 results .Add ((- 1 ,- 1 ),1 ,wx .EXPAND )
26602724 txtSizer .Add (results ,1 ,wx .EXPAND ,0 )
26612725 mainSizer .Add (txtSizer ,1 ,wx .EXPAND )
2662-
26632726 mainSizer .Add ((- 1 ,5 ))
26642727 txt = wx .StaticText (dlg ,wx .ID_ANY ,'Load new result?' )
26652728 mainSizer .Add (txt ,0 ,wx .CENTER )
@@ -2680,8 +2743,6 @@ def G2AfterFit(parent,msg,title='Error',vartbl=[],txtwidth=300):
26802743 ans = dlg .ShowModal ()
26812744 dlg .Destroy ()
26822745 return ans
2683- #ans = dlg.Show()
2684- #breakpoint()
26852746
26862747def ShowScrolledInfo (parent ,txt ,width = 600 ,height = 400 ,header = 'Warning info' ,
26872748 buttonlist = None ):
@@ -7786,57 +7847,13 @@ def SetColWidth(self,col,width=None,auto=True,minwidth=0,maxwidth=None,
77867847 def SetInitialSortColumn (self , col , ascending = True ):
77877848 '''Sets the initial column to be used for sorting when the table is first displayed.
77887849 This method should be called after all PopulateLine calls are complete.
7850+ The up or down arrow indicator will be displayed on the specified column.
77897851
77907852 :param int col: the column index (0-based) to sort by initially
77917853 :param bool ascending: if True (default), sort in ascending order; if False, descending
77927854 '''
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 )
7855+ # Use SortListItems to both sort the items and display the sort indicator arrow
7856+ self .list .SortListItems (col , ascending )
78407857
78417858try :
78427859 class G2LstCtrl (wx .ListCtrl , listmix .ListCtrlAutoWidthMixin , listmix .ColumnSorterMixin ):
@@ -7867,10 +7884,10 @@ def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,
78677884 def GetListCtrl (self ): # needed for sorting
78687885 return self
78697886 def GetSortImages (self ):
7870- #return (self.parent.DownArrow, self.parent.UpArrow)
78717887 return (self .DownArrow , self .UpArrow )
78727888 def GetColumnSorter (self ):
7873- """Custom sorter that handles absolute numerical values for columns 1, 2, 3 (2nd, 3rd, 4th columns)"""
7889+ """Custom sorter that handles absolute numerical values for columns 1, 2,
7890+ and 3 (2nd, 3rd, 4th columns)"""
78747891 def compare_func (key1 , key2 ):
78757892 col = self .GetSortState ()[0 ]
78767893 ascending = self .GetSortState ()[1 ]
0 commit comments