source: trunk/GSASII.py @ 167

Last change on this file since 167 was 167, checked in by vondreele, 12 years ago

image fixes for offset detector
drawing/phase fixes

File size: 57.7 KB
Line 
1#GSASII
2
3import os
4import os.path as ospath
5import sys
6import math
7import cPickle
8import time
9import copy
10import numpy as np
11import wx
12import matplotlib as mpl
13
14# load the GSAS routines
15import GSASIIpath
16import GSASIIIO as G2IO
17import GSASIIgrid as G2gd
18import GSASIIplot as G2plt
19import GSASIIpwdGUI as G2pdG
20import GSASIIspc as G2spc
21import GSASIIstruct as G2str
22import OpenGL as ogl
23
24# print versions
25print "Available python module versions for GSASII:"
26print "python:     ",sys.version[:5]
27print "wxpython:   ",wx.__version__
28print "matplotlib: ",mpl.__version__
29print "numpy:      ",np.__version__
30print "OpenGL:     ",ogl.__version__
31
32__version__ = '0.1.5'
33
34# useful degree trig functions
35sind = lambda x: math.sin(x*math.pi/180.)
36cosd = lambda x: math.cos(x*math.pi/180.)
37tand = lambda x: math.tan(x*math.pi/180.)
38asind = lambda x: 180.*math.asin(x)/math.pi
39acosd = lambda x: 180.*math.acos(x)/math.pi
40atan2d = lambda x,y: 180.*math.atan2(y,x)/math.pi
41
42def create(parent):
43    return GSASII(parent)
44
45[wxID_PATTERNTREE, 
46] = [wx.NewId() for _init_ctrls in range(1)]
47
48[wxID_FILECLOSE, wxID_FILEEXIT, wxID_FILEOPEN, 
49 wxID_FILESAVE, wxID_FILESAVEAS, wxID_UNDO, wxID_REFINE, 
50] = [wx.NewId() for _init_coll_File_Items in range(7)]
51
52[wxID_PWDRREAD,wxID_SNGLREAD,wxID_ADDPHASE,wxID_DELETEPHASE,
53 wxID_DATADELETE,wxID_READPEAKS,wxID_PWDSUM,wxID_IMGREAD,
54 wxID_IMSUM, wxID_DATARENAME,
55] = [wx.NewId() for _init_coll_Data_Items in range(10)]
56
57[wxID_IMPORT, wxID_IMPORTPATTERN, wxID_IMPORTHKL, wxID_IMPORTPHASE,
58wxID_IMPORTCIF, wxID_IMPORTPDB, 
59] = [wx.NewId() for _init_coll_Import_Items in range(6)]
60
61[wxID_EXPORT, wxID_EXPORTPATTERN, wxID_EXPORTHKL, wxID_EXPORTPHASE,
62wxID_EXPORTCIF, wxID_EXPORTPEAKLIST
63] = [wx.NewId() for _init_coll_Export_Items in range(6)]
64
65[wxID_HELPABOUT, wxID_HELPHELP, 
66] = [wx.NewId() for _init_coll_Help_Items in range(2)]
67
68class GSASII(wx.Frame):
69   
70    def _init_coll_GSASIIMenu_Menus(self, parent):
71        parent.Append(menu=self.File, title='File')
72        parent.Append(menu=self.Data, title='Data')
73        parent.Append(menu=self.Calculate, title='Calculate')
74        parent.Append(menu=self.Import, title='Import')
75        parent.Append(menu=self.Export, title='Export')
76        parent.Append(menu=self.Help, title='Help')
77
78    def _init_coll_File_Items(self, parent):
79        parent.Append(help='Open a gsasii project file (*.gpx)', id=wxID_FILEOPEN,
80             kind=wx.ITEM_NORMAL,text='Open project...')
81        parent.Append(help='SAve project to old file', id=wxID_FILESAVE, 
82            kind=wx.ITEM_NORMAL,text='Save project')
83        parent.Append(help='Save project to new file', id=wxID_FILESAVEAS, 
84            kind=wx.ITEM_NORMAL,text='Save As...')
85        parent.Append(help='Close project, saving is optional', id=wxID_FILECLOSE, 
86            kind=wx.ITEM_NORMAL,text='Close project')
87        parent.Append(help='Exit from gsasii', id=wxID_FILEEXIT, kind=wx.ITEM_NORMAL,
88            text='Exit')
89        self.Bind(wx.EVT_MENU, self.OnFileOpen, id=wxID_FILEOPEN)
90        self.Bind(wx.EVT_MENU, self.OnFileSave, id=wxID_FILESAVE)
91        self.Bind(wx.EVT_MENU, self.OnFileSaveas, id=wxID_FILESAVEAS)
92        self.Bind(wx.EVT_MENU, self.OnFileClose, id=wxID_FILECLOSE)
93        self.Bind(wx.EVT_MENU, self.OnFileExit, id=wxID_FILEEXIT)
94       
95    def _init_coll_Data_Items(self,parent):
96        parent.Append(help='', id=wxID_PWDRREAD, kind=wx.ITEM_NORMAL,
97            text='Read powder data...')
98        parent.Append(help='',id=wxID_IMGREAD, kind=wx.ITEM_NORMAL,
99            text='Read image data...')
100        parent.Append(help='',id=wxID_READPEAKS, kind=wx.ITEM_NORMAL,
101            text='Read Powder Pattern Peaks...')
102        parent.Append(help='', id=wxID_SNGLREAD, kind=wx.ITEM_NORMAL,
103            text='Read single crystal data...')
104        parent.Append(help='', id=wxID_PWDSUM, kind=wx.ITEM_NORMAL,
105            text='Sum powder data')
106        parent.Append(help='',id=wxID_IMSUM, kind=wx.ITEM_NORMAL,
107            text='Sum image data')
108        parent.Append(help='', id=wxID_ADDPHASE, kind=wx.ITEM_NORMAL,
109            text='Add phase')
110        parent.Append(help='', id=wxID_DELETEPHASE, kind=wx.ITEM_NORMAL,
111            text='Delete phase')
112        parent.Append(help='', id=wxID_DATARENAME, kind=wx.ITEM_NORMAL,
113            text='Rename data') 
114        parent.Append(help='', id=wxID_DATADELETE, kind=wx.ITEM_NORMAL,
115            text='Delete data')
116        self.Bind(wx.EVT_MENU, self.OnPwdrRead, id=wxID_PWDRREAD)
117        self.Bind(wx.EVT_MENU, self.OnPwdrSum, id=wxID_PWDSUM)
118        self.Bind(wx.EVT_MENU, self.OnReadPowderPeaks, id=wxID_READPEAKS)
119        self.Bind(wx.EVT_MENU, self.OnImageRead, id=wxID_IMGREAD)
120        self.Bind(wx.EVT_MENU, self.OnImageSum, id=wxID_IMSUM)
121        self.Bind(wx.EVT_MENU, self.OnSnglRead, id=wxID_SNGLREAD)
122        self.Bind(wx.EVT_MENU, self.OnAddPhase, id=wxID_ADDPHASE)
123        self.Bind(wx.EVT_MENU, self.OnDeletePhase, id=wxID_DELETEPHASE)
124        self.Bind(wx.EVT_MENU, self.OnRenameData, id=wxID_DATARENAME)
125        self.Bind(wx.EVT_MENU, self.OnDataDelete, id=wxID_DATADELETE)
126               
127    def _init_coll_Calculate_Items(self,parent):
128        self.Refine = parent.Append(help='', id=wxID_REFINE, kind=wx.ITEM_NORMAL,
129            text='Refine')
130        self.Refine.Enable(False)
131        self.Bind(wx.EVT_MENU, self.OnRefine, id=wxID_REFINE)
132        self.UnDo = parent.Append(help='', id=wxID_UNDO, kind=wx.ITEM_NORMAL,
133            text='UnDo')
134        self.UnDo.Enable(False)
135        self.Bind(wx.EVT_MENU, self.OnUnDo, id=wxID_UNDO)
136       
137    def _init_coll_Import_Items(self,parent):
138        self.ImportPhase = parent.Append(help='Import phase data from GSAS EXP file',
139            id=wxID_IMPORTPHASE, kind=wx.ITEM_NORMAL,text='Import GSAS EXP Phase...')
140        self.ImportPDB = parent.Append(help='Import phase data from PDB file',
141            id=wxID_IMPORTPDB, kind=wx.ITEM_NORMAL,text='Import PDB Phase...')
142        self.ImportPattern = parent.Append(help='',id=wxID_IMPORTPATTERN, kind=wx.ITEM_NORMAL,
143            text='Import Powder Pattern...')
144        self.ImportHKL = parent.Append(help='',id=wxID_IMPORTHKL, kind=wx.ITEM_NORMAL,
145            text='Import HKLs...')
146        self.ImportCIF = parent.Append(help='',id=wxID_IMPORTCIF, kind=wx.ITEM_NORMAL,
147            text='Import CIF...')
148        self.Bind(wx.EVT_MENU, self.OnImportPhase, id=wxID_IMPORTPHASE)
149        self.Bind(wx.EVT_MENU, self.OnImportPDB, id=wxID_IMPORTPDB)
150        self.Bind(wx.EVT_MENU, self.OnImportPattern, id=wxID_IMPORTPATTERN)
151        self.Bind(wx.EVT_MENU, self.OnImportHKL, id=wxID_IMPORTHKL)
152        self.Bind(wx.EVT_MENU, self.OnImportCIF, id=wxID_IMPORTCIF)
153
154    def _init_coll_Export_Items(self,parent):
155        self.ExportPattern = parent.Append(help='Select PWDR item to enable',id=wxID_EXPORTPATTERN, kind=wx.ITEM_NORMAL,
156            text='Export Powder Pattern...')
157        self.ExportPeakList = parent.Append(help='',id=wxID_EXPORTPEAKLIST, kind=wx.ITEM_NORMAL,
158            text='Export All Peak Lists...')
159        self.ExportHKL = parent.Append(help='',id=wxID_EXPORTHKL, kind=wx.ITEM_NORMAL,
160            text='Export HKLs...')
161        self.ExportPhase = parent.Append(help='',id=wxID_EXPORTPHASE, kind=wx.ITEM_NORMAL,
162            text='Export Phase...')
163        self.ExportCIF = parent.Append(help='',id=wxID_EXPORTCIF, kind=wx.ITEM_NORMAL,
164            text='Export CIF...')
165        self.ExportPattern.Enable(False)
166        self.ExportPeakList.Enable(True)
167        self.ExportHKL.Enable(False)
168        self.ExportPhase.Enable(False)
169        self.ExportCIF.Enable(False)
170        self.Bind(wx.EVT_MENU, self.OnExportPattern, id=wxID_EXPORTPATTERN)
171        self.Bind(wx.EVT_MENU, self.OnExportPeakList, id=wxID_EXPORTPEAKLIST)
172        self.Bind(wx.EVT_MENU, self.OnExportHKL, id=wxID_EXPORTHKL)
173        self.Bind(wx.EVT_MENU, self.OnExportPhase, id=wxID_EXPORTPHASE)
174        self.Bind(wx.EVT_MENU, self.OnExportCIF, id=wxID_EXPORTCIF)
175               
176    def _init_coll_Help_Items(self, parent):
177        parent.Append(help='', id=wxID_HELPHELP, kind=wx.ITEM_NORMAL,
178            text='Help')
179        parent.Append(help='', id=wxID_HELPABOUT, kind=wx.ITEM_NORMAL,
180            text='About')
181        self.Bind(wx.EVT_MENU, self.OnHelpHelp, id=wxID_HELPHELP)
182        self.Bind(wx.EVT_MENU, self.OnHelpAbout, id=wxID_HELPABOUT)
183
184    def _init_utils(self):
185        self.GSASIIMenu = wx.MenuBar()
186        self.File = wx.Menu(title='')
187        self.Data = wx.Menu(title='')       
188        self.Calculate = wx.Menu(title='')       
189        self.Import = wx.Menu(title='')       
190        self.Export = wx.Menu(title='')       
191        self.Help = wx.Menu(title='')
192
193        self._init_coll_GSASIIMenu_Menus(self.GSASIIMenu)
194        self._init_coll_File_Items(self.File)
195        self._init_coll_Data_Items(self.Data)
196        self._init_coll_Calculate_Items(self.Calculate)
197        self._init_coll_Import_Items(self.Import)
198        self._init_coll_Export_Items(self.Export)
199        self._init_coll_Help_Items(self.Help)
200       
201    def _init_ctrls(self, parent):
202        wx.Frame.__init__(self, name='GSASII', parent=parent,
203            size=wx.Size(300, 250),style=wx.DEFAULT_FRAME_STYLE, title='GSAS-II data tree')
204        screenSize = wx.DisplaySize()
205        Size = self.GetSize()
206        xPos = screenSize[0]-Size[0]
207        self.SetPosition(wx.Point(xPos,0))
208        self._init_utils()
209        self.SetMenuBar(self.GSASIIMenu)
210        self.Bind(wx.EVT_SIZE, self.OnSize)
211        self.CreateStatusBar()
212        self.mainPanel = wx.Panel(self,-1)
213       
214        self.PatternTree = wx.TreeCtrl(id=wxID_PATTERNTREE,
215            parent=self.mainPanel, pos=wx.Point(0, 0),style=wx.TR_DEFAULT_STYLE )
216        self.PatternTree.Bind(wx.EVT_TREE_SEL_CHANGED,
217            self.OnPatternTreeSelChanged, id=wxID_PATTERNTREE)
218        self.PatternTree.Bind(wx.EVT_TREE_ITEM_COLLAPSED,
219            self.OnPatternTreeItemCollapsed, id=wxID_PATTERNTREE)
220        self.PatternTree.Bind(wx.EVT_TREE_ITEM_EXPANDED,
221            self.OnPatternTreeItemExpanded, id=wxID_PATTERNTREE)
222        self.root = self.PatternTree.AddRoot('Loaded Data: ')
223       
224        plotFrame = wx.Frame(None,-1,'GSASII Plots',size=wx.Size(700,600), \
225            style=wx.DEFAULT_FRAME_STYLE ^ wx.CLOSE_BOX)
226        self.G2plotNB = G2plt.G2PlotNoteBook(plotFrame)
227        plotFrame.Show()
228       
229        self.dataDisplay = None
230       
231    def __init__(self, parent):
232        self._init_ctrls(parent)
233        self.Bind(wx.EVT_CLOSE, self.ExitMain)
234        self.GSASprojectfile = ''
235        self.dirname = ''
236        self.undofile = ''
237        self.Offset = 0.0
238        self.Weight = False
239        self.IparmName = ''
240        self.IfPlot = False
241        self.PatternId = 0
242        self.PickId = 0
243        self.PeakTable = []
244        self.LimitsTable = []
245        self.HKL = []
246        self.Lines = []
247        self.itemPicked = None
248        self.dataFrame = None
249        self.Contour = False
250        self.SinglePlot = False
251        self.plotView = 0
252        self.Image = 0
253        self.oldImagefile = ''
254        self.Integrate = 0
255        self.Pwdr = False
256        self.imageDefault = {}
257        self.Sngl = 0
258        self.ifGetRing = False
259        self.setPoly = False
260        arg = sys.argv
261        if len(arg) > 1:
262            self.GSASprojectfile = arg[1]
263            self.dirname = ospath.dirname(arg[1])
264            G2IO.ProjFileOpen(self)
265            self.PatternTree.Expand(self.root)
266            self.Refine.Enable(True)
267
268    def OnSize(self,event):
269        w,h = self.GetClientSizeTuple()
270        self.mainPanel.SetSize(wx.Size(w,h))
271        self.PatternTree.SetSize(wx.Size(w,h))
272                       
273    def OnPatternTreeSelChanged(self, event):
274        pltNum = self.G2plotNB.nb.GetSelection()
275        if pltNum >= 0:                         #to avoid the startup with no plot!
276            pltPage = self.G2plotNB.nb.GetPage(pltNum)
277            pltPlot = pltPage.figure
278        item = event.GetItem()
279        G2gd.MovePatternTreeToGrid(self,item)
280       
281    def OnPatternTreeItemCollapsed(self, event):
282        event.Skip()
283
284    def OnPatternTreeItemExpanded(self, event):
285        self.PatternTree.ScrollTo(self.PatternTree.GetLastChild(event.GetItem()))
286       
287    def OnPatternTreeDeleteItem(self, event):
288        event.Skip()
289
290    def OnPatternTreeItemActivated(self, event):
291        event.Skip()
292       
293    def OnPwdrRead(self, event):
294        self.CheckNotebook()
295        dlg = wx.FileDialog(self, 'Choose files', '.', '', 
296            'GSAS fxye files (*.fxye)|*.fxye|GSAS fxy files (*.fxy)|*.fxy|All files (*.*)|*.*', 
297            wx.OPEN | wx.MULTIPLE)
298        if self.dirname: dlg.SetDirectory(self.dirname)
299        try:
300            if dlg.ShowModal() == wx.ID_OK:
301                filenames = dlg.GetPaths()
302                filenames.sort()
303                self.dirname = dlg.GetDirectory()
304                for filename in filenames:
305                    Data,Iparm,Comments = G2IO.SelectPowderData(self, filename)              #Data: list of tuples (filename,Pos,Bank)
306                    if not Data:                                                    #if Data rejected by user - go to next one
307                        continue
308                    DataType = Iparm['INS   HTYPE ']                                #expect only 4 char string
309                    DataType = DataType.strip()[0:3]                                #just 1st 3 chars
310                    wx.BeginBusyCursor()
311                    Sample = {'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],'DisplaceX':[0.0,False],
312                        'DisplaceY':[0.0,False],'Diffuse':[]}
313                    try:
314                        for Item in Data:
315                            vals = Item[2].split()          #split up the BANK record
316                            Id = self.PatternTree.AppendItem(parent=self.root,text='PWDR '+ospath.basename(Item[0])+': '+vals[0]+vals[1])
317                            data = G2IO.GetPowderData(filename,Item[1],Item[2],DataType)
318                            self.PatternTree.SetItemPyData(Id,[Item,data])
319                            '''
320                            Each tree item data is a list with:
321                            Item: the (filename,Pos,Bank) tuple
322                            data: (x,y,w,yc,yb,yd) list  of np.arrays from GetPowderData
323                            '''
324                           
325                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)                           
326                            Tmin = min(data[0])
327                            Tmax = max(data[0])
328                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Limits'),[(Tmin,Tmax),[Tmin,Tmax]])
329                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',1,3,1.0,0.0,0.0]])
330       
331                            data = [DataType,]
332                            if 'C' in DataType:
333                                s = Iparm['INS  1 ICONS']
334                                v = (G2IO.sfloat(s[:10]),G2IO.sfloat(s[10:20]),G2IO.sfloat(s[20:30]),G2IO.sfloat(s[55:65]),G2IO.sfloat(s[40:50])) #get lam1, lam2, zero, pola & ratio
335                                if not v[1]:
336                                    names = ['Type','Lam','Zero','Polariz.','U','V','W','X','Y','SH/L','Azimuth'] 
337                                    v = (v[0],v[2],v[4])
338                                    codes = [0,0,0,0]
339                                else:
340                                    names = ['Type','Lam1','Lam2','Zero','I(L2)/I(L1)','Polariz.','U','V','W','X','Y','SH/L','Azimuth']
341                                    codes = [0,0,0,0,0,0]
342                                data.extend(v)
343                                v1 = Iparm['INS  1PRCF1 '].split()                                                 
344                                v = Iparm['INS  1PRCF11'].split()
345                                data.extend([float(v[0]),float(v[1]),float(v[2])])                  #get GU, GV & GW - always here
346                                v = Iparm['INS  1PRCF12'].split()
347                                if v1[0] == 3:
348                                    data.extend([float(v[0]),float(v[1]),float(v[2])+float(v[3],0.0)])  #get LX, LY, S+H/L & azimuth
349                                else:
350                                    data.extend([0.0,0.0,0.002,0.0])                                      #OK defaults if fxn #3 not 1st in iprm file
351                                codes.extend([0,0,0,0,0,0,0])
352                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(data),data,codes,names])
353                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
354                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Peak List'),[])
355                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),[])
356                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
357                            self.PatternId = G2gd.GetPatternTreeItemId(self,Id,'Limits')
358                    finally:
359                        wx.EndBusyCursor()
360                self.PatternTree.Expand(Id)
361                self.PatternTree.SelectItem(Id)
362   
363        finally:
364            dlg.Destroy()
365       
366    def OnReadPowderPeaks(self,event):
367        Cuka = 1.54052
368        self.CheckNotebook()
369        dlg = wx.FileDialog(self, 'Choose file with peak list', '.', '', 
370            'peak files (*.txt)|*.txt|All files (*.*)|*.*',wx.OPEN)
371        if self.dirname:
372            dlg.SetDirectory(self.dirname)
373        try:
374            if dlg.ShowModal() == wx.ID_OK:
375                self.HKL = []
376                self.powderfile = dlg.GetPath()
377                self.dirname = dlg.GetDirectory()
378                comments,peaks = G2IO.GetPowderPeaks(self.powderfile)
379                Id = self.PatternTree.AppendItem(parent=self.root,text='PKS '+ospath.basename(self.powderfile))
380                data = ['PKS',Cuka,0.0]
381                names = ['Type','Lam','Zero'] 
382                codes = [0,0]
383                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(data),data,codes,names])
384                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),comments)
385                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),peaks)
386                self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
387                self.PatternTree.Expand(Id)
388                self.PatternTree.SelectItem(Id)
389        finally:
390            dlg.Destroy()
391           
392    def OnImageRead(self,event):
393        self.CheckNotebook()
394        dlg = wx.FileDialog(self, 'Choose image files', '.', '',\
395        'MAR345 (*.mar3450;*.mar2300)|*.mar3450;*.mar2300|ADSC Image (*.img)\
396        |*.img|Detector tif (*.tif;*.tiff)|*.tif;*.tiff|GE Image sum (*.sum)\
397        |*.sum|GE Image avg (*.avg)|*.avg|GE Image raw (*)|*|All files (*.*)|*.*',wx.OPEN | wx.MULTIPLE)
398        if self.dirname:
399            dlg.SetDirectory(self.dirname)
400        try:
401            if dlg.ShowModal() == wx.ID_OK:
402                self.dirname = dlg.GetDirectory()
403                imagefiles = dlg.GetPaths()
404                imagefiles.sort()
405                for imagefile in imagefiles:
406                    Comments,Data,Size,Image = G2IO.GetImageData(imagefile)
407                    if Comments:
408                        Id = self.PatternTree.AppendItem(parent=self.root,text='IMG '+ospath.basename(imagefile))
409                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)
410                        Imax = np.amax(Image)
411                        Imin = np.amin(Image)
412                        if self.imageDefault:
413                            Data = copy.copy(self.imageDefault)
414                            Data['showLines'] = True
415                            Data['ring'] = []
416                            Data['rings'] = []
417                            Data['cutoff'] = 10
418                            Data['pixLimit'] = 20
419                            Data['ellipses'] = []
420                            Data['calibrant'] = ''
421                        else:
422                            Data['color'] = 'binary'
423                            Data['tilt'] = 0.0
424                            Data['rotation'] = 0.0
425                            Data['showLines'] = False
426                            Data['ring'] = []
427                            Data['rings'] = []
428                            Data['cutoff'] = 10
429                            Data['pixLimit'] = 20
430                            Data['ellipses'] = []
431                            Data['calibrant'] = ''
432                            Data['IOtth'] = [2.0,5.0]
433                            Data['LRazimuth'] = [-135,-45]
434                            Data['outChannels'] = 2500
435                            Data['outAzimuths'] = 1
436                            Data['fullIntegrate'] = False
437                            Data['setRings'] = False
438                        Data['setDefault'] = False
439                        Data['range'] = [(Imin,Imax),[Imin,Imax]]
440                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Image Controls'),Data)
441                        Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
442                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Masks'),Masks)
443                        self.PatternTree.SetItemPyData(Id,[Size,imagefile])
444                        self.PickId = Id
445                        self.Image = Id
446                self.PatternTree.SelectItem(Id)             #show last one
447                self.PatternTree.Expand(Id)
448        finally:
449            dlg.Destroy()
450       
451    def OnSnglRead(self,event):
452        self.CheckNotebook()
453        dlg = wx.FileDialog(self, 'Choose file', '.', '', 
454            'hkl files (*.hkl)|*.hkl|All files (*.*)|*.*', 
455            wx.OPEN)
456        if self.dirname: dlg.SetDirectory(self.dirname)
457        try:
458            if dlg.ShowModal() == wx.ID_OK:
459                filename = dlg.GetPath()
460                self.dirname = dlg.GetDirectory()
461                wx.BeginBusyCursor()
462                try:
463                    Data = {}
464                    names = ['Type','Lam']
465                    HKLref,HKLmin,HKLmax,FoMax,ifFc = G2IO.GetHKLData(filename)
466                    Id = self.PatternTree.AppendItem(parent=self.root,text='HKLF '+ospath.basename(filename))
467                    self.PatternTree.SetItemPyData(Id,HKLref)
468                    Sub = self.PatternTree.AppendItem(Id,text='Instrument Parameters')
469                    data = ['SXC',1.5428,]
470                    self.PatternTree.SetItemPyData(Sub,[tuple(data),data,names])
471                    Data['Type'] = 'Fosq'
472                    Data['ifFc'] = ifFc
473                    Data['HKLmax'] = HKLmax
474                    Data['HKLmin'] = HKLmin
475                    Data['FoMax'] = FoMax
476                    Data['Zone'] = '001'
477                    Data['Layer'] = 0
478                    Data['Scale'] = 1.0
479                    Data['log-lin'] = 'lin'                   
480                    self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='HKL Plot Controls'),Data)
481                    self.PatternTree.SelectItem(Id)
482                    self.PatternTree.Expand(Id)
483                    self.Sngl = Id
484                finally:
485                    wx.EndBusyCursor()   
486        finally:
487            dlg.Destroy()
488           
489    def CheckNotebook(self):
490        if not G2gd.GetPatternTreeItemId(self,self.root,'Notebook'):
491            sub = self.PatternTree.AppendItem(parent=self.root,text='Notebook')
492            self.PatternTree.SetItemPyData(sub,[''])
493            sub = self.PatternTree.AppendItem(parent=self.root,text='Controls')
494            self.PatternTree.SetItemPyData(sub,{})
495               
496    class CopyDialog(wx.Dialog):
497        def __init__(self,parent,title,text,data):
498            wx.Dialog.__init__(self,parent,-1,title, 
499                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
500            self.data = data
501            panel = wx.Panel(self)
502            mainSizer = wx.BoxSizer(wx.VERTICAL)
503            topLabl = wx.StaticText(panel,-1,text)
504            mainSizer.Add((10,10),1)
505            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
506            mainSizer.Add((10,10),1)
507            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=1,hgap=2,vgap=2)
508            for id,item in enumerate(self.data):
509                ckbox = wx.CheckBox(panel,id,item[1])
510                ckbox.Bind(wx.EVT_CHECKBOX,self.OnCopyChange)                   
511                dataGridSizer.Add(ckbox,0,wx.LEFT,10)
512            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
513            OkBtn = wx.Button(panel,-1,"Ok")
514            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
515            cancelBtn = wx.Button(panel,-1,"Cancel")
516            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
517            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
518            btnSizer.Add((20,20),1)
519            btnSizer.Add(OkBtn)
520            btnSizer.Add((20,20),1)
521            btnSizer.Add(cancelBtn)
522            btnSizer.Add((20,20),1)
523           
524            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
525            panel.SetSizer(mainSizer)
526            panel.Fit()
527            self.Fit()
528       
529        def OnCopyChange(self,event):
530            id = event.GetId()
531            self.data[id][0] = self.FindWindowById(id).GetValue()       
532           
533        def OnOk(self,event):
534            parent = self.GetParent()
535            parent.Raise()
536            self.EndModal(wx.ID_OK)             
537            self.Destroy()
538           
539        def OnCancel(self,event):
540            parent = self.GetParent()
541            parent.Raise()
542            self.EndModal(wx.ID_CANCEL)             
543            self.Destroy()
544           
545        def GetData(self):
546                return self.data
547       
548    class SumDialog(wx.Dialog):
549        def __init__(self,parent,title,text,dataType,data):
550            wx.Dialog.__init__(self,parent,-1,title, 
551                pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
552            self.data = data
553            panel = wx.Panel(self)
554            mainSizer = wx.BoxSizer(wx.VERTICAL)
555            topLabl = wx.StaticText(panel,-1,text)
556            mainSizer.Add((10,10),1)
557            mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.LEFT,10)
558            mainSizer.Add((10,10),1)
559            dataGridSizer = wx.FlexGridSizer(rows=len(data),cols=2,hgap=2,vgap=2)
560            for id,item in enumerate(self.data[:-1]):
561                name = wx.TextCtrl(panel,-1,item[1],size=wx.Size(200,20))
562                name.SetEditable(False)
563                scale = wx.TextCtrl(panel,id,str(item[0]),style=wx.TE_PROCESS_ENTER)
564                scale.Bind(wx.EVT_TEXT,self.OnScaleChange)                   
565                dataGridSizer.Add(scale,0,wx.LEFT,10)
566                dataGridSizer.Add(name,0,wx.RIGHT,10)
567            dataGridSizer.Add(wx.StaticText(panel,-1,'Sum result name: '+dataType),0, \
568                wx.LEFT|wx.TOP|wx.ALIGN_CENTER_VERTICAL,10)
569            self.name = wx.TextCtrl(panel,-1,self.data[-1],size=wx.Size(200,20),style=wx.TE_PROCESS_ENTER)
570            self.name.Bind(wx.EVT_TEXT,self.OnNameChange)
571            dataGridSizer.Add(self.name,0,wx.RIGHT|wx.TOP,10)
572            mainSizer.Add(dataGridSizer,0,wx.EXPAND)
573            OkBtn = wx.Button(panel,-1,"Ok")
574            OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
575            cancelBtn = wx.Button(panel,-1,"Cancel")
576            cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
577            btnSizer = wx.BoxSizer(wx.HORIZONTAL)
578            btnSizer.Add((20,20),1)
579            btnSizer.Add(OkBtn)
580            btnSizer.Add((20,20),1)
581            btnSizer.Add(cancelBtn)
582            btnSizer.Add((20,20),1)
583           
584            mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
585            panel.SetSizer(mainSizer)
586            panel.Fit()
587            self.Fit()
588           
589        def OnNameChange(self,event):
590            self.data[-1] = self.name.GetValue() 
591           
592        def OnScaleChange(self,event):
593            id = event.GetId()
594            value = self.FindWindowById(id).GetValue()
595            try:
596                self.data[id][0] = float(value)
597                self.FindWindowById(id).SetValue('%.3f'%(self.data[id][0]))
598            except ValueError:
599                if value and '-' not in value[0]:
600                    print 'bad input - numbers only'
601                    self.FindWindowById(id).SetValue('0.0')
602           
603        def OnOk(self,event):
604            parent = self.GetParent()
605            parent.Raise()
606            self.EndModal(wx.ID_OK)             
607            self.Destroy()
608           
609        def OnCancel(self,event):
610            parent = self.GetParent()
611            parent.Raise()
612            self.EndModal(wx.ID_CANCEL)             
613            self.Destroy()
614           
615        def GetData(self):
616            return self.data
617           
618    def OnPwdrSum(self,event):
619        TextList = []
620        DataList = []
621        SumList = []
622        Names = []
623        Inst = []
624        SumItemList = []
625        Comments = ['Sum equals: \n']
626        if self.PatternTree.GetCount():
627            item, cookie = self.PatternTree.GetFirstChild(self.root)
628            while item:
629                name = self.PatternTree.GetItemText(item)
630                Names.append(name)
631                if 'PWDR' in name:
632                    TextList.append([0.0,name])
633                    DataList.append(self.PatternTree.GetItemPyData(item)[1])    # (x,y,w,yc,yb,yd)
634                    if not Inst:
635                        Inst = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,item, 'Instrument Parameters'))
636                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
637            if len(TextList) < 2:
638                self.ErrorDialog('Not enough data to sum','There must be more than one "PWDR" pattern')
639                return
640            TextList.append('default_sum_name')               
641            dlg = self.SumDialog(self,'Sum data','Enter scale for each pattern in summation','PWDR',TextList)
642            try:
643                if dlg.ShowModal() == wx.ID_OK:
644                    lenX = 0
645                    Xminmax = [0,0]
646                    Xsum = []
647                    Ysum = []
648                    Wsum = []
649                    result = dlg.GetData()
650                    for i,item in enumerate(result[:-1]):
651                        scale,name = item
652                        data = DataList[i]
653                        if scale:
654                            Comments.append("%10.3f %s" % (scale,' * '+name))
655                            x,y,w,yc,yb,yd = data
656                            if lenX:
657                                if lenX != len(x):
658                                    self.ErrorDialog('Data length error','Data to be summed must have same number of points'+ \
659                                        '\nExpected:'+str(lenX)+ \
660                                        '\nFound:   '+str(len(x))+'\nfor '+name)
661                                    return
662                            else:
663                                lenX = len(x)
664                            if Xminmax[1]:
665                                if Xminmax != [x[0],x[-1]]:
666                                    self.ErrorDialog('Data range error','Data to be summed must span same range'+ \
667                                        '\nExpected:'+str(Xminmax[0])+' '+str(Xminmax[1])+ \
668                                        '\nFound:   '+str(x[0])+' '+str(x[-1])+'\nfor '+name)
669                                    return
670                                else:
671                                    for j,yi in enumerate(y):
672                                         Ysum[j] += scale*yi
673                            else:
674                                Xminmax = [x[0],x[-1]]
675                                YCsum = YBsum = YDsum = [0.0 for i in range(lenX)]
676                                for j,yi in enumerate(y):
677                                    Xsum.append(x[j])
678                                    Ysum.append(scale*yi)
679                                    Wsum.append(w[j])
680                    outname = 'PWDR '+result[-1]
681                    Id = 0
682                    if outname in Names:
683                        dlg2 = wx.MessageDialog(self,'Overwrite data?','Duplicate data name',wx.OK|wx.CANCEL)
684                        try:
685                            if dlg2.ShowModal() == wx.ID_OK:
686                                Id = G2gd.GetPatternTreeItemId(self,self.root,name)
687                        finally:
688                            dlg2.Destroy()
689                    else:
690                        Id = self.PatternTree.AppendItem(parent=self.root,text=outname)
691                    if Id:
692                        Sample = {'Scale':[1.0,True],'Type':'Debye-Scherrer','Absorption':[0.0,False],'DisplaceX':[0.0,False],
693                            'DisplaceY':[0.0,False],'Diffuse':[]}
694                        self.PatternTree.SetItemPyData(Id,[[''],[Xsum,Ysum,Wsum,YCsum,YBsum,YDsum]])
695                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)                   
696                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Limits'),[tuple(Xminmax),Xminmax])
697                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',1,3,1.0,0.0,0.0]])
698                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Instrument Parameters'),Inst)
699                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
700                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Peak List'),[])
701                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Index Peak List'),[])
702                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Unit Cells List'),[])             
703                        self.PatternTree.SelectItem(Id)
704                        self.PatternTree.Expand(Id)
705                   
706            finally:
707                dlg.Destroy()
708
709    def OnImageSum(self,event):
710        TextList = []
711        DataList = []
712        SumList = []
713        Names = []
714        Inst = []
715        SumItemList = []
716        Comments = ['Sum equals: \n']
717        if self.PatternTree.GetCount():
718            item, cookie = self.PatternTree.GetFirstChild(self.root)
719            while item:
720                name = self.PatternTree.GetItemText(item)
721                Names.append(name)
722                if 'IMG' in name:
723                    TextList.append([0.0,name])
724                    DataList.append(self.PatternTree.GetItemPyData(item))        #Size,Image
725                    Data = self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,item,'Image Controls'))
726                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
727            if len(TextList) < 2:
728                self.ErrorDialog('Not enough data to sum','There must be more than one "IMG" pattern')
729                return
730            TextList.append('default_sum_name')               
731            dlg = self.SumDialog(self,'Sum data','Enter scale for each image in summation','IMG',TextList)
732            try:
733                if dlg.ShowModal() == wx.ID_OK:
734                    imSize = 0
735                    result = dlg.GetData()
736                    First = True
737                    Found = False
738                    for i,item in enumerate(result[:-1]):
739                        scale,name = item
740                        data = DataList[i]
741                        if scale:
742                            Found = True                               
743                            Comments.append("%10.3f %s" % (scale,' * '+name))
744                            size,imagefile = data
745                            image = G2IO.GetImageData(imagefile,imageOnly=True)
746                            if First:
747                                newImage = np.zeros_like(image)
748                                First = False
749                            if imSize:
750                                if imSize != size:
751                                    self.ErrorDialog('Image size error','Images to be summed must be same size'+ \
752                                        '\nExpected:'+str(imSize)+ \
753                                        '\nFound:   '+str(size)+'\nfor '+name)
754                                    return
755                                newImage = newImage+scale*image
756                            else:
757                                imSize = size
758                                newImage = newImage+scale*image
759                            del(image)
760                    if not Found:
761                        self.ErrorDialog('Image sum error','No nonzero image multipliers found')
762                        return
763                       
764                    newImage = np.asfarray(newImage,dtype=np.float32)                       
765                    outname = 'IMG '+result[-1]
766                    Id = 0
767                    if outname in Names:
768                        dlg2 = wx.MessageDialog(self,'Overwrite data?','Duplicate data name',wx.OK|wx.CANCEL)
769                        try:
770                            if dlg2.ShowModal() == wx.ID_OK:
771                                Id = G2gd.GetPatternTreeItemId(self,self.root,name)
772                        finally:
773                            dlg2.Destroy()
774                    else:
775                        Id = self.PatternTree.AppendItem(parent=self.root,text=outname)
776                    if Id:
777                        dlg = wx.FileDialog(self, 'Choose sum image filename', '.', '', 
778                            'G2img files (*.G2img)|*.G2img', 
779                            wx.SAVE|wx.FD_OVERWRITE_PROMPT)
780                        if self.dirname: dlg.SetDirectory(self.dirname)
781                        if dlg.ShowModal() == wx.ID_OK:
782                            self.dirname = dlg.GetDirectory()
783                            newimagefile = dlg.GetPath()
784                            G2IO.PutG2Image(newimagefile,newImage)
785                            Imax = np.amax(newImage)
786                            Imin = np.amin(newImage)
787                            newImage = []
788                            self.PatternTree.SetItemPyData(Id,[imSize,newimagefile])
789                            self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Comments'),Comments)
790                        del(newImage)
791                        if self.imageDefault:
792                            Data = copy.copy(self.imageDefault)
793                        Data['showLines'] = True
794                        Data['ring'] = []
795                        Data['rings'] = []
796                        Data['cutoff'] = 10
797                        Data['pixLimit'] = 20
798                        Data['ellipses'] = []
799                        Data['calibrant'] = ''
800                        Data['range'] = [(Imin,Imax),[Imin,Imax]]
801                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Image Controls'),Data)                                           
802                        Masks = {'Points':[],'Rings':[],'Arcs':[],'Polygons':[],'Thresholds':[(Imin,Imax),[Imin,Imax]]}
803                        self.PatternTree.SetItemPyData(self.PatternTree.AppendItem(Id,text='Masks'),Masks)
804                        self.PatternTree.SelectItem(Id)
805                        self.PatternTree.Expand(Id)
806                        self.PickId = G2gd.GetPatternTreeItemId(self,self.root,outname)
807                        self.Image = self.PickId
808            finally:
809                dlg.Destroy()
810                     
811    def OnAddPhase(self,event):
812        if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
813            sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
814        else:
815            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
816        PhaseName = ''
817        dlg = wx.TextEntryDialog(None,'Enter a name for this phase','Phase Name Entry','New phase',
818            style=wx.OK)
819        if dlg.ShowModal() == wx.ID_OK:
820            PhaseName = dlg.GetValue()
821        dlg.Destroy()
822        sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
823        E,SGData = G2spc.SpcGroup('P 1')
824        self.PatternTree.SetItemPyData(sub, \
825            {'General':{'Name':PhaseName,'Type':'nuclear','SGData':SGData,
826            'Cell':[False,10.,10.,10.,90.,90.,90,1000.],
827            'Pawley dmin':1.0},'Atoms':[],'Drawing':{},'Histograms':{}})
828       
829    def OnDeletePhase(self,event):
830        if self.dataFrame:
831            self.dataFrame.Clear() 
832        TextList = []
833        DelList = []
834        DelItemList = []
835        if G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
836            sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
837        else:
838            return
839        if sub:
840            item, cookie = self.PatternTree.GetFirstChild(sub)
841            while item:
842                TextList.append(self.PatternTree.GetItemText(item))
843                item, cookie = self.PatternTree.GetNextChild(sub, cookie)               
844            dlg = wx.MultiChoiceDialog(self, 'Which phase to delete?', 'Delete phase', TextList, wx.CHOICEDLG_STYLE)
845            try:
846                if dlg.ShowModal() == wx.ID_OK:
847                    result = dlg.GetSelections()
848                    for i in result: DelList.append([i,TextList[i]])
849                    item, cookie = self.PatternTree.GetFirstChild(sub)
850                    i = 0
851                    while item:
852                        if [i,self.PatternTree.GetItemText(item)] in DelList: DelItemList.append(item)
853                        item, cookie = self.PatternTree.GetNextChild(sub, cookie)
854                        i += 1
855                    for item in DelItemList:
856                        name = self.PatternTree.GetItemText(item)
857                        self.PatternTree.Delete(item)
858                        self.G2plotNB.Delete(name)
859            finally:
860                dlg.Destroy()
861               
862    def OnRenameData(self,event):
863        name = self.PatternTree.GetItemText(self.PickId)     
864        if 'PWDR' in name or 'HKLF' in name or 'IMG' in name:
865            dataType = name[:name.index(' ')+1]                 #includes the ' '
866            dlg = wx.TextEntryDialog(self,'Data name: '+dataType,'Change data name',
867                defaultValue=name[name.index(' ')+1:])
868            try:
869                if dlg.ShowModal() == wx.ID_OK:
870                    self.PatternTree.SetItemText(self.PickId,dataType+dlg.GetValue())
871            finally:
872                dlg.Destroy()
873       
874    def OnDataDelete(self, event):
875        TextList = []
876        DelList = []
877        DelItemList = []
878        if self.PatternTree.GetCount():
879            item, cookie = self.PatternTree.GetFirstChild(self.root)
880            while item:
881                name = self.PatternTree.GetItemText(item)
882                if 'PWDR' in name or 'HKLF' in name or 'IMG' in name:
883                    TextList.append(name)
884                item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
885            dlg = wx.MultiChoiceDialog(self, 'Which data to delete?', 'Delete data', TextList, wx.CHOICEDLG_STYLE)
886            try:
887                if dlg.ShowModal() == wx.ID_OK:
888                    result = dlg.GetSelections()
889                    for i in result: DelList.append(TextList[i])
890                    item, cookie = self.PatternTree.GetFirstChild(self.root)
891                    while item:
892                        if self.PatternTree.GetItemText(item) in DelList: DelItemList.append(item)
893                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)
894                    for item in DelItemList:
895                        self.PatternTree.Delete(item)
896                    G2plt.PlotPatterns(self,True)                        #so plot gets updated
897            finally:
898                dlg.Destroy()
899
900    def OnFileOpen(self, event):
901        result = ''
902        Id = 0
903        if self.PatternTree.GetChildrenCount(self.root,False):
904            if self.dataFrame:
905                self.dataFrame.Clear() 
906            dlg = wx.MessageDialog(self, 'Overwrite?','Project exists!',  wx.OK | wx.CANCEL)
907            try:
908                result = dlg.ShowModal()
909                if result == wx.ID_OK:
910                    self.PatternTree.DeleteChildren(self.root)
911                    self.GSASprojectfile = ''
912                    self.PatternTree.DeleteChildren(self.root)
913                    if self.HKL: self.HKL = []
914                    if self.G2plotNB.plotList:
915                        self.G2plotNB.clear()
916            finally:
917                dlg.Destroy()
918        if result != wx.ID_CANCEL:   
919            if self.dataDisplay: self.dataDisplay.Destroy()
920            dlg = wx.FileDialog(self, 'Choose GSAS-II project file', '.', '', 
921                'GSAS-II project file (*.gpx)|*.gpx',wx.OPEN)
922            if self.dirname: dlg.SetDirectory(self.dirname)
923            try:
924                if dlg.ShowModal() == wx.ID_OK:
925                    self.GSASprojectfile = dlg.GetPath()
926                    self.dirname = dlg.GetDirectory()
927                    G2IO.ProjFileOpen(self)
928                    self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
929                    self.PatternTree.Expand(self.root)
930                    self.HKL = []
931                    item, cookie = self.PatternTree.GetFirstChild(self.root)
932                    while item and not Id:
933                        name = self.PatternTree.GetItemText(item)
934                        if name[:4] in ['PWDR','HKLF','IMG']:
935                            Id = item
936                        elif name == 'Controls':
937                            data = self.PatternTree.GetItemPyData(item)
938                            if data != [0] and data != {}:
939                                self.Refine.Enable(True)
940                        item, cookie = self.PatternTree.GetNextChild(self.root, cookie)               
941                    if Id:
942                        self.PatternTree.SelectItem(Id)
943            finally:
944                dlg.Destroy()
945
946    def OnFileClose(self, event):
947        if self.dataFrame:
948            self.dataFrame.Clear()
949            self.dataFrame.SetLabel('GSAS-II data display') 
950        dlg = wx.MessageDialog(self, 'Save current project?', ' ', wx.YES | wx.NO | wx.CANCEL)
951        try:
952            result = dlg.ShowModal()
953            if result == wx.ID_OK:
954                self.OnFileSaveMenu(event)
955            if result != wx.ID_CANCEL:
956                self.GSASprojectfile = ''
957                self.PatternTree.SetItemText(self.root,'Loaded Data: ')
958                self.PatternTree.DeleteChildren(self.root)
959                if self.HKL: self.HKL = []
960                if self.G2plotNB.plotList:
961                    self.G2plotNB.clear()
962        finally:
963            dlg.Destroy()
964
965    def OnFileSave(self, event):
966        if self.GSASprojectfile: 
967            self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
968            G2IO.ProjFileSave(self)
969        else:
970            self.OnFileSaveas(event)
971
972    def OnFileSaveas(self, event):
973        dlg = wx.FileDialog(self, 'Choose GSAS-II project file name', '.', '', 
974            'GSAS-II project file (*.gpx)|*.gpx',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
975        if self.dirname:
976            dlg.SetDirectory(self.dirname)
977        try:
978            if dlg.ShowModal() == wx.ID_OK:
979                self.GSASprojectfile = dlg.GetPath()
980                self.PatternTree.SetItemText(self.root,'Loaded Data: '+self.GSASprojectfile)
981                G2IO.ProjFileSave(self)
982                self.dirname = dlg.GetDirectory()
983        finally:
984            dlg.Destroy()
985
986    def ExitMain(self, event):
987        if self.undofile:
988            os.remove(self.undofile)
989        sys.exit()
990       
991    def OnFileExit(self, event):
992        if self.dataFrame:
993            self.dataFrame.Clear() 
994            self.dataFrame.Destroy()
995        self.Close()
996       
997    def OnImportPattern(self,event):
998            dlg = wx.FileDialog(self, 'Choose nonGSAS powder file', '.', '', 
999                '(*.*)|*.*',wx.OPEN)
1000            if self.dirname:
1001                dlg.SetDirectory(self.dirname)
1002            try:
1003                if dlg.ShowModal() == wx.ID_OK:
1004                    self.powderfile = dlg.GetPath()
1005                    self.dirname = dlg.GetDirectory()
1006            finally:
1007                dlg.Destroy()
1008               
1009    def OnImportHKL(self,event):
1010            dlg = wx.FileDialog(self, 'Choose structure factor file', '.', '', 
1011                '(*.*)|*.*',wx.OPEN)
1012            if self.dirname:
1013                dlg.SetDirectory(self.dirname)
1014            try:
1015                if dlg.ShowModal() == wx.ID_OK:
1016                    self.HKLfile = dlg.GetPath()
1017                    self.dirname = dlg.GetDirectory()
1018            finally:
1019                dlg.Destroy()
1020       
1021    def OnImportPhase(self,event):
1022            dlg = wx.FileDialog(self, 'Choose GSAS EXP file', '.', '', 
1023                'EXP file (*.EXP)|*.EXP',wx.OPEN)
1024            if self.dirname:
1025                dlg.SetDirectory(self.dirname)
1026            try:
1027                Phase = {}
1028                if dlg.ShowModal() == wx.ID_OK:
1029                    EXPfile = dlg.GetPath()
1030                    self.dirname = dlg.GetDirectory()
1031                    Phase = G2IO.ReadEXPPhase(self,EXPfile)
1032            finally:
1033                dlg.Destroy()
1034            if Phase:
1035                PhaseName = Phase['General']['Name']
1036                if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1037                    sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1038                else:
1039                    sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1040                sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1041                self.PatternTree.SetItemPyData(sub,Phase)
1042               
1043    def OnImportPDB(self,event):
1044            dlg = wx.FileDialog(self, 'Choose PDB file', '.', '', 
1045                'PDB file (*.pdb,*.ent)|*.pdb;*.ent|All files (*.*)|*.*',wx.OPEN)
1046            if self.dirname:
1047                dlg.SetDirectory(self.dirname)
1048            try:
1049                if dlg.ShowModal() == wx.ID_OK:
1050                    PDBfile = dlg.GetPath()
1051                    self.dirname = dlg.GetDirectory()
1052                    Phase = G2IO.ReadPDBPhase(PDBfile)
1053            finally:
1054                dlg.Destroy()
1055            if Phase:
1056                PhaseName = Phase['General']['Name']
1057                if not G2gd.GetPatternTreeItemId(self,self.root,'Phases'):
1058                    sub = self.PatternTree.AppendItem(parent=self.root,text='Phases')
1059                else:
1060                    sub = G2gd.GetPatternTreeItemId(self,self.root,'Phases')
1061                sub = self.PatternTree.AppendItem(parent=sub,text=PhaseName)
1062                self.PatternTree.SetItemPyData(sub,Phase)       
1063       
1064    def OnImportCIF(self,event):
1065            dlg = wx.FileDialog(self, 'Choose CIF file', '.', '', 
1066                'CIF file (*.cif)|*.cif',wx.OPEN)
1067            if self.dirname:
1068                dlg.SetDirectory(self.dirname)
1069            try:
1070                if dlg.ShowModal() == wx.ID_OK:
1071                    self.CIFfile = dlg.GetPath()
1072                    self.dirname = dlg.GetDirectory()
1073            finally:
1074                dlg.Destroy()
1075       
1076    def OnExportPattern(self,event):
1077        dlg = wx.FileDialog(self, 'Choose output powder file name', '.', '', 
1078            'GSAS fxye file (*.fxye)|*.fxye|xye file (*.xye)|*.xye',
1079            wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
1080        if self.dirname:
1081            dlg.SetDirectory(self.dirname)
1082        try:
1083            if dlg.ShowModal() == wx.ID_OK:
1084                powderfile = dlg.GetPath()
1085                if 'fxye' in powderfile:
1086                    G2IO.powderFxyeSave(self,powderfile)
1087                else:       #just xye
1088                    G2IO.powderXyeSave(self,powderfile)
1089                self.dirname = dlg.GetDirectory()
1090        finally:
1091            dlg.Destroy()
1092       
1093    def OnExportPeakList(self,event):
1094        dlg = wx.FileDialog(self, 'Choose output peak list file name', '.', '', 
1095            '(*.*)|*.*',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
1096        if self.dirname:
1097            dlg.SetDirectory(self.dirname)
1098        try:
1099            if dlg.ShowModal() == wx.ID_OK:
1100                self.peaklistfile = dlg.GetPath()
1101                file = open(self.peaklistfile,'w')               
1102                item, cookie = self.PatternTree.GetFirstChild(self.root)
1103                while item:
1104                    name = self.PatternTree.GetItemText(item)
1105                    if 'PWDR' in name:
1106                        item2, cookie2 = self.PatternTree.GetFirstChild(item)
1107                        while item2:
1108                            name2 = self.PatternTree.GetItemText(item2)
1109                            if name2 == 'Peak List':
1110                                peaks = self.PatternTree.GetItemPyData(item2)
1111                                file.write("%s \n" % (name+' Peak List'))               
1112                                for peak in peaks:
1113                                    file.write("%10.4f %12.2f %10.3f %10.3f \n" % \
1114                                        (peak[0],peak[2],peak[4],peak[6]))
1115                            item2, cookie2 = self.PatternTree.GetNextChild(item, cookie2)                           
1116                    item, cookie = self.PatternTree.GetNextChild(self.root, cookie)                           
1117                file.close()
1118                self.dirname = dlg.GetDirectory()
1119        finally:
1120            dlg.Destroy()
1121       
1122    def OnExportHKL(self,event):
1123        event.Skip()
1124       
1125    def OnExportPhase(self,event):
1126        event.Skip()
1127       
1128    def OnExportCIF(self,event):
1129        event.Skip()
1130       
1131    def OnUnDo(self,event):
1132        self.DoUnDo()
1133        self.UnDo.Enable(False)
1134       
1135    def OnRefine(self,event):
1136        #works - but it'd be better if it could restore plots
1137        G2str.Refine(self.GSASprojectfile)
1138        dlg = wx.MessageDialog(self,'Load new result?','Refinement results',wx.OK|wx.CANCEL)
1139        try:
1140            if dlg.ShowModal() == wx.ID_OK:
1141                self.PatternTree.DeleteChildren(self.root)
1142                if self.HKL: self.HKL = []
1143                if self.G2plotNB.plotList:
1144                    self.G2plotNB.clear()
1145                G2IO.ProjFileOpen(self)
1146        finally:
1147            dlg.Destroy()
1148       
1149    def DoUnDo(self):
1150        print 'Undo last refinement'
1151        file = open(self.undofile,'rb')
1152        PatternId = self.PatternId
1153        for item in ['Background','Instrument Parameters','Peak List']:
1154            self.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, item),cPickle.load(file))
1155            if self.dataDisplay.GetName() == item:
1156                if item == 'Background':
1157                    G2pdG.UpdateBackgroundGrid(self,self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, item)))
1158                elif item == 'Instrument Parameters':
1159                    G2pdG.UpdateInstrumentGrid(self,self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, item)))
1160                elif item == 'Peak List':
1161                    G2pdG.UpdatePeakGrid(self,self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId, item)))
1162            print item,' recovered'
1163        file.close()
1164       
1165    def SaveState(self):
1166        self.undofile = self.dirname+'\\GSASII.save'
1167        file = open(self.undofile,'wb')
1168        PatternId = self.PatternId
1169        for item in ['Background','Instrument Parameters','Peak List']:
1170            cPickle.dump(self.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(self,PatternId,item)),file,1)
1171        file.close()
1172        self.UnDo.Enable(True)
1173               
1174    def ErrorDialog(self,title,message):
1175        dlg = wx.MessageDialog(self, message, title,  wx.OK)
1176        try:
1177            result = dlg.ShowModal()
1178        finally:
1179            dlg.Destroy()
1180
1181    def OnHelpHelp(self, event):
1182        event.Skip()
1183       
1184    def OnHelpAbout(self, event):
1185        info = wx.AboutDialogInfo()
1186        info.Name = 'GSAS-II'
1187        info.Version = __version__
1188        info.Copyright = '''
1189Robert B. Von Dreele
1190Argonne National Laboratory(C)
1191This product includes software developed
1192by the UChicago Argonne, LLC, as
1193Operator of Argonne National Laboratory.         '''
1194        info.Description = '''
1195General Structure Analysis System - II
1196        '''
1197        wx.AboutBox(info)
1198       
1199class GSASIImain(wx.App):
1200    def OnInit(self):
1201        self.main = GSASII(None)
1202        self.main.Show()
1203        self.SetTopWindow(self.main)
1204        return True
1205
1206def main():
1207    application = GSASIImain(0)
1208    application.MainLoop()
1209
1210if __name__ == '__main__':
1211    main()
Note: See TracBrowser for help on using the repository browser.