source: trunk/GSASII.py @ 248

Last change on this file since 248 was 248, checked in by vondreele, 11 years ago

histogram2d.for - cleaned up
add azmthOff - as for a rotation of a 2D detector
fix image integration problems

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