1 | #!/usr/bin/env python |
---|
2 | # -*- coding: utf-8 -*- |
---|
3 | #GSAS-II Data/Model Comparison |
---|
4 | ########### SVN repository information ################### |
---|
5 | # $Date: 2021-02-06 04:14:23 +0000 (Sat, 06 Feb 2021) $ |
---|
6 | # $Author: toby $ |
---|
7 | # $Revision: 4801 $ |
---|
8 | # $URL: trunk/G2compare.py $ |
---|
9 | # $Id: G2compare.py 4801 2021-02-06 04:14:23Z toby $ |
---|
10 | ########### SVN repository information ################### |
---|
11 | ''' |
---|
12 | .. _G2compare: |
---|
13 | |
---|
14 | *G2compare: Tool for project comparison* |
---|
15 | --------------------------------------------- |
---|
16 | ''' |
---|
17 | |
---|
18 | #TODO: |
---|
19 | # Prince-test next |
---|
20 | # Make Phase unique? (need a phaselist) |
---|
21 | # more graphics |
---|
22 | # display more in datawindow |
---|
23 | |
---|
24 | import sys |
---|
25 | import os |
---|
26 | import platform |
---|
27 | import glob |
---|
28 | if '2' in platform.python_version_tuple()[0]: |
---|
29 | import cPickle |
---|
30 | else: |
---|
31 | try: |
---|
32 | import _pickle as cPickle |
---|
33 | except: |
---|
34 | print('Warning: failed to import the optimized Py3 pickle (_pickle)') |
---|
35 | import pickle as cPickle |
---|
36 | |
---|
37 | import wx |
---|
38 | import numpy as np |
---|
39 | import matplotlib as mpl |
---|
40 | try: |
---|
41 | import OpenGL as ogl |
---|
42 | except ImportError: |
---|
43 | pass |
---|
44 | import scipy as sp |
---|
45 | |
---|
46 | import GSASIIpath |
---|
47 | GSASIIpath.SetVersionNumber("$Revision: 4801 $") |
---|
48 | import GSASIIfiles as G2fil |
---|
49 | import GSASIIplot as G2plt |
---|
50 | import GSASIIdataGUI as G2gd |
---|
51 | import GSASIIctrlGUI as G2G |
---|
52 | import GSASIIobj as G2obj |
---|
53 | |
---|
54 | __version__ = '0.0.1' |
---|
55 | |
---|
56 | # math to do F-test |
---|
57 | def RC2Ftest(npts,RChiSq0,nvar0,RChiSq1,nvar1): |
---|
58 | '''Compute the F-test probability that a model expanded with added |
---|
59 | parameters (relaxed model) is statistically more likely than the |
---|
60 | constrained (base) model |
---|
61 | :param int npts: number of observed diffraction data points |
---|
62 | :param float RChiSq0: Reduced Chi**2 for the base model |
---|
63 | :param int nvar0: number of refined variables in the base model |
---|
64 | :param float RChiSq0: Reduced Chi**2 for the relaxed model |
---|
65 | :param int nvar1: number of refined variables in the relaxed model |
---|
66 | ''' |
---|
67 | if nvar1 == nvar0: |
---|
68 | raise Exception("parameter # agree, test is not valid") |
---|
69 | elif nvar1 < nvar0: |
---|
70 | print("Warning: RwFtest used with base/relaxed models reversed") |
---|
71 | RChiSq0,nvar0,RChiSq1,nvar1 = RChiSq1,nvar1,RChiSq0,nvar0 |
---|
72 | ratio = RChiSq0 / RChiSq1 |
---|
73 | nu1 = float(nvar1 - nvar0) |
---|
74 | nu2 = float(npts - nvar1) |
---|
75 | F = (ratio - 1.) * nu2 / nu1 |
---|
76 | import scipy.stats |
---|
77 | return scipy.stats.f.cdf(F,nu1,nu2) |
---|
78 | |
---|
79 | def RwFtest(npts,Rwp0,nvar0,Rwp1,nvar1): |
---|
80 | '''Compute the F-test probability that a model expanded with added |
---|
81 | parameters (relaxed model) is statistically more likely than the |
---|
82 | constrained (base) model |
---|
83 | :param int npts: number of observed diffraction data points |
---|
84 | :param float Rwp0: Weighted profile R-factor or GOF for the base model |
---|
85 | :param int nvar0: number of refined variables in the base model |
---|
86 | :param float Rwp1: Weighted profile R-factor or GOF for the relaxed model |
---|
87 | :param int nvar1: number of refined variables in the relaxed model |
---|
88 | ''' |
---|
89 | if nvar1 == nvar0: |
---|
90 | raise Exception("parameter # agree, test is not valid") |
---|
91 | elif nvar1 < nvar0: |
---|
92 | print("Warning: RwFtest used with base/relaxed models reversed") |
---|
93 | Rwp0,nvar0,Rwp1,nvar1 = Rwp1,nvar1,Rwp0,nvar0 |
---|
94 | ratio = (Rwp0 / Rwp1)**2 |
---|
95 | nu1 = float(nvar1 - nvar0) |
---|
96 | nu2 = float(npts - nvar1) |
---|
97 | F = (ratio - 1.) * nu2 / nu1 |
---|
98 | import scipy.stats |
---|
99 | return scipy.stats.f.cdf(F,nu1,nu2) |
---|
100 | |
---|
101 | def cPickleLoad(fp): |
---|
102 | if '2' in platform.python_version_tuple()[0]: |
---|
103 | return cPickle.load(fp) |
---|
104 | else: |
---|
105 | return cPickle.load(fp,encoding='latin-1') |
---|
106 | |
---|
107 | def main(application): |
---|
108 | '''Start up the GSAS-II GUI''' |
---|
109 | knownVersions = ['3.6','3.7','3.8','3.9'] |
---|
110 | if platform.python_version()[:3] not in knownVersions: |
---|
111 | dlg = wx.MessageDialog(None, |
---|
112 | 'GSAS-II requires Python 3.6+\n Yours is '+sys.version.split()[0], |
---|
113 | 'Python version error', wx.OK) |
---|
114 | try: |
---|
115 | dlg.ShowModal() |
---|
116 | finally: |
---|
117 | dlg.Destroy() |
---|
118 | sys.exit() |
---|
119 | |
---|
120 | application.main = MakeTopWindow(None) # application.main is the main wx.Frame |
---|
121 | application.SetTopWindow(application.main) |
---|
122 | # save the current package versions |
---|
123 | application.main.PackageVersions = G2fil.get_python_versions([wx, mpl, np, sp, ogl]) |
---|
124 | try: |
---|
125 | application.SetAppDisplayName('GSAS-II Compare') |
---|
126 | except: |
---|
127 | pass |
---|
128 | #application.GetTopWindow().SendSizeEvent() |
---|
129 | application.GetTopWindow().Show(True) |
---|
130 | return application.GetTopWindow() |
---|
131 | |
---|
132 | class MakeTopWindow(wx.Frame): |
---|
133 | '''Define the main frame and its associated menu items |
---|
134 | ''' |
---|
135 | def __init__(self, parent): |
---|
136 | size = wx.Size(700,450) |
---|
137 | wx.Frame.__init__(self, name='dComp', parent=parent, |
---|
138 | size=size,style=wx.DEFAULT_FRAME_STYLE, title='GSAS-II data/model comparison') |
---|
139 | # misc vars |
---|
140 | self.VcovColor = 'RdYlGn' |
---|
141 | # plot window |
---|
142 | try: |
---|
143 | size = GSASIIpath.GetConfigValue('Plot_Size') |
---|
144 | if type(size) is tuple: |
---|
145 | pass |
---|
146 | elif type(size) is str: |
---|
147 | size = eval(size) |
---|
148 | else: |
---|
149 | raise Exception |
---|
150 | except: |
---|
151 | size = wx.Size(700,600) |
---|
152 | self.plotFrame = wx.Frame(None,-1,'dComp Plots',size=size, |
---|
153 | style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX) |
---|
154 | self.G2plotNB = G2plt.G2PlotNoteBook(self.plotFrame,G2frame=self) |
---|
155 | #self.plotFrame.Show() |
---|
156 | self.plotFrame.Show(False) # until we have some graphics, hide the plot window |
---|
157 | # menus |
---|
158 | Frame = self.GetTopLevelParent() # same as self |
---|
159 | self.MenuBar = wx.MenuBar() |
---|
160 | File = wx.Menu(title='') |
---|
161 | self.MenuBar.Append(menu=File, title='&File') |
---|
162 | item = File.Append(wx.ID_ANY,'&Import single project...\tCtrl+O','Open a GSAS-II project file (*.gpx)') |
---|
163 | self.Bind(wx.EVT_MENU, self.onLoadGPX, id=item.GetId()) |
---|
164 | item = File.Append(wx.ID_ANY,'&Import multiple projects...\tCtrl+U','Open a GSAS-II project file (*.gpx)') |
---|
165 | self.Bind(wx.EVT_MENU, self.onLoadMultGPX, id=item.GetId()) |
---|
166 | item = File.Append(wx.ID_ANY,'&Wildcard import of projects...\tCtrl+W','Open a GSAS-II project file (*.gpx)') |
---|
167 | self.Bind(wx.EVT_MENU, self.onLoadWildGPX, id=item.GetId()) |
---|
168 | # item = File.Append(wx.ID_ANY,'&Import selected...','Open a GSAS-II project file (*.gpx)') |
---|
169 | # self.Bind(wx.EVT_MENU, self.onLoadSel, id=item.GetId()) |
---|
170 | |
---|
171 | self.Mode = wx.Menu(title='') |
---|
172 | self.MenuBar.Append(menu=self.Mode, title='&Mode') |
---|
173 | self.wxID_Mode = {} |
---|
174 | for i,m in enumerate(("Histogram","Phase","Project")): |
---|
175 | self.wxID_Mode[m] = i+1 |
---|
176 | item = self.Mode.AppendRadioItem(i+1,m+'\tCtrl+{}'.format(i+1), |
---|
177 | 'Display {}s'.format(m)) |
---|
178 | self.Bind(wx.EVT_MENU, self.onRefresh, id=item.GetId()) |
---|
179 | self.hFilter = self.Mode.Append(wx.ID_ANY,'Filter by histogram\tCtrl+F','Only show selected histograms') |
---|
180 | self.Bind(wx.EVT_MENU, self.onHistFilter, id=self.hFilter.GetId()) |
---|
181 | modeMenu = wx.Menu(title='') |
---|
182 | self.MenuBar.Append(menu=modeMenu, title='TBD') |
---|
183 | self.modeMenuPos = self.MenuBar.FindMenu('TBD') |
---|
184 | |
---|
185 | Frame.SetMenuBar(self.MenuBar) |
---|
186 | # status bar |
---|
187 | self.Status = self.CreateStatusBar() |
---|
188 | self.Status.SetFieldsCount(2) |
---|
189 | # split the frame and add the tree |
---|
190 | self.mainPanel = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_LIVE_UPDATE|wx.SP_3D) |
---|
191 | self.mainPanel.SetMinimumPaneSize(100) |
---|
192 | self.treePanel = wx.Panel(self.mainPanel, wx.ID_ANY, |
---|
193 | style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER) |
---|
194 | |
---|
195 | # self.dataWindow = G2DataWindow(self.mainPanel) |
---|
196 | self.dataWindow = wx.ScrolledWindow(self.mainPanel) |
---|
197 | dataSizer = wx.BoxSizer(wx.VERTICAL) |
---|
198 | self.dataWindow.SetSizer(dataSizer) |
---|
199 | self.mainPanel.SplitVertically(self.treePanel, self.dataWindow, 200) |
---|
200 | self.Status.SetStatusWidths([200,-1]) # make these match? |
---|
201 | |
---|
202 | treeSizer = wx.BoxSizer(wx.VERTICAL) |
---|
203 | self.treePanel.SetSizer(treeSizer) |
---|
204 | self.GPXtree = G2G.G2TreeCtrl(id=wx.ID_ANY, |
---|
205 | parent=self.treePanel, size=self.treePanel.GetClientSize(),style=wx.TR_DEFAULT_STYLE ) |
---|
206 | #TreeId = self.GPXtree.Id |
---|
207 | |
---|
208 | treeSizer.Add(self.GPXtree,1,wx.EXPAND|wx.ALL,0) |
---|
209 | #self.GPXtree.Bind(wx.EVT_TREE_SEL_CHANGED,self.OnDataTreeSelChanged) |
---|
210 | self.GPXtree.Bind(wx.EVT_TREE_SEL_CHANGED,self.OnDataTreeSelChanged) |
---|
211 | # self.GPXtree.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK,self.OnDataTreeSelChanged) |
---|
212 | # self.GPXtree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, |
---|
213 | # self.OnGPXtreeItemCollapsed, id=TreeId) |
---|
214 | #self.GPXtree.Bind(wx.EVT_TREE_ITEM_EXPANDED, |
---|
215 | # self.OnGPXtreeItemExpanded, id=TreeId) |
---|
216 | # self.GPXtree.Bind(wx.EVT_TREE_DELETE_ITEM, |
---|
217 | # self.OnGPXtreeItemDelete, id=TreeId) |
---|
218 | # self.GPXtree.Bind(wx.EVT_TREE_KEY_DOWN, |
---|
219 | # self.OnGPXtreeKeyDown, id=TreeId) |
---|
220 | # self.GPXtree.Bind(wx.EVT_TREE_BEGIN_RDRAG, |
---|
221 | # self.OnGPXtreeBeginRDrag, id=TreeId) |
---|
222 | # self.GPXtree.Bind(wx.EVT_TREE_END_DRAG, |
---|
223 | # self.OnGPXtreeEndDrag, id=TreeId) |
---|
224 | self.root = self.GPXtree.root |
---|
225 | self.Bind(wx.EVT_CLOSE, lambda event: sys.exit()) |
---|
226 | |
---|
227 | self.fileList = [] # list of files read for use in Reload |
---|
228 | self.histListOrg = [] # list of histograms, before mods for unique naming |
---|
229 | self.histList = [] # list of histograms, after mods for unique naming |
---|
230 | self.projList = [] |
---|
231 | |
---|
232 | self.PWDRfilter = None |
---|
233 | for win,var in ((self.plotFrame,'Plot_Pos'),): |
---|
234 | #for win,var in ((self,'Main_Pos'),(self.plotFrame,'Plot_Pos')): |
---|
235 | try: |
---|
236 | pos = GSASIIpath.GetConfigValue(var) |
---|
237 | if type(pos) is str: pos = eval(pos) |
---|
238 | win.SetPosition(pos) |
---|
239 | if G2gd.GetDisplay(pos) is None: win.Center() |
---|
240 | except: |
---|
241 | if GSASIIpath.GetConfigValue(var): |
---|
242 | print('Value for config {} {} is invalid'.format(var,GSASIIpath.GetConfigValue(var))) |
---|
243 | win.Center() |
---|
244 | self.SetModeMenu() |
---|
245 | |
---|
246 | def SelectGPX(self): |
---|
247 | '''Select a .GPX file to be read |
---|
248 | ''' |
---|
249 | dlg = wx.FileDialog(self, 'Choose GSAS-II project file', |
---|
250 | wildcard='GSAS-II project file (*.gpx)|*.gpx',style=wx.FD_OPEN) |
---|
251 | try: |
---|
252 | if dlg.ShowModal() != wx.ID_OK: return |
---|
253 | fil = os.path.splitext(dlg.GetPath())[0]+'.gpx' |
---|
254 | finally: |
---|
255 | dlg.Destroy() |
---|
256 | if os.path.exists(fil): |
---|
257 | #self.fileList.append([fil,'GPX']) |
---|
258 | return fil |
---|
259 | else: |
---|
260 | print('File {} not found, skipping'.format(fil)) |
---|
261 | return |
---|
262 | |
---|
263 | def SelectMultGPX(self): |
---|
264 | '''Select multiple .GPX files to be read |
---|
265 | ''' |
---|
266 | dlg = wx.FileDialog(self, 'Choose GSAS-II project file', |
---|
267 | wildcard='GSAS-II project file (*.gpx)|*.gpx', |
---|
268 | style=wx.FD_OPEN|wx.FD_MULTIPLE) |
---|
269 | try: |
---|
270 | if dlg.ShowModal() != wx.ID_OK: return |
---|
271 | files = dlg.GetPaths() |
---|
272 | finally: |
---|
273 | dlg.Destroy() |
---|
274 | fileList = [] |
---|
275 | for f in files: |
---|
276 | fil = os.path.splitext(f)[0]+'.gpx' |
---|
277 | if os.path.exists(fil): |
---|
278 | if fil not in fileList: |
---|
279 | fileList.append(fil) |
---|
280 | else: |
---|
281 | print('File {} not found, skipping'.format(fil)) |
---|
282 | return fileList |
---|
283 | |
---|
284 | def getMode(self): |
---|
285 | '''returns the display mode (one of "Histogram","Phase","Project"). |
---|
286 | Could return '?' in case of an error. |
---|
287 | ''' |
---|
288 | for m in self.wxID_Mode: |
---|
289 | if self.Mode.FindItemById(self.wxID_Mode[m]).IsChecked(): |
---|
290 | break |
---|
291 | else: |
---|
292 | m = '?' |
---|
293 | return m |
---|
294 | |
---|
295 | def onRefresh(self,event): |
---|
296 | '''reread all files, in response to a change in mode, etc. |
---|
297 | ''' |
---|
298 | self.GPXtree.DeleteChildren(self.root) # delete tree contents |
---|
299 | self.histList = [] # clear list of loaded histograms |
---|
300 | self.histListOrg = [] |
---|
301 | self.projList = [] |
---|
302 | self.hFilter.Enable(not self.getMode() == "Phase") # Filter disabled for Phase display |
---|
303 | for fil,mode in self.fileList: |
---|
304 | self.loadFile(fil) |
---|
305 | self.doneLoad() |
---|
306 | self.SetModeMenu() |
---|
307 | |
---|
308 | def SetModeMenu(self): |
---|
309 | '''Create the mode-specific menu and its contents |
---|
310 | ''' |
---|
311 | modeMenu = wx.Menu(title='') |
---|
312 | oldmenu = self.MenuBar.Replace(self.modeMenuPos,modeMenu,self.getMode()) |
---|
313 | wx.CallAfter(oldmenu.Destroy) |
---|
314 | if self.getMode() == "Histogram": |
---|
315 | item = modeMenu.Append(wx.ID_ANY,'Prince test') |
---|
316 | self.Bind(wx.EVT_MENU, self.onHistPrinceTest, id=item.GetId()) |
---|
317 | elif self.getMode() == "Phase": |
---|
318 | pass |
---|
319 | elif self.getMode() == "Project": |
---|
320 | item = modeMenu.Append(wx.ID_ANY,'F-test') |
---|
321 | self.Bind(wx.EVT_MENU, self.onProjFtest, id=item.GetId()) |
---|
322 | |
---|
323 | def loadFile(self,fil): |
---|
324 | '''read or reread a file |
---|
325 | ''' |
---|
326 | if self.getMode() == "Histogram": |
---|
327 | self.LoadPwdr(fil) |
---|
328 | elif self.getMode() == "Phase": |
---|
329 | self.LoadPhase(fil) |
---|
330 | elif self.getMode() == "Project": |
---|
331 | self.LoadProject(fil) |
---|
332 | else: |
---|
333 | print("mode not implemented") |
---|
334 | #raise Exception("mode not implemented") |
---|
335 | |
---|
336 | def doneLoad(self): |
---|
337 | self.GPXtree.Expand(self.root) |
---|
338 | if self.getMode() == "Project": |
---|
339 | overId = self.GPXtree.InsertItem(pos=0,parent=self.root,text='Project Overview') |
---|
340 | self.GPXtree.SelectItem(overId) |
---|
341 | |
---|
342 | def onLoadGPX(self,event): |
---|
343 | '''Initial load of GPX file in response to a menu command |
---|
344 | ''' |
---|
345 | fil = self.SelectGPX() |
---|
346 | if not fil: return |
---|
347 | if not os.path.exists(fil): return |
---|
348 | self.fileList.append([fil,'GPX']) |
---|
349 | self.loadFile(fil) |
---|
350 | self.doneLoad() |
---|
351 | |
---|
352 | def onLoadMultGPX(self,event): |
---|
353 | '''Initial load of multiple GPX files in response to a menu command |
---|
354 | ''' |
---|
355 | for fil in self.SelectMultGPX(): |
---|
356 | if not os.path.exists(fil): continue |
---|
357 | self.fileList.append([fil,'GPX']) |
---|
358 | self.loadFile(fil) |
---|
359 | self.doneLoad() |
---|
360 | |
---|
361 | def onLoadWildGPX(self,event,wildcard=None): |
---|
362 | '''Initial load of GPX file in response to a menu command |
---|
363 | ''' |
---|
364 | home = os.path.abspath(os.getcwd()) |
---|
365 | hlp = '''Enter a wildcard version of a file name. |
---|
366 | The directory is assumed to be "{}" unless specified otherwise. |
---|
367 | Extensions will be set to .gpx and .bak files will be ignored unless |
---|
368 | the wildcard string includes "bak". For example, "*abc*" will match any |
---|
369 | .gpx file in that directory containing "abc". String "/tmp/A*" will match |
---|
370 | files in "/tmp" beginning with "A". Supplying two strings, "A*" and "B*bak*" |
---|
371 | will match files names beginning with "A" or "B", but ".bak" files will |
---|
372 | be included for the files beginning with "B" only. |
---|
373 | '''.format(home) |
---|
374 | if wildcard is None: |
---|
375 | dlg = G2G.MultiStringDialog(self, 'Enter wildcard file names', |
---|
376 | ['wild-card 1'] , values=['*'], |
---|
377 | lbl='Provide string(s) with "*" to find matching files', |
---|
378 | addRows=True, hlp=hlp) |
---|
379 | res = dlg.Show() |
---|
380 | wl = dlg.GetValues() |
---|
381 | dlg.Destroy() |
---|
382 | if not res: return |
---|
383 | else: |
---|
384 | wl = [wildcard] |
---|
385 | for w in wl: |
---|
386 | if not os.path.split(w)[0]: |
---|
387 | w = os.path.join(home,w) |
---|
388 | w = os.path.splitext(w)[0] + '.gpx' |
---|
389 | for fil in glob.glob(w): |
---|
390 | if not os.path.exists(fil): continue |
---|
391 | if '.bak' in fil and 'bak' not in w: continue |
---|
392 | if fil in [i for i,j in self.fileList]: continue |
---|
393 | self.fileList.append([fil,'GPX']) |
---|
394 | self.loadFile(fil) |
---|
395 | self.doneLoad() |
---|
396 | |
---|
397 | def LoadPwdr(self,fil): |
---|
398 | '''Load PWDR entries from a .GPX file to the tree. |
---|
399 | see :func:`GSASIIIO.ProjFileOpen` |
---|
400 | ''' |
---|
401 | G2frame = self |
---|
402 | filep = open(fil,'rb') |
---|
403 | shortname = os.path.splitext(os.path.split(fil)[1])[0] |
---|
404 | |
---|
405 | wx.BeginBusyCursor() |
---|
406 | histLoadList = [] |
---|
407 | try: |
---|
408 | while True: |
---|
409 | try: |
---|
410 | data = cPickleLoad(filep) |
---|
411 | except EOFError: |
---|
412 | break |
---|
413 | if not data[0][0].startswith('PWDR'): continue |
---|
414 | self.histListOrg.append(data[0][0]) |
---|
415 | if self.PWDRfilter is not None: # implement filter |
---|
416 | if self.PWDRfilter not in data[0][0]: continue |
---|
417 | data[0][0] += ' (' |
---|
418 | data[0][0] += shortname |
---|
419 | data[0][0] += ')' |
---|
420 | histLoadList.append(data) |
---|
421 | |
---|
422 | except Exception as errmsg: |
---|
423 | if GSASIIpath.GetConfigValue('debug'): |
---|
424 | print('\nError reading GPX file:',errmsg) |
---|
425 | import traceback |
---|
426 | print (traceback.format_exc()) |
---|
427 | msg = wx.MessageDialog(G2frame,message="Error reading file "+ |
---|
428 | str(fil)+". This is not a current GSAS-II .gpx file", |
---|
429 | caption="Load Error",style=wx.ICON_ERROR | wx.OK | wx.STAY_ON_TOP) |
---|
430 | msg.ShowModal() |
---|
431 | finally: |
---|
432 | filep.close() |
---|
433 | wx.EndBusyCursor() |
---|
434 | |
---|
435 | datum = None |
---|
436 | for i,data in enumerate(histLoadList): |
---|
437 | datum = data[0] |
---|
438 | datum[0] = G2obj.MakeUniqueLabel(datum[0],self.histList) |
---|
439 | Id = G2frame.GPXtree.AppendItem(parent=G2frame.root,text=datum[0]) |
---|
440 | self.histList.append(datum[0]) |
---|
441 | # if 'ranId' not in datum[1][0]: # patch: add random Id if not present |
---|
442 | # datum[1][0]['ranId'] = ran.randint(0,sys.maxsize) |
---|
443 | G2frame.GPXtree.SetItemPyData(Id,datum[1][:3]) #temp. trim off junk (patch?) |
---|
444 | for datus in data[1:]: |
---|
445 | sub = G2frame.GPXtree.AppendItem(Id,datus[0]) |
---|
446 | #patch |
---|
447 | if datus[0] == 'Instrument Parameters' and len(datus[1]) == 1: |
---|
448 | if datum[0].startswith('PWDR'): |
---|
449 | datus[1] = [dict(zip(datus[1][3],zip(datus[1][0],datus[1][1],datus[1][2]))),{}] |
---|
450 | else: |
---|
451 | datus[1] = [dict(zip(datus[1][2],zip(datus[1][0],datus[1][1]))),{}] |
---|
452 | for item in datus[1][0]: #zip makes tuples - now make lists! |
---|
453 | datus[1][0][item] = list(datus[1][0][item]) |
---|
454 | #end patch |
---|
455 | G2frame.GPXtree.SetItemPyData(sub,datus[1]) |
---|
456 | if datum: # was anything loaded? |
---|
457 | print('data load successful for {}'.format(datum[0])) |
---|
458 | # G2frame.Status.SetStatusText('Mouse RB drag/drop to reorder',0) |
---|
459 | # G2frame.SetTitleByGPX() |
---|
460 | self.GPXtree.Expand(self.root) |
---|
461 | |
---|
462 | def onHistFilter(self,event): |
---|
463 | 'Load a filter string via a dialog in response to a menu event' |
---|
464 | defval = '' |
---|
465 | if self.PWDRfilter is not None: |
---|
466 | defval = self.PWDRfilter |
---|
467 | uniqueHist = sorted(set(self.histListOrg)) |
---|
468 | dlg = G2G.SingleStringDialog(self,'Set string', |
---|
469 | 'Set a string that must be in histogram name', |
---|
470 | defval, choices=uniqueHist, size=(400,-1)) |
---|
471 | if dlg.Show(): |
---|
472 | if dlg.GetValue().strip() == '': |
---|
473 | self.PWDRfilter = None |
---|
474 | else: |
---|
475 | self.PWDRfilter = dlg.GetValue() |
---|
476 | dlg.Destroy() |
---|
477 | self.onRefresh(event) |
---|
478 | else: |
---|
479 | dlg.Destroy() |
---|
480 | |
---|
481 | def LoadPhase(self,fil): |
---|
482 | '''Load Phase entries from a .GPX file to the tree. |
---|
483 | see :func:`GSASIIIO.ProjFileOpen` |
---|
484 | ''' |
---|
485 | G2frame = self |
---|
486 | filep = open(fil,'rb') |
---|
487 | shortname = os.path.splitext(os.path.split(fil)[1])[0] |
---|
488 | |
---|
489 | wx.BeginBusyCursor() |
---|
490 | Phases = None |
---|
491 | try: |
---|
492 | while True: |
---|
493 | try: |
---|
494 | data = cPickleLoad(filep) |
---|
495 | except EOFError: |
---|
496 | break |
---|
497 | if not data[0][0].startswith('Phase'): continue |
---|
498 | Phases = data |
---|
499 | #if self.PWDRfilter is not None: # implement filter |
---|
500 | # if self.PWDRfilter not in data[0][0]: continue |
---|
501 | data[0][0] += ' (' |
---|
502 | if Phases: |
---|
503 | data[0][0] += shortname |
---|
504 | data[0][0] += ')' |
---|
505 | else: |
---|
506 | data[0][0] += shortname |
---|
507 | data[0][0] += 'has no phases)' |
---|
508 | Phases = data |
---|
509 | break |
---|
510 | |
---|
511 | except Exception as errmsg: |
---|
512 | if GSASIIpath.GetConfigValue('debug'): |
---|
513 | print('\nError reading GPX file:',errmsg) |
---|
514 | import traceback |
---|
515 | print (traceback.format_exc()) |
---|
516 | msg = wx.MessageDialog(G2frame,message="Error reading file "+ |
---|
517 | str(fil)+". This is not a current GSAS-II .gpx file", |
---|
518 | caption="Load Error",style=wx.ICON_ERROR | wx.OK | wx.STAY_ON_TOP) |
---|
519 | msg.ShowModal() |
---|
520 | finally: |
---|
521 | filep.close() |
---|
522 | wx.EndBusyCursor() |
---|
523 | |
---|
524 | datum = None |
---|
525 | if Phases: |
---|
526 | datum = data[0] |
---|
527 | #datum[0] = G2obj.MakeUniqueLabel(datum[0],self.histList) |
---|
528 | Id = G2frame.GPXtree.AppendItem(parent=G2frame.root,text=datum[0]) |
---|
529 | G2frame.GPXtree.SetItemPyData(Id,datum[1]) |
---|
530 | for datus in data[1:]: |
---|
531 | #datus[0] += ' (' |
---|
532 | #datus[0] += shortname |
---|
533 | #datus[0] += ')' |
---|
534 | sub = G2frame.GPXtree.AppendItem(Id,datus[0]) |
---|
535 | G2frame.GPXtree.SetItemPyData(sub,datus[1]) |
---|
536 | if datum: # was anything loaded? |
---|
537 | self.GPXtree.Expand(Id) |
---|
538 | print('Phase load successful for {}'.format(datum[0])) |
---|
539 | # G2frame.Status.SetStatusText('Mouse RB drag/drop to reorder',0) |
---|
540 | # G2frame.SetTitleByGPX() |
---|
541 | self.GPXtree.Expand(self.root) |
---|
542 | |
---|
543 | def LoadProject(self,fil): |
---|
544 | '''Load the Covariance entry from a .GPX file to the tree. |
---|
545 | see :func:`GSASIIIO.ProjFileOpen` |
---|
546 | ''' |
---|
547 | import datetime |
---|
548 | G2frame = self |
---|
549 | filep = open(fil,'rb') |
---|
550 | saved = datetime.datetime.fromtimestamp(os.path.getmtime(fil)).strftime("%Y-%h-%d %H:%M") |
---|
551 | shortname = os.path.splitext(os.path.split(fil)[1])[0] |
---|
552 | projInfo = [shortname,saved] |
---|
553 | wx.BeginBusyCursor() |
---|
554 | #Phases = None |
---|
555 | #G2frame.GPXtree.SetItemPyData(Id,Covar[1]) |
---|
556 | if self.PWDRfilter is None: # implement filter |
---|
557 | match = True |
---|
558 | else: |
---|
559 | match = False |
---|
560 | Covar = None |
---|
561 | try: |
---|
562 | while True: |
---|
563 | try: |
---|
564 | data = cPickleLoad(filep) |
---|
565 | except EOFError: |
---|
566 | break |
---|
567 | if data[0][0].startswith('PWDR'): |
---|
568 | self.histListOrg.append(data[0][0]) |
---|
569 | if self.PWDRfilter is not None: # implement filter |
---|
570 | if self.PWDRfilter in data[0][0]: match = True |
---|
571 | if not data[0][0].startswith('Covariance'): continue |
---|
572 | Covar = data[0] |
---|
573 | f = '{:d}' |
---|
574 | if 'varyList' in data[0][1]: |
---|
575 | projInfo += [f.format(len(data[0][1]['varyList']))] |
---|
576 | else: |
---|
577 | projInfo += ['?'] |
---|
578 | for v in 'Nobs','GOF': |
---|
579 | if 'Rvals' in data[0][1] and v in data[0][1]['Rvals']: |
---|
580 | projInfo += [f.format(data[0][1]['Rvals'][v])] |
---|
581 | else: |
---|
582 | projInfo += ['?'] |
---|
583 | f = '{:6.2f}' |
---|
584 | Covar[0] = shortname # + ' Covariance' |
---|
585 | if match and Covar: |
---|
586 | Id = G2frame.GPXtree.AppendItem(parent=G2frame.root,text=Covar[0]) |
---|
587 | G2frame.GPXtree.SetItemPyData(Id,Covar[1]) |
---|
588 | self.projList.append(projInfo) |
---|
589 | except Exception as errmsg: |
---|
590 | if GSASIIpath.GetConfigValue('debug'): |
---|
591 | print('\nError reading GPX file:',errmsg) |
---|
592 | import traceback |
---|
593 | print (traceback.format_exc()) |
---|
594 | msg = wx.MessageDialog(G2frame,message="Error reading file "+ |
---|
595 | str(fil)+". This is not a current GSAS-II .gpx file", |
---|
596 | caption="Load Error",style=wx.ICON_ERROR | wx.OK | wx.STAY_ON_TOP) |
---|
597 | msg.ShowModal() |
---|
598 | finally: |
---|
599 | filep.close() |
---|
600 | wx.EndBusyCursor() |
---|
601 | |
---|
602 | def OnDataTreeSelChanged(self,event): |
---|
603 | def ClearData(self): |
---|
604 | '''Initializes the contents of the dataWindow panel |
---|
605 | ''' |
---|
606 | self.Unbind(wx.EVT_SIZE) |
---|
607 | self.SetBackgroundColour(wx.Colour(240,240,240)) |
---|
608 | Sizer = self.GetSizer() |
---|
609 | if Sizer: |
---|
610 | try: |
---|
611 | Sizer.Clear(True) |
---|
612 | except: |
---|
613 | pass |
---|
614 | G2frame = self |
---|
615 | item = event.GetItem() |
---|
616 | #print('selected',item) |
---|
617 | lbl = G2frame.GPXtree.GetItemText(item) |
---|
618 | if self.getMode() == "Project" and lbl == 'Project Overview': |
---|
619 | ClearData(G2frame.dataWindow) |
---|
620 | #import imp |
---|
621 | #imp.reload(G2G) |
---|
622 | pnl = G2G.SortableLstCtrl(G2frame.dataWindow) |
---|
623 | h = ["File", "last saved", "vars", "Nobs", "GOF"] |
---|
624 | j = [ 0, 0, 1, 1, 1] |
---|
625 | pnl.PopulateHeader(h,j) |
---|
626 | for i,line in enumerate(self.projList): |
---|
627 | pnl.PopulateLine(i,line) |
---|
628 | G2frame.dataWindow.GetSizer().Add(pnl,1,wx.EXPAND) |
---|
629 | pnl.SetColWidth(0,maxwidth=170) |
---|
630 | for i in range(1,len(h)): |
---|
631 | pnl.SetColWidth(i,minwidth=50) |
---|
632 | G2frame.dataWindow.SendSizeEvent() |
---|
633 | elif self.getMode() == "Project": |
---|
634 | ClearData(G2frame.dataWindow) |
---|
635 | data = G2frame.GPXtree.GetItemPyData(item) |
---|
636 | if data is None: |
---|
637 | self.plotFrame.Show(False) |
---|
638 | return |
---|
639 | text = '' |
---|
640 | if 'Rvals' in data: |
---|
641 | Nvars = len(data['varyList']) |
---|
642 | Rvals = data['Rvals'] |
---|
643 | text = ('Residuals after last refinement:\n'+ |
---|
644 | '\twR = {:.3f}\n\tchi**2 = {:.1f}\n\tGOF = {:.2f}').format( |
---|
645 | Rvals['Rwp'],Rvals['chisq'],Rvals['GOF']) |
---|
646 | text += '\n\tNobs = {}\n\tNvals = {}\n\tSVD zeros = {}'.format( |
---|
647 | Rvals['Nobs'],Nvars,Rvals.get('SVD0',0.)) |
---|
648 | text += '\n\tmax shift/esd = {:.3f}'.format(Rvals.get('Max shft/sig',0.0)) |
---|
649 | if 'lamMax' in Rvals: |
---|
650 | text += '\n\tlog10 MaxLambda = {:.1f}'.format(np.log10(Rvals['lamMax'])) |
---|
651 | text += '\n\tReduced Ï**2 = {:.2f}'.format(Rvals['GOF']**2) |
---|
652 | G2frame.dataWindow.GetSizer().Add( |
---|
653 | wx.StaticText(G2frame.dataWindow,wx.ID_ANY,text) |
---|
654 | ) |
---|
655 | self.plotFrame.Show(True) |
---|
656 | G2plt.PlotCovariance(G2frame,data) |
---|
657 | else: |
---|
658 | self.plotFrame.Show(False) |
---|
659 | ClearData(G2frame.dataWindow) |
---|
660 | |
---|
661 | #print(self.GPXtree._getTreeItemsList(item)) |
---|
662 | # pltNum = self.G2plotNB.nb.GetSelection() |
---|
663 | # print(pltNum) |
---|
664 | # if pltNum >= 0: #to avoid the startup with no plot! |
---|
665 | # self.G2plotNB.nb.GetPage(pltNum) |
---|
666 | # NewPlot = False |
---|
667 | # else: |
---|
668 | # NewPlot = True |
---|
669 | #if self.getMode() == "Histogram": |
---|
670 | #self.PatternId = self.PickId = item |
---|
671 | #G2plt.PlotPatterns(self,plotType='PWDR',newPlot=NewPlot) |
---|
672 | |
---|
673 | # def OnGPXtreeItemExpanded(self,event): |
---|
674 | # item = event.GetItem() |
---|
675 | # print('expanded',item) |
---|
676 | # print(self.GPXtree._getTreeItemsList(item)) |
---|
677 | # if item == self.root: |
---|
678 | # event.StopPropagation() |
---|
679 | # else: |
---|
680 | # event.Skip(False) |
---|
681 | |
---|
682 | def onProjFtest(self,event): |
---|
683 | '''Compare two projects (selected here if more than two are present) |
---|
684 | using the statistical F-test (aka Hamilton R-factor test), see: |
---|
685 | |
---|
686 | * Hamilton, R. W. (1965), Acta Crystallogr. 18, 502-510. |
---|
687 | * Prince, E., Mathematical Techniques in Crystallography and Materials Science, Second ed. (Springer-Verlag, New York, 1994). |
---|
688 | ''' |
---|
689 | items = [] |
---|
690 | item, cookie = self.GPXtree.GetFirstChild(self.root) |
---|
691 | while item: |
---|
692 | items.append(item) |
---|
693 | item, cookie = self.GPXtree.GetNextChild(self.root, cookie) |
---|
694 | if len(items) < 2: |
---|
695 | G2G.G2MessageBox(self,'F-test requires two projects','Need more projects') |
---|
696 | return |
---|
697 | elif len(items) == 2: |
---|
698 | s0 = items[0] |
---|
699 | baseDict = self.GPXtree.GetItemPyData(s0) |
---|
700 | s1 = items[1] |
---|
701 | relxDict = self.GPXtree.GetItemPyData(s1) |
---|
702 | # sort out the dicts in order of number of refined variables |
---|
703 | if len(baseDict['varyList']) > len(relxDict['varyList']): |
---|
704 | s0,s1,baseDict,relxDict = s1,s0,relxDict,baseDict |
---|
705 | else: |
---|
706 | # need to make selection here |
---|
707 | sel = [] |
---|
708 | for i in items: |
---|
709 | sel.append(self.GPXtree.GetItemText(i)) |
---|
710 | dlg = G2G.G2SingleChoiceDialog(self,'Select constrained refinement', |
---|
711 | 'Choose refinement',sel) |
---|
712 | if dlg.ShowModal() == wx.ID_OK: |
---|
713 | s0 = dlg.GetSelection() |
---|
714 | dlg.Destroy() |
---|
715 | else: |
---|
716 | dlg.Destroy() |
---|
717 | return |
---|
718 | inds = list(range(len(items))) |
---|
719 | del sel[s0] |
---|
720 | del inds[s0] |
---|
721 | dlg = G2G.G2SingleChoiceDialog(self,'Select relaxed refinement', |
---|
722 | 'Choose refinement',sel) |
---|
723 | if dlg.ShowModal() == wx.ID_OK: |
---|
724 | s1 = dlg.GetSelection() |
---|
725 | s1 = inds[s1] |
---|
726 | dlg.Destroy() |
---|
727 | else: |
---|
728 | dlg.Destroy() |
---|
729 | return |
---|
730 | baseDict = self.GPXtree.GetItemPyData(items[s0]) |
---|
731 | relxDict = self.GPXtree.GetItemPyData(items[s1]) |
---|
732 | if len(baseDict['varyList']) > len(relxDict['varyList']): |
---|
733 | G2G.G2MessageBox(self, |
---|
734 | 'F-test warning: constrained refinement has more '+ |
---|
735 | 'variables ({}) than relaxed refinement ({}). Swapping' |
---|
736 | .format(len(baseDict['varyList']), len(relxDict['varyList'])), |
---|
737 | 'Fits reversed?') |
---|
738 | s0,s1,baseDict,relxDict = s1,s0,relxDict,baseDict |
---|
739 | baseDict,relxDict = relxDict,baseDict |
---|
740 | if len(baseDict['varyList']) == len(relxDict['varyList']): |
---|
741 | G2G.G2MessageBox(self,'F-test requires differing numbers of variables','F-test not valid') |
---|
742 | return |
---|
743 | elif baseDict['Rvals']['Nobs'] != relxDict['Rvals']['Nobs']: |
---|
744 | G2G.G2MessageBox(self,'F-test requires same number of observations in each refinement','F-test not valid') |
---|
745 | return |
---|
746 | missingVars = [] |
---|
747 | for var in baseDict['varyList']: |
---|
748 | if var not in relxDict['varyList']: |
---|
749 | missingVars.append(var) |
---|
750 | txt = '' |
---|
751 | postmsg = '' |
---|
752 | if missingVars: |
---|
753 | txt = ('*** Possible invalid use of F-test: '+ |
---|
754 | 'The F-test requires that the constrained model be a subset '+ |
---|
755 | 'of the relaxed model. Review the parameters shown below to '+ |
---|
756 | 'confirm missing var(s) have new names in the relaxed model. '+ |
---|
757 | '***\n\n') |
---|
758 | postmsg = ('\n\nThese parameters are in the constrained '+ |
---|
759 | 'fit and are not in the relaxed fit:\n* ') |
---|
760 | for i,var in enumerate(missingVars): |
---|
761 | if i > 0: postmsg += ', ' |
---|
762 | postmsg += var |
---|
763 | postmsg += ('\nThese parameters are in the relaxed fit and not'+ |
---|
764 | ' in the constrained fit:\n* ') |
---|
765 | i = 0 |
---|
766 | for var in relxDict['varyList']: |
---|
767 | if var not in baseDict['varyList']: |
---|
768 | if i > 0: postmsg += ', ' |
---|
769 | i += 1 |
---|
770 | postmsg += var |
---|
771 | #GSASIIpath.IPyBreak_base() |
---|
772 | prob = RwFtest(baseDict['Rvals']['Nobs'], |
---|
773 | baseDict['Rvals']['GOF'],len(baseDict['varyList']), |
---|
774 | relxDict['Rvals']['GOF'],len(relxDict['varyList'])) |
---|
775 | fmt = "{} model is \n* {}\n* {} variables and Reduced Chi**2 = {:.3f}" |
---|
776 | msg = txt |
---|
777 | msg += fmt.format('Constrained',self.GPXtree.GetItemText(s0)[:-11], |
---|
778 | len(baseDict['varyList']), |
---|
779 | baseDict['Rvals']['GOF']**2) |
---|
780 | msg += '\n\n' |
---|
781 | msg += fmt.format('Relaxed',self.GPXtree.GetItemText(s1)[:-11], |
---|
782 | len(relxDict['varyList']), |
---|
783 | relxDict['Rvals']['GOF']**2) |
---|
784 | msg += '\n\nCumulative F-test probability {:.2f}%\n'.format(prob*100) |
---|
785 | if prob > 0.95: |
---|
786 | msg += "The relaxed model is statistically preferred to the constrained model." |
---|
787 | elif prob > 0.75: |
---|
788 | msg += "There is little ability to differentiate between the two models on a statistical basis." |
---|
789 | else: |
---|
790 | msg += "The constrained model is statistically preferred to the relaxed model." |
---|
791 | msg += postmsg |
---|
792 | G2G.G2MessageBox(self,msg,'F-test result') |
---|
793 | |
---|
794 | def onHistPrinceTest(self,event): |
---|
795 | '''Compare two histograms (selected here if more than two are present) |
---|
796 | using the statistical test proposed by Ted Prince in |
---|
797 | Acta Cryst. B35 1099-1100. (1982). Also see Int. Tables Vol. C |
---|
798 | (1st Ed.) chapter 8.4, 618-621 (1995). |
---|
799 | ''' |
---|
800 | items = [] |
---|
801 | item, cookie = self.GPXtree.GetFirstChild(self.root) |
---|
802 | while item: |
---|
803 | items.append(item) |
---|
804 | item, cookie = self.GPXtree.GetNextChild(self.root, cookie) |
---|
805 | |
---|
806 | if len(items) < 2: |
---|
807 | G2G.G2MessageBox(self,'Prince test requires two histograms','Need more') |
---|
808 | return |
---|
809 | elif len(items) == 2: |
---|
810 | s0,s1 = items |
---|
811 | else: |
---|
812 | # need to make selection here |
---|
813 | sel = [] |
---|
814 | for i in items: |
---|
815 | sel.append(self.GPXtree.GetItemText(i)) |
---|
816 | dlg = G2G.G2SingleChoiceDialog(self,'Select one refinement', |
---|
817 | 'Choose refinement',sel) |
---|
818 | if dlg.ShowModal() == wx.ID_OK: |
---|
819 | s0 = dlg.GetSelection() |
---|
820 | dlg.Destroy() |
---|
821 | else: |
---|
822 | dlg.Destroy() |
---|
823 | return |
---|
824 | inds = list(range(len(items))) |
---|
825 | del sel[s0] |
---|
826 | del inds[s0] |
---|
827 | dlg = G2G.G2SingleChoiceDialog(self,'Select comparison refinement', |
---|
828 | 'Choose refinement',sel) |
---|
829 | if dlg.ShowModal() == wx.ID_OK: |
---|
830 | s1 = dlg.GetSelection() |
---|
831 | s1 = inds[s1] |
---|
832 | dlg.Destroy() |
---|
833 | else: |
---|
834 | dlg.Destroy() |
---|
835 | return |
---|
836 | model0 = self.GPXtree.GetItemPyData(s0) |
---|
837 | data0 = model0[1] |
---|
838 | model1 = self.GPXtree.GetItemPyData(s1) |
---|
839 | data1 = model1[1] |
---|
840 | if len(data0[0]) != len(data1[0]): |
---|
841 | G2G.G2MessageBox(self,'Unable to test: differing numbers of data points','Comparison not valid') |
---|
842 | return |
---|
843 | if max(abs((data0[0]-data1[0])/data0[0])) > 0.01: |
---|
844 | G2G.G2MessageBox(self,'Unable to use test: "X" values differ','Comparison not valid') |
---|
845 | return |
---|
846 | # X = data0[3] - data1[3] |
---|
847 | # #Z = np.sqrt(data0[3]) * (data0[1] - (data0[3] + data1[3])/2) |
---|
848 | # X = (data0[3] - data1[3]) / np.sqrt(data0[1]) |
---|
849 | # Z = (data0[1] - (data0[3] + data1[3])/2) / np.sqrt(data0[1]) |
---|
850 | # lam = np.sum(X*Z) / np.sum(X) |
---|
851 | # sig = np.sqrt( |
---|
852 | # (np.sum(Z*Z) - lam*lam*np.sum(X*X)) / |
---|
853 | # ((len(data0[0]) - 1) * np.sum(X*X)) |
---|
854 | # ) |
---|
855 | |
---|
856 | # 0 the x-postions (two-theta in degrees), |
---|
857 | # 1 the intensity values (Yobs), |
---|
858 | # 2 the weights for each Yobs value |
---|
859 | # 3 the computed intensity values (Ycalc) |
---|
860 | # 4 the background values |
---|
861 | # 5 Yobs-Ycalc |
---|
862 | |
---|
863 | GSASIIpath.IPyBreak_base() |
---|
864 | |
---|
865 | #====================================================================== |
---|
866 | if __name__ == '__main__': |
---|
867 | #if sys.platform == "darwin": |
---|
868 | # application = G2App(0) # create the GUI framework |
---|
869 | #else: |
---|
870 | application = wx.App(0) # create the GUI framework |
---|
871 | try: |
---|
872 | GSASIIpath.SetBinaryPath(True) |
---|
873 | except: |
---|
874 | print('Unable to run with current setup, do you want to update to the') |
---|
875 | try: |
---|
876 | # if '2' in platform.python_version_tuple()[0]: |
---|
877 | # ans = raw_input("latest GSAS-II version? Update ([Yes]/no): ") |
---|
878 | # else: |
---|
879 | ans = input("latest GSAS-II version? Update ([Yes]/no): ") |
---|
880 | except: |
---|
881 | ans = 'no' |
---|
882 | if ans.strip().lower() == "no": |
---|
883 | print('Exiting') |
---|
884 | sys.exit() |
---|
885 | print('Updating...') |
---|
886 | GSASIIpath.svnUpdateProcess() |
---|
887 | GSASIIpath.InvokeDebugOpts() |
---|
888 | Frame = main(application) # start the GUI |
---|
889 | loadall = False |
---|
890 | argLoadlist = sys.argv[1:] |
---|
891 | for arg in argLoadlist: |
---|
892 | fil = os.path.splitext(arg)[0] + '.gpx' |
---|
893 | if os.path.exists(fil): |
---|
894 | Frame.fileList.append([fil,'GPX']) |
---|
895 | Frame.loadFile(fil) |
---|
896 | elif '-d' in arg: |
---|
897 | loadall = True |
---|
898 | else: |
---|
899 | print('File {} not found. Skipping'.format(fil)) |
---|
900 | Frame.doneLoad() |
---|
901 | # debug code to select Project in initial mode |
---|
902 | if loadall: |
---|
903 | Frame.onLoadWildGPX(None,wildcard='*') |
---|
904 | Frame.Mode.FindItemById(Frame.wxID_Mode['Project']).Check(True) |
---|
905 | Frame.onRefresh(None) |
---|
906 | |
---|
907 | application.MainLoop() |
---|