source: trunk/GSASIIIO.py @ 643

Last change on this file since 643 was 643, checked in by toby, 10 years ago

allow multiple selection from zip on data input, read structure CIFs w/o atom type

  • Property svn:keywords set to Date Author Revision URL Id
File size: 70.4 KB
Line 
1# -*- coding: utf-8 -*-
2"""GSASIIIO: functions for IO of data
3   Copyright: 2008, Robert B. Von Dreele (Argonne National Laboratory)
4"""
5########### SVN repository information ###################
6# $Date: 2012-05-30 19:12:46 +0000 (Wed, 30 May 2012) $
7# $Author: toby $
8# $Revision: 643 $
9# $URL: trunk/GSASIIIO.py $
10# $Id: GSASIIIO.py 643 2012-05-30 19:12:46Z toby $
11########### SVN repository information ###################
12import wx
13import math
14import numpy as np
15import cPickle
16import sys
17import random as ran
18import GSASIIpath
19import GSASIIgrid as G2gd
20import GSASIIspc as G2spc
21import GSASIIlattice as G2lat
22import GSASIIpwdGUI as G2pdG
23import GSASIIElem as G2el
24import os
25import os.path as ospath
26
27def sfloat(S):
28    if S.strip():
29        return float(S)
30    else:
31        return 0.0
32
33def sint(S):
34    if S.strip():
35        return int(S)
36    else:
37        return 0
38
39def FileDlgFixExt(dlg,file):
40    #this is needed to fix a problem in linux wx.FileDialog
41    ext = dlg.GetWildcard().split('|')[2*dlg.GetFilterIndex()+1].strip('*')
42    if ext not in file:
43        file += ext
44    return file
45   
46## to be removed
47#def SelectPowderData(G2frame, filename):
48#    """Selects banks of data from a filename of any GSAS powder data format
49#    Input - filename: any GSAS powder data formatted file (currently STD, FXYE, FXY & ESD)
50#    Returns - a list of banks to be read; each entry in list is a tuple containing:
51#    filename: same as input filename
52#    Pos: position for start of data; record just after BANK record
53#    Bank: the BANK record
54#    """
55#    File = open(filename,'Ur')
56#    Title = '''
57#First line of this file:
58#'''+File.readline()
59#    dlg = wx.MessageDialog(G2frame, Title, 'Is this the file you want?',
60#        wx.YES_NO | wx.ICON_QUESTION)
61#    try:
62#        result = dlg.ShowModal()
63#    finally:
64#        dlg.Destroy()
65#    if result == wx.ID_NO: return (0,0)
66#    Temperature = 300
67#   
68#    if '.xye' in filename:      #Topas style xye file (e.g. 2-th, I, sig) - no iparm file/no BANK record
69#        dlg = wx.MessageDialog(G2frame,'''Is this laboratory Cu Ka1/Ka2 data?
70#(No = 0.6A wavelength synchrotron data)
71#Change wavelength in Instrument Parameters if needed''','Data type?',
72#            wx.YES_NO | wx.ICON_QUESTION)
73#        try:
74#            result = dlg.ShowModal()
75#        finally:
76#            dlg.Destroy()
77#        print result
78#        if result == wx.ID_YES:
79#            Iparm = {}                                               #Assume CuKa lab data
80#            Iparm['INS   HTYPE '] = 'PXC '
81#            Iparm['INS  1 ICONS'] = '  1.540500  1.544300       0.0         0       0.7    0       0.5   '
82#            Iparm['INS  1PRCF1 '] = '    3    8      0.01                                                '
83#            Iparm['INS  1PRCF11'] = '   2.000000E+00  -2.000000E+00   5.000000E+00   0.000000E+00        '
84#            Iparm['INS  1PRCF12'] = '   0.000000E+00   0.000000E+00   0.100000E-01   0.100000E-01        '
85#        else:
86#            Iparm = {}                                               #Assume 0.6A synchrotron data
87#            Iparm['INS   HTYPE '] = 'PXC '
88#            Iparm['INS  1 ICONS'] = '  0.600000  0.000000       0.0         0      0.99    0       0.5   '
89#            Iparm['INS  1PRCF1 '] = '    3    8      0.01                                                '
90#            Iparm['INS  1PRCF11'] = '   1.000000E+00  -1.000000E+00   0.300000E+00   0.000000E+00        '
91#            Iparm['INS  1PRCF12'] = '   0.000000E+00   0.000000E+00   0.100000E-02   0.100000E-02        '
92#                       
93#       
94#    else:                       #GSAS style fxye or fxy file (e.g. 100*2-th, I, sig)
95#        G2frame.IparmName = GetInstrumentFile(G2frame,filename)
96#        if G2frame.IparmName:
97#            Iparm = GetInstrumentData(G2frame.IparmName)
98#        else:
99#            Iparm = {}                                               #Assume CuKa lab data if no iparm file
100#            Iparm['INS   HTYPE '] = 'PXC '
101#            Iparm['INS  1 ICONS'] = '  1.540500  1.544300       0.0         0       0.7    0       0.5   '
102#            Iparm['INS  1PRCF1 '] = '    3    8      0.01                                                '
103#            Iparm['INS  1PRCF11'] = '   2.000000E+00  -2.000000E+00   5.000000E+00   0.000000E+00        '
104#            Iparm['INS  1PRCF12'] = '   0.000000E+00   0.000000E+00   0.100000E-01   0.100000E-01        '
105#    S = 1
106#    Banks = []
107#    Pos = []
108#    FoundData = []
109#    Comments = []
110#    wx.BeginBusyCursor()
111#    try:
112#        while S:
113#            S = File.readline()
114#            if S[:1] != '#':
115#                if S[:4] == 'BANK':
116#                    Banks.append(S)
117#                    Pos.append(File.tell())
118#                elif '.xye' in filename:    #No BANK in a xye file
119#                    Banks.append('BANK 1 XYE')
120#                    Pos.append(File.tell())
121#                    break
122#            else:
123#                Comments.append(S[:-1])
124#                if 'Temp' in S.split('=')[0]:
125#                    Temperature = float(S.split('=')[1])
126#        File.close()
127#    finally:
128#        wx.EndBusyCursor()
129#    if Comments:
130#       print 'Comments on file:'
131#       for Comment in Comments: print Comment
132#    if Banks:
133#        result = [0]
134#        if len(Banks) >= 2:
135#            dlg = wx.MultiChoiceDialog(G2frame, 'Which scans do you want?', 'Select scans', Banks, wx.CHOICEDLG_STYLE)
136#            try:
137#                if dlg.ShowModal() == wx.ID_OK:
138#                    result = dlg.GetSelections()
139#                else:
140#                    result = []
141#            finally:
142#                dlg.Destroy()
143#        for i in result:
144#            FoundData.append((filename,Pos[i],Banks[i]))
145#    else:
146#        dlg = wx.MessageDialog(G2frame, 'ERROR - this is not a GSAS powder data file', 'No BANK records', wx.OK | wx.ICON_ERROR)
147#        try:
148#            result = dlg.ShowModal()
149#        finally:
150#            dlg.Destroy()
151#    return FoundData,Iparm,Comments,Temperature
152#
153## to be removed
154#def GetInstrumentFile(G2frame,filename):
155#    import os.path as op
156#    dlg = wx.FileDialog(G2frame,'Choose an instrument file','.', '', 'GSAS iparm file (*.prm)|*.prm|All files(*.*)|*.*',
157#        wx.OPEN|wx.CHANGE_DIR)
158#    Tname = filename[:filename.index('.')]+'.prm'
159#    if op.exists(Tname):
160#        G2frame.IparmName = Tname       
161#    if G2frame.IparmName: dlg.SetFilename(G2frame.IparmName)
162#    filename = ''
163#    try:
164#        if dlg.ShowModal() == wx.ID_OK:
165#            filename = dlg.GetPath()
166#    finally:
167#        dlg.Destroy()
168#    return filename
169#
170## to be removed
171#def GetInstrumentData(IparmName):
172#    file = open(IparmName, 'Ur')
173#    S = 1
174#    Iparm = {}
175#    while S:
176#        S = file.readline()
177#        Iparm[S[:12]] = S[12:-1]
178#    return Iparm
179   
180def GetPowderPeaks(fileName):
181    sind = lambda x: math.sin(x*math.pi/180.)
182    asind = lambda x: 180.*math.asin(x)/math.pi
183    Cuka = 1.54052
184    File = open(fileName,'Ur')
185    Comments = []
186    peaks = []
187    S = File.readline()
188    while S:
189        if S[:1] == '#':
190            Comments.append(S[:-1])
191        else:
192            item = S.split()
193            if len(item) == 1:
194                peaks.append([float(item[0]),1.0])
195            elif len(item) > 1:
196                peaks.append([float(item[0]),float(item[0])])
197        S = File.readline()
198    File.close()
199    if Comments:
200       print 'Comments on file:'
201       for Comment in Comments: print Comment
202    Peaks = []
203    if peaks[0][0] > peaks[-1][0]:          # d-spacings - assume CuKa
204        for peak in peaks:
205            dsp = peak[0]
206            sth = Cuka/(2.0*dsp)
207            if sth < 1.0:
208                tth = 2.0*asind(sth)
209            else:
210                break
211            Peaks.append([tth,peak[1],True,False,0,0,0,dsp,0.0])
212    else:                                   #2-thetas - assume Cuka (for now)
213        for peak in peaks:
214            tth = peak[0]
215            dsp = Cuka/(2.0*sind(tth/2.0))
216            Peaks.append([tth,peak[1],True,False,0,0,0,dsp,0.0])
217    return Comments,Peaks
218
219#def GetPawleyPeaks(filename):   #dead code??
220#    rt2ln2x2 = 2.35482
221#    File = open(filename,'Ur')
222#    PawleyPeaks = []
223#    S = File.readline()         #skip header
224#    S = File.readline()
225#    item = S.split()
226#    while S:
227#        h,k,l = int(item[0]),int(item[1]),int(item[2])
228#        mult = int(item[3])
229#        tth = float(item[5])
230#        sig = float(item[6])/rt2ln2x2
231#        Iobs = float(item[7])*mult
232#        PawleyPeaks.append([h,k,l,mult,tth,False,Iobs,0.0])
233#        S = File.readline()
234#        item = S.split()
235#        if item[3] == '-100.0000':       #find trailer
236#            break
237#    File.close()
238#    return PawleyPeaks
239   
240# this will be removed eventually
241#def GetHKLData(filename):
242#    print 'Reading: '+filename
243#    File = open(filename,'Ur')
244#    HKLref = []
245#    HKLmin = [1000,1000,1000]
246#    HKLmax = [0,0,0]
247#    FoMax = 0
248#    ifFc = False
249#    S = File.readline()
250#    while '#' in S[0]:        #get past comments if any
251#        S = File.readline()       
252#    if '_' in S:         #cif style .hkl file
253#        while 'loop_' not in S:         #skip preliminaries if any - can't have 'loop_' in them!
254#            S = File.readline()       
255#        S = File.readline()             #get past 'loop_' line
256#        pos = 0
257#        hpos = kpos = lpos = Fosqpos = Fcsqpos = sigpos = -1
258#        while S:
259#            if '_' in S:
260#                if 'index_h' in S:
261#                    hpos = pos
262#                elif 'index_k' in S:
263#                    kpos = pos
264#                elif 'index_l' in S:
265#                    lpos = pos
266#                elif 'F_squared_meas' in S:
267#                    Fosqpos = pos
268#                elif 'F_squared_calc' in S:
269#                    Fcsqpos = pos
270#                elif 'F_squared_sigma' in S:
271#                    sigpos = pos
272#                pos += 1
273#            else:
274#                data = S.split()
275#                if data:                    #avoid blank lines
276#                    HKL = np.array([int(data[hpos]),int(data[kpos]),int(data[lpos])])
277#                    h,k,l = HKL
278#                    Fosq = float(data[Fosqpos])
279#                    if sigpos != -1:
280#                        sigFosq = float(data[sigpos])
281#                    else:
282#                        sigFosq = 1.
283#                    if Fcsqpos != -1:
284#                        Fcsq = float(data[Fcsqpos])
285#                        if Fcsq:
286#                            ifFc = True
287#                    else:
288#                        Fcsq = 0.
289#                       
290#                    HKLmin = [min(h,HKLmin[0]),min(k,HKLmin[1]),min(l,HKLmin[2])]
291#                    HKLmax = [max(h,HKLmax[0]),max(k,HKLmax[1]),max(l,HKLmax[2])]
292#                    FoMax = max(FoMax,Fosq)
293#                    HKLref.append([HKL,Fosq,sigFosq,Fcsq,0,0,0])                 #room for Fcp, Fcpp & phase
294#            S = File.readline()
295#    else:                   #dumb h,k,l,Fo,sigFo .hkl file
296#        while S:
297#            h,k,l,Fo,sigFo = S.split()
298#            HKL = np.array([int(h),int(k),int(l)])
299#            h,k,l = HKL
300#            Fo = float(Fo)
301#            sigFo = float(sigFo)
302#            HKLmin = [min(h,HKLmin[0]),min(k,HKLmin[1]),min(l,HKLmin[2])]
303#            HKLmax = [max(h,HKLmax[0]),max(k,HKLmax[1]),max(l,HKLmax[2])]
304#            FoMax = max(FoMax,Fo)
305#            HKLref.append([HKL,Fo**2,2.*Fo*sigFo,0,0,0,0])                 #room for Fc, Fcp, Fcpp & phase
306#            S = File.readline()
307#    File.close()
308#    return HKLref,HKLmin,HKLmax,FoMax,ifFc
309
310## to be removed
311#def GetPowderData(filename,Pos,Bank,DataType):
312#    '''Reads one BANK of data from GSAS raw powder data file
313#    input:
314#    filename: GSAS raw powder file dataname
315#    Pos: start of data in file just after BANK record
316#    Bank: the BANK record
317#    DataType: powder data type, e.g. "PXC" for Powder X-ray CW data
318#    returns: list [x,y,e,yc,yb]
319#    x: np.array of x-axis values
320#    y: np.array of powder pattern intensities
321#    w: np.array of w=sig(intensity)^2 values
322#    yc: np.array of calc. intensities (zero)
323#    yb: np.array of calc. background (zero)
324#    yd: np.array of obs-calc profiles
325#    '''
326#    print 'Reading: '+filename
327#    print 'Bank:    '+Bank[:-1]
328#    if 'FXYE' in Bank:
329#        return GetFXYEdata(filename,Pos,Bank,DataType)
330#    elif ' XYE' in Bank:
331#        return GetXYEdata(filename,Pos,Bank,DataType)
332#    elif 'FXY' in Bank:
333#        return GetFXYdata(filename,Pos,Bank,DataType)
334#    elif 'ESD' in Bank:
335#        return GetESDdata(filename,Pos,Bank,DataType)
336#    elif 'STD' in Bank:
337#        return GetSTDdata(filename,Pos,Bank,DataType)
338#    else:
339#        return GetSTDdata(filename,Pos,Bank,DataType)
340#    return []
341#
342## to be removed
343#def GetFXYEdata(filename,Pos,Bank,DataType):
344#    File = open(filename,'Ur')
345#    File.seek(Pos)
346#    x = []
347#    y = []
348#    w = []
349#    S = File.readline()
350#    while S and S[:4] != 'BANK':
351#        vals = S.split()
352#        if DataType[2] == 'C':
353#            x.append(float(vals[0])/100.)               #CW: from centidegrees to degrees
354#        elif DataType[2] == 'T':
355#            x.append(float(vals[0])/1000.0)             #TOF: from musec to millisec
356#        f = float(vals[1])
357#        if f <= 0.0:
358#            y.append(0.0)
359#            w.append(1.0)
360#        else:
361#            y.append(float(vals[1]))
362#            w.append(1.0/float(vals[2])**2)
363#        S = File.readline()
364#    File.close()
365#    N = len(x)
366#    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
367#   
368## to be removed
369#def GetXYEdata(filename,Pos,Bank,DataType):
370#    File = open(filename,'Ur')
371#    File.seek(Pos)
372#    x = []
373#    y = []
374#    w = []
375#    S = File.readline()
376#    while S:
377#        vals = S.split()
378#        try:
379#            x.append(float(vals[0]))
380#            f = float(vals[1])
381#            if f <= 0.0:
382#                y.append(0.0)
383#                w.append(1.0)
384#            else:
385#                y.append(float(vals[1]))
386#                w.append(1.0/float(vals[2])**2)
387#            S = File.readline()
388#        except ValueError:
389#            break
390#    File.close()
391#    N = len(x)
392#    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
393#   
394#   
395## to be removed
396#def GetFXYdata(filename,Pos,Bank,DataType):
397#    File = open(filename,'Ur')
398#    File.seek(Pos)
399#    x = []
400#    y = []
401#    w = []
402#    S = File.readline()
403#    while S and S[:4] != 'BANK':
404#        vals = S.split()
405#        if DataType[2] == 'C':
406#            x.append(float(vals[0])/100.)               #CW: from centidegrees to degrees
407#        elif DataType[2] == 'T':
408#            x.append(float(vals[0])/1000.0)             #TOF: from musec to millisec
409#        f = float(vals[1])
410#        if f > 0.0:
411#            y.append(f)
412#            w.append(1.0/f)
413#        else:             
414#            y.append(0.0)
415#            w.append(1.0)
416#        S = File.readline()
417#    File.close()
418#    N = len(x)
419#    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
420#   
421## to be removed
422#def GetESDdata(filename,Pos,Bank,DataType):
423#    File = open(filename,'Ur')
424#    cons = Bank.split()
425#    if DataType[2] == 'C':
426#        start = float(cons[5])/100.0               #CW: from centidegrees to degrees
427#        step = float(cons[6])/100.0
428#    elif DataType[2] == 'T':
429#        start = float(cons[5])/1000.0              #TOF: from musec to millisec
430#        step = float(cons[6])/1000.0
431#    File.seek(Pos)
432#    x = []
433#    y = []
434#    w = []
435#    S = File.readline()
436#    j = 0
437#    while S and S[:4] != 'BANK':
438#        for i in range(0,80,16):
439#            xi = start+step*j
440#            yi = sfloat(S[i:i+8])
441#            ei = sfloat(S[i+8:i+16])
442#            x.append(xi)
443#            if yi > 0.0:
444#                y.append(yi)
445#                w.append(1.0/ei**2)
446#            else:             
447#                y.append(0.0)
448#                w.append(1.0)
449#            j += 1
450#        S = File.readline()
451#    File.close()
452#    N = len(x)
453#    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
454#
455## to be removed
456#def GetSTDdata(filename,Pos,Bank,DataType):
457#    File = open(filename,'Ur')
458#    cons = Bank.split()
459#    Nch = int(cons[2])
460#    if DataType[2] == 'C':
461#        start = float(cons[5])/100.0               #CW: from centidegrees to degrees
462#        step = float(cons[6])/100.0
463#    elif DataType[2] == 'T':
464#        start = float(cons[5])/1000.0              #TOF: from musec to millisec - not likely!
465#        step = float(cons[6])/1000.0
466#    File.seek(Pos)
467#    x = []
468#    y = []
469#    w = []
470#    S = File.readline()
471#    j = 0
472#    while S and S[:4] != 'BANK':
473#        for i in range(0,80,8):
474#            xi = start+step*j
475#            ni = max(sint(S[i:i+2]),1)
476#            yi = max(sfloat(S[i+2:i+8]),0.0)
477#            if yi:
478#                vi = yi/ni
479#            else:
480#                yi = 0.0
481#                vi = 1.0
482#            j += 1
483#            if j < Nch:
484#                x.append(xi)
485#                y.append(yi)
486#                w.append(1.0/vi)
487#        S = File.readline()
488#    File.close()
489#    N = len(x)
490#    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
491   
492def CheckImageFile(G2frame,imagefile):
493    if not ospath.exists(imagefile):
494        dlg = wx.FileDialog(G2frame, 'Bad image file name; choose name', '.', '',\
495        'Any image file (*.tif;*.tiff;*.mar*;*.avg;*.sum;*.img)\
496        |*.tif;*.tiff;*.mar*;*.avg;*.sum;*.img|\
497        Any detector tif (*.tif;*.tiff)|*.tif;*.tiff|\
498        MAR file (*.mar*)|*.mar*|\
499        GE Image (*.avg;*.sum)|*.avg;*.sum|\
500        ADSC Image (*.img)|*.img|\
501        All files (*.*)|*.*',wx.OPEN|wx.CHANGE_DIR)
502        try:
503            dlg.SetFilename(''+ospath.split(imagefile)[1])
504            if dlg.ShowModal() == wx.ID_OK:
505                imagefile = dlg.GetPath()
506            else:
507                imagefile = False
508        finally:
509            dlg.Destroy()
510    return imagefile
511       
512def GetImageData(G2frame,imagefile,imageOnly=False):       
513    ext = ospath.splitext(imagefile)[1]
514    Comments = []
515    if ext == '.tif' or ext == '.tiff':
516        Comments,Data,Npix,Image = GetTifData(imagefile)
517    elif ext == '.img':
518        Comments,Data,Npix,Image = GetImgData(imagefile)
519        Image[0][0] = 0
520    elif ext == '.mar3450' or ext == '.mar2300':
521        Comments,Data,Npix,Image = GetMAR345Data(imagefile)
522    elif ext in ['.sum','.avg','']:
523        Comments,Data,Npix,Image = GetGEsumData(imagefile)
524    elif ext == '.G2img':
525        Comments,Data,Npix,Image = GetG2Image(imagefile)
526    if imageOnly:
527        return Image
528    else:
529        return Comments,Data,Npix,Image
530       
531def PutG2Image(filename,Comments,Data,Npix,image):
532    File = open(filename,'wb')
533    cPickle.dump([Comments,Data,Npix,image],File,1)
534    File.close()
535    return
536   
537def GetG2Image(filename):
538    File = open(filename,'rb')
539    Comments,Data,Npix,image = cPickle.load(File)
540    File.close()
541    return Comments,Data,Npix,image
542   
543def GetGEsumData(filename,imageOnly=False):
544    import struct as st
545    import array as ar
546    if not imageOnly:
547        print 'Read GE sum file: ',filename   
548    File = open(filename,'rb')
549    if '.sum' in filename:
550        head = ['GE detector sum data from APS 1-ID',]
551        sizexy = [2048,2048]
552    elif '.avg' in filename:
553        head = ['GE detector avg data from APS 1-ID',]
554        sizexy = [2048,2048]
555    else:
556        head = ['GE detector raw data from APS 1-ID',]
557        File.seek(18)
558        size,nframes = st.unpack('<ih',File.read(6))
559        sizexy = [2048,2048]
560        pos = 8192
561        File.seek(pos)
562    Npix = sizexy[0]*sizexy[1]
563    if '.sum' in filename:
564        image = np.array(ar.array('f',File.read(4*Npix)),dtype=np.int32)
565    elif '.avg' in filename:
566        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
567    else:
568        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
569        while nframes > 1:
570            image += np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
571            nframes -= 1
572    image = np.reshape(image,(sizexy[1],sizexy[0]))
573    data = {'pixelSize':(200,200),'wavelength':0.15,'distance':250.0,'center':[204.8,204.8],'size':sizexy} 
574    File.close()   
575    if imageOnly:
576        return image
577    else:
578        return head,data,Npix,image
579       
580def GetImgData(filename,imageOnly=False):
581    import struct as st
582    import array as ar
583    if not imageOnly:
584        print 'Read ADSC img file: ',filename
585    File = open(filename,'rb')
586    head = File.read(511)
587    lines = head.split('\n')
588    head = []
589    center = [0,0]
590    for line in lines[1:-2]:
591        line = line.strip()[:-1]
592        if line:
593            if 'SIZE1' in line:
594                size = int(line.split('=')[1])
595                Npix = size*size
596            elif 'WAVELENGTH' in line:
597                wave = float(line.split('=')[1])
598            elif 'BIN' in line:
599                if line.split('=')[1] == '2x2':
600                    pixel=(102,102)
601                else:
602                    pixel = (51,51)
603            elif 'DISTANCE' in line:
604                distance = float(line.split('=')[1])
605            elif 'CENTER_X' in line:
606                center[0] = float(line.split('=')[1])
607            elif 'CENTER_Y' in line:
608                center[1] = float(line.split('=')[1])
609            head.append(line)
610    data = {'pixelSize':pixel,'wavelength':wave,'distance':distance,'center':center,'size':[size,size]}
611    image = []
612    row = 0
613    pos = 512
614    File.seek(pos)
615    image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
616    image = np.reshape(image,(sizexy[1],sizexy[0]))
617#    image = np.zeros(shape=(size,size),dtype=np.int32)   
618#    while row < size:
619#        File.seek(pos)
620#        line = ar.array('H',File.read(2*size))
621#        image[row] = np.asarray(line)
622#        row += 1
623#        pos += 2*size
624    File.close()
625    if imageOnly:
626        return image
627    else:
628        return lines[1:-2],data,Npix,image
629       
630def GetMAR345Data(filename,imageOnly=False):
631    import array as ar
632    import struct as st
633    try:
634        import pack_f as pf
635    except:
636        msg = wx.MessageDialog(None, message="Unable to load the GSAS MAR image decompression, pack_f",
637                               caption="Import Error",
638                               style=wx.ICON_ERROR | wx.OK | wx.STAY_ON_TOP)
639        msg.ShowModal()
640        return None,None,None,None
641
642    if not imageOnly:
643        print 'Read Mar345 file: ',filename
644    File = open(filename,'rb')
645    head = File.read(4095)
646    numbers = st.unpack('<iiiiiiiiii',head[:40])
647    lines = head[128:].split('\n')
648    head = []
649    for line in lines:
650        line = line.strip()
651        if 'PIXEL' in line:
652            values = line.split()
653            pixel = (int(values[2]),int(values[4]))     #in microns
654        elif 'WAVELENGTH' in line:
655            wave = float(line.split()[1])
656        elif 'DISTANCE' in line:
657            distance = float(line.split()[1])           #in mm
658        elif 'CENTER' in line:
659            values = line.split()
660            center = [float(values[2])/10.,float(values[4])/10.]    #make in mm from pixels
661        if line: 
662            head.append(line)
663    data = {'pixelSize':pixel,'wavelength':wave,'distance':distance,'center':center}
664    for line in head:
665        if 'FORMAT' in line[0:6]:
666            items = line.split()
667            size = int(items[1])
668            Npix = size*size
669    pos = 4096
670    data['size'] = [size,size]
671    File.seek(pos)
672    line = File.read(8)
673    while 'CCP4' not in line:       #get past overflow list for now
674        line = File.read(8)
675        pos += 8
676    pos += 37
677    File.seek(pos)
678    raw = File.read()
679    File.close()
680    image = np.zeros(shape=(size,size),dtype=np.int32)
681    image = pf.pack_f(len(raw),raw,size,image)
682    if imageOnly:
683        return image.T              #transpose to get it right way around
684    else:
685        return head,data,Npix,image.T
686       
687def GetTifData(filename,imageOnly=False):
688    import struct as st
689    import array as ar
690    File = open(filename,'rb')
691    dataType = 5
692    try:
693        Meta = open(filename+'.metadata','Ur')
694        head = Meta.readlines()
695        for line in head:
696            line = line.strip()
697            if 'dataType=' in line:
698                dataType = int(line.split('=')[1])
699        Meta.close()
700    except IOError:
701        print 'no metadata file found - will try to read file anyway'
702        head = ['no metadata file found',]
703       
704    tag = File.read(2)
705    byteOrd = '<'
706    if tag == 'II' and int(st.unpack('<h',File.read(2))[0]) == 42:     #little endian
707        IFD = int(st.unpack(byteOrd+'i',File.read(4))[0])
708    elif tag == 'MM' and int(st.unpack('>h',File.read(2))[0]) == 42:   #big endian
709        byteOrd = '>'
710        IFD = int(st.unpack(byteOrd+'i',File.read(4))[0])       
711    else:
712        lines = ['not a detector tiff file',]
713        return lines,0,0,0
714    File.seek(IFD)                                                  #get number of directory entries
715    NED = int(st.unpack(byteOrd+'h',File.read(2))[0])
716    IFD = {}
717    for ied in range(NED):
718        Tag,Type = st.unpack(byteOrd+'Hh',File.read(4))
719        nVal = st.unpack(byteOrd+'i',File.read(4))[0]
720        if Type == 1:
721            Value = st.unpack(byteOrd+nVal*'b',File.read(nVal))
722        elif Type == 2:
723            Value = st.unpack(byteOrd+'i',File.read(4))
724        elif Type == 3:
725            Value = st.unpack(byteOrd+nVal*'h',File.read(nVal*2))
726            x = st.unpack(byteOrd+nVal*'h',File.read(nVal*2))
727        elif Type == 4:
728            Value = st.unpack(byteOrd+nVal*'i',File.read(nVal*4))
729        elif Type == 5:
730            Value = st.unpack(byteOrd+nVal*'i',File.read(nVal*4))
731        elif Type == 11:
732            Value = st.unpack(byteOrd+nVal*'f',File.read(nVal*4))
733        IFD[Tag] = [Type,nVal,Value]
734#    for key in IFD:
735#        print key,IFD[key]
736    sizexy = [IFD[256][2][0],IFD[257][2][0]]
737    [nx,ny] = sizexy
738    Npix = nx*ny
739    if 272 in IFD:
740        ifd = IFD[272]
741        File.seek(ifd[2][0])
742        S = File.read(ifd[1])
743        if 'PILATUS' in S:
744            tifType = 'Pilatus'
745            dataType = 0
746            pixy = (172,172)
747            File.seek(4096)
748            if not imageOnly:
749                print 'Read Pilatus tiff file: ',filename
750            image = ar.array('L',File.read(4*Npix))
751            image = np.array(np.asarray(image),dtype=np.int32)
752    elif 262 in IFD and IFD[262][2][0] > 4:
753        tifType = 'DND'
754        pixy = (158,158)
755        File.seek(512)
756        if not imageOnly:
757            print 'Read DND SAX/WAX-detector tiff file: ',filename
758        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
759    elif sizexy == [1536,1536]:
760        tifType = 'APS Gold'
761        pixy = (150,150)
762        File.seek(64)
763        if not imageOnly:
764            print 'Read Gold tiff file:',filename
765        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
766    elif sizexy == [2048,2048] or sizexy == [1024,1024]:
767        if IFD[273][2][0] == 8:
768            if IFD[258][2][0] == 32:
769                tifType = 'PE'
770                pixy = (200,200)
771                File.seek(8)
772                if not imageOnly:
773                    print 'Read APS PE-detector tiff file: ',filename
774                if dataType == 5:
775                    image = np.array(ar.array('f',File.read(4*Npix)),dtype=np.float32)
776                else:
777                    image = np.array(ar.array('I',File.read(4*Npix)),dtype=np.int32)
778        elif IFD[273][2][0] == 4096:
779            tifType = 'MAR'
780            pixy = (158,158)
781            File.seek(4096)
782            if not imageOnly:
783                print 'Read MAR CCD tiff file: ',filename
784            image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
785    elif sizexy == [4096,4096]:
786        if IFD[273][2][0] == 8:
787            if IFD[258][2][0] == 16:
788                tifType = 'scanCCD'
789                pixy = (9,9)
790                File.seek(8)
791                if not imageOnly:
792                    print 'Read APS scanCCD tiff file: ',filename
793                image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
794#    elif sizexy == [960,960]:
795#        tiftype = 'PE-BE'
796#        pixy = (200,200)
797#        File.seek(8)
798#        if not imageOnly:
799#            print 'Read Gold tiff file:',filename
800#        image = np.array(ar.array('H',File.read(2*Npix)),dtype=np.int32)
801           
802    else:
803        lines = ['not a known detector tiff file',]
804        return lines,0,0,0
805       
806    image = np.reshape(image,(sizexy[1],sizexy[0]))
807    center = [pixy[0]*sizexy[0]/2000,pixy[1]*sizexy[1]/2000]
808    data = {'pixelSize':pixy,'wavelength':0.10,'distance':100.0,'center':center,'size':sizexy}
809    File.close()   
810    if imageOnly:
811        return image
812    else:
813        return head,data,Npix,image
814   
815def ProjFileOpen(G2frame):
816    file = open(G2frame.GSASprojectfile,'rb')
817    print 'load from file: ',G2frame.GSASprojectfile
818    wx.BeginBusyCursor()
819    try:
820        while True:
821            try:
822                data = cPickle.load(file)
823            except EOFError:
824                break
825            datum = data[0]
826           
827            Id = G2frame.PatternTree.AppendItem(parent=G2frame.root,text=datum[0])
828            if 'PWDR' in datum[0]:               
829                G2frame.PatternTree.SetItemPyData(Id,datum[1][:3])     #temp. trim off junk
830            else:
831                G2frame.PatternTree.SetItemPyData(Id,datum[1])
832            for datus in data[1:]:
833                sub = G2frame.PatternTree.AppendItem(Id,datus[0])
834                G2frame.PatternTree.SetItemPyData(sub,datus[1])
835            if 'IMG' in datum[0]:                   #retrieve image default flag & data if set
836                Data = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Image Controls'))
837                if Data['setDefault']:
838                    G2frame.imageDefault = Data               
839        file.close()
840       
841    finally:
842        wx.EndBusyCursor()
843    print 'project load successful'
844    G2frame.NewPlot = True
845   
846def ProjFileSave(G2frame):
847    if not G2frame.PatternTree.IsEmpty():
848        file = open(G2frame.GSASprojectfile,'wb')
849        print 'save to file: ',G2frame.GSASprojectfile
850        wx.BeginBusyCursor()
851        try:
852            item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
853            while item:
854                data = []
855                name = G2frame.PatternTree.GetItemText(item)
856                data.append([name,G2frame.PatternTree.GetItemPyData(item)])
857                item2, cookie2 = G2frame.PatternTree.GetFirstChild(item)
858                while item2:
859                    name = G2frame.PatternTree.GetItemText(item2)
860                    data.append([name,G2frame.PatternTree.GetItemPyData(item2)])
861                    item2, cookie2 = G2frame.PatternTree.GetNextChild(item, cookie2)                           
862                item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)                           
863                cPickle.dump(data,file,1)
864            file.close()
865        finally:
866            wx.EndBusyCursor()
867        print 'project save successful'
868
869def SaveIntegration(G2frame,PickId,data):
870    azms = G2frame.Integrate[1]
871    X = G2frame.Integrate[2][:-1]
872    Xminmax = [X[0],X[-1]]
873    N = len(X)
874    Id = G2frame.PatternTree.GetItemParent(PickId)
875    name = G2frame.PatternTree.GetItemText(Id)
876    name = name.replace('IMG ','PWDR ')
877    Comments = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id, 'Comments'))
878    names = ['Type','Lam','Zero','Polariz.','U','V','W','X','Y','SH/L','Azimuth'] 
879    codes = [0 for i in range(11)]
880    LRazm = data['LRazimuth']
881    Azms = []
882    if data['fullIntegrate'] and data['outAzimuths'] == 1:
883        Azms = [45.0,]                              #a poor man's average?
884    else:
885        for i,azm in enumerate(azms[:-1]):
886            Azms.append((azms[i+1]+azm)/2.)
887    for i,azm in enumerate(azms[:-1]):
888        item, cookie = G2frame.PatternTree.GetFirstChild(G2frame.root)
889        Id = 0
890        while item:
891            Name = G2frame.PatternTree.GetItemText(item)
892            if name == Name:
893                Id = item
894            item, cookie = G2frame.PatternTree.GetNextChild(G2frame.root, cookie)
895        parms = ['PXC',data['wavelength'],0.0,0.99,1.0,-0.10,0.4,0.30,1.0,0.0001,Azms[i]]    #set polarization for synchrotron radiation!
896        Y = G2frame.Integrate[0][i]
897        W = 1./Y                    #probably not true
898        Sample = G2pdG.SetDefaultSample()
899        if Id:
900            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id, 'Comments'),Comments)                   
901            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Limits'),[tuple(Xminmax),Xminmax])
902            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Background'),[['chebyschev',1,3,1.0,0.0,0.0],
903                            {'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]}])
904            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Instrument Parameters'),[tuple(parms),parms[:],codes,names])
905            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Peak List'),[])
906            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Index Peak List'),[])
907            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Unit Cells List'),[])             
908            G2frame.PatternTree.SetItemPyData(G2gd.GetPatternTreeItemId(G2frame,Id,'Reflection Lists'),{})             
909        else:
910            Id = G2frame.PatternTree.AppendItem(parent=G2frame.root,text=name+" Azm= %.2f"%(Azms[i]))
911            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Comments'),Comments)                   
912            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Limits'),[tuple(Xminmax),Xminmax])
913            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Background'),[['chebyschev',1,3,1.0,0.0,0.0],
914                            {'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]}])
915            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Instrument Parameters'),[tuple(parms),parms[:],codes,names])
916            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Sample Parameters'),Sample)
917            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Peak List'),[])
918            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Index Peak List'),[])
919            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Unit Cells List'),[])
920            G2frame.PatternTree.SetItemPyData(G2frame.PatternTree.AppendItem(Id,text='Reflection Lists'),{})             
921        G2frame.PatternTree.SetItemPyData(Id,[[''],[np.array(X),np.array(Y),np.array(W),np.zeros(N),np.zeros(N),np.zeros(N)]])
922    G2frame.PatternTree.SelectItem(Id)
923    G2frame.PatternTree.Expand(Id)
924    G2frame.PatternId = Id
925           
926def powderFxyeSave(G2frame,exports,powderfile):
927    head,tail = ospath.split(powderfile)
928    name,ext = tail.split('.')
929    for i,export in enumerate(exports):
930        filename = ospath.join(head,name+'-%03d.'%(i)+ext)
931        prmname = filename.strip(ext)+'prm'
932        prm = open(prmname,'w')      #old style GSAS parm file
933        PickId = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, export)
934        Values,Names = G2frame.PatternTree.GetItemPyData(G2gd.GetPatternTreeItemId(G2frame, \
935            PickId, 'Instrument Parameters'))[1::2]     #get values & names
936        Inst = dict(zip(Names,Values))
937        print Inst['Type']
938        prm.write( '            123456789012345678901234567890123456789012345678901234567890        '+'\n')
939        prm.write( 'INS   BANK      1                                                               '+'\n')
940        prm.write(('INS   HTYPE   %sR                                                              '+'\n')%(Inst['Type']))
941        if 'Lam1' in Inst:              #Ka1 & Ka2
942            prm.write(('INS  1 ICONS%10.7f%10.7f    0.0000               0.990    0     0.500   '+'\n')%(Inst['Lam1'],Inst['Lam2']))
943        elif 'Lam' in Inst:             #single wavelength
944            prm.write(('INS  1 ICONS%10.7f%10.7f    0.0000               0.990    0     0.500   '+'\n')%(Inst['Lam'],0.0))
945        prm.write( 'INS  1 IRAD     0                                                               '+'\n')
946        prm.write( 'INS  1I HEAD                                                                    '+'\n')
947        prm.write( 'INS  1I ITYP    0    0.0000  180.0000         1                                 '+'\n')
948        prm.write(('INS  1DETAZM%10.3f                                                          '+'\n')%(Inst['Azimuth']))
949        prm.write( 'INS  1PRCF1     3    8   0.00100                                                '+'\n')
950        prm.write(('INS  1PRCF11     %15.6g%15.6g%15.6g%15.6g   '+'\n')%(Inst['U'],Inst['V'],Inst['W'],0.0))
951        prm.write(('INS  1PRCF12     %15.6g%15.6g%15.6g%15.6g   '+'\n')%(Inst['X'],Inst['Y'],Inst['SH/L']/2.,Inst['SH/L']/2.))
952        prm.close()
953        file = open(filename,'w')
954        print 'save powder pattern to file: ',filename
955        x,y,w,yc,yb,yd = G2frame.PatternTree.GetItemPyData(PickId)[1]
956        file.write(powderfile+'\n')
957        file.write('Instrument parameter file:'+ospath.split(prmname)[1]+'\n')
958        file.write('BANK 1 %d %d CONS %.2f %.2f 0 0 FXYE\n'%(len(x),len(x),\
959            100.*x[0],100.*(x[1]-x[0])))
960        s = list(np.sqrt(1./np.array(w)))       
961        XYW = zip(x,y,s)
962        for X,Y,S in XYW:
963            file.write("%15.6g %15.6g %15.6g\n" % (100.*X,Y,max(S,1.0)))
964        file.close()
965        print 'powder pattern file '+filename+' written'
966       
967def powderXyeSave(G2frame,exports,powderfile):
968    head,tail = ospath.split(powderfile)
969    name,ext = tail.split('.')
970    for i,export in enumerate(exports):
971        filename = ospath.join(head,name+'-%03d.'%(i)+ext)
972        PickId = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, export)
973        file = open(filename,'w')
974        file.write('#%s\n'%(export))
975        print 'save powder pattern to file: ',filename
976        x,y,w,yc,yb,yd = G2frame.PatternTree.GetItemPyData(PickId)[1]
977        s = list(np.sqrt(1./np.array(w)))       
978        XYW = zip(x,y,s)
979        for X,Y,W in XYW:
980            file.write("%15.6g %15.6g %15.6g\n" % (X,Y,W))
981        file.close()
982        print 'powder pattern file '+filename+' written'
983       
984def PDFSave(G2frame,exports):   
985    for export in exports:
986        PickId = G2gd.GetPatternTreeItemId(G2frame, G2frame.root, export)
987        SQname = 'S(Q)'+export[4:]
988        GRname = 'G(R)'+export[4:]
989        sqfilename = ospath.join(G2frame.dirname,export.replace(' ','_')[5:]+'.sq')
990        grfilename = ospath.join(G2frame.dirname,export.replace(' ','_')[5:]+'.gr')
991        sqId = G2gd.GetPatternTreeItemId(G2frame, PickId, SQname)
992        grId = G2gd.GetPatternTreeItemId(G2frame, PickId, GRname)
993        sqdata = np.array(G2frame.PatternTree.GetItemPyData(sqId)[1][:2]).T
994        grdata = np.array(G2frame.PatternTree.GetItemPyData(grId)[1][:2]).T
995        sqfile = open(sqfilename,'w')
996        grfile = open(grfilename,'w')
997        sqfile.write('#T S(Q) %s\n'%(export))
998        grfile.write('#T G(R) %s\n'%(export))
999        sqfile.write('#L Q     S(Q)\n')
1000        grfile.write('#L R     G(R)\n')
1001        for q,sq in sqdata:
1002            sqfile.write("%15.6g %15.6g\n" % (q,sq))
1003        sqfile.close()
1004        for r,gr in grdata:
1005            grfile.write("%15.6g %15.6g\n" % (r,gr))
1006        grfile.close()
1007   
1008def PeakListSave(G2frame,file,peaks):
1009    print 'save peak list to file: ',G2frame.peaklistfile
1010    if not peaks:
1011        dlg = wx.MessageDialog(G2frame, 'No peaks!', 'Nothing to save!', wx.OK)
1012        try:
1013            result = dlg.ShowModal()
1014        finally:
1015            dlg.Destroy()
1016        return
1017    for peak in peaks:
1018        file.write("%10.4f %12.2f %10.3f %10.3f \n" % \
1019            (peak[0],peak[2],peak[4],peak[6]))
1020    print 'peak list saved'
1021             
1022def IndexPeakListSave(G2frame,peaks):
1023    file = open(G2frame.peaklistfile,'wa')
1024    print 'save index peak list to file: ',G2frame.peaklistfile
1025    wx.BeginBusyCursor()
1026    try:
1027        if not peaks:
1028            dlg = wx.MessageDialog(G2frame, 'No peaks!', 'Nothing to save!', wx.OK)
1029            try:
1030                result = dlg.ShowModal()
1031            finally:
1032                dlg.Destroy()
1033            return
1034        for peak in peaks:
1035            file.write("%12.6f\n" % (peak[7]))
1036        file.close()
1037    finally:
1038        wx.EndBusyCursor()
1039    print 'index peak list saved'
1040   
1041def SetNewPhase(Name='New Phase',SGData=G2spc.SpcGroup('P 1')[1],cell=[1.0,1.0,1.0,90.,90,90.,1.]):
1042    phaseData = {
1043        'General':{
1044            'Name':Name,
1045            'Type':'nuclear',
1046            'SGData':SGData,
1047            'Cell':[False,]+cell,
1048            'Pawley dmin':1.0,
1049            'Data plot type':'None',
1050            'SH Texture':{
1051                'Order':0,
1052                'Model':'cylindrical',
1053                'Sample omega':[False,0.0],
1054                'Sample chi':[False,0.0],
1055                'Sample phi':[False,0.0],
1056                'SH Coeff':[False,{}],
1057                'SHShow':False,
1058                'PFhkl':[0,0,1],
1059                'PFxyz':[0,0,1],
1060                'PlotType':'Pole figure'}},
1061        'Atoms':[],
1062        'Drawing':{},
1063        'Histograms':{},
1064        'Pawley ref':[],
1065        'Models':{},
1066        }
1067    return phaseData
1068   
1069def ReadEXPPhase(G2frame,filename):
1070    shModels = ['cylindrical','none','shear - 2/m','rolling - mmm']
1071    textureData = {'Order':0,'Model':'cylindrical','Sample omega':[False,0.0],
1072        'Sample chi':[False,0.0],'Sample phi':[False,0.0],'SH Coeff':[False,{}],
1073        'SHShow':False,'PFhkl':[0,0,1],'PFxyz':[0,0,1],'PlotType':'Pole figure'}
1074    shNcof = 0
1075    file = open(filename, 'Ur')
1076    S = 1
1077    Expr = [{},{},{},{},{},{},{},{},{}]
1078    while S:
1079        S = file.readline()
1080        if 'EXPR NPHAS' in S[:12]:
1081            Num = S[12:-1].count('0')
1082            NPhas = S[12:-1].split()
1083        if 'CRS' in S[:3]:
1084            N = int(S[3:4])-1
1085            Expr[N][S[:12]] = S[12:-1]
1086    file.close()
1087    PNames = []
1088    for n,N in enumerate(NPhas):
1089        if N != '0':
1090            result = n
1091            key = 'CRS'+str(n+1)+'    PNAM'
1092            PNames.append(Expr[n][key])
1093    if Num < 8:
1094        dlg = wx.SingleChoiceDialog(G2frame, 'Which phase to read?', 'Read phase data', PNames, wx.CHOICEDLG_STYLE)
1095        try:
1096            if dlg.ShowModal() == wx.ID_OK:
1097                result = dlg.GetSelection()
1098        finally:
1099            dlg.Destroy()       
1100    EXPphase = Expr[result]
1101    keyList = EXPphase.keys()
1102    keyList.sort()
1103    SGData = {}
1104    if NPhas[result] == '1':
1105        Ptype = 'nuclear'
1106    elif NPhas[result] in ['2','3']:
1107        Ptype = 'magnetic'
1108    elif NPhas[result] == '4':
1109        Ptype = 'macromolecular'
1110    elif NPhas[result] == '10':
1111        Ptype = 'Pawley'
1112    for key in keyList:
1113        if 'PNAM' in key:
1114           PhaseName = EXPphase[key].strip()
1115        elif 'ABC   ' in key:
1116            abc = [float(EXPphase[key][:10]),float(EXPphase[key][10:20]),float(EXPphase[key][20:30])]                       
1117        elif 'ANGLES' in key:
1118            angles = [float(EXPphase[key][:10]),float(EXPphase[key][10:20]),float(EXPphase[key][20:30])]                                               
1119        elif 'SG SYM' in key:
1120            SpGrp = EXPphase[key][:15].strip()
1121            E,SGData = G2spc.SpcGroup(SpGrp)
1122        elif 'OD    ' in key:
1123            SHdata = EXPphase[key].split() # may not have all 9 values
1124            SHvals = 9*[0]
1125            for i in range(9):
1126                try:
1127                    float(SHdata[i])
1128                    SHvals[i] = SHdata[i]
1129                except:
1130                    pass
1131            textureData['Order'] = int(SHvals[0])
1132            textureData['Model'] = shModels[int(SHvals[2])]
1133            textureData['Sample omega'] = [False,float(SHvals[6])]
1134            textureData['Sample chi'] = [False,float(SHvals[7])]
1135            textureData['Sample phi'] = [False,float(SHvals[8])]
1136            shNcof = int(SHvals[1])
1137    Atoms = []
1138    if Ptype == 'nuclear':
1139        for key in keyList:
1140            if 'AT' in key:
1141                if key[11:] == 'A':
1142                    S = EXPphase[key]
1143                elif key[11:] == 'B':
1144                    S += EXPphase[key]
1145                    Atom = [S[50:58].strip(),S[:10].strip(),'',
1146                        float(S[10:20]),float(S[20:30]),float(S[30:40]),
1147                        float(S[40:50]),'',int(S[60:62]),S[130:131]]
1148                    if Atom[9] == 'I':
1149                        Atom += [float(S[68:78]),0.,0.,0.,0.,0.,0.]
1150                    elif Atom[9] == 'A':
1151                        Atom += [0.0,float(S[68:78]),float(S[78:88]),
1152                            float(S[88:98]),float(S[98:108]),
1153                            float(S[108:118]),float(S[118:128])]
1154                    XYZ = Atom[3:6]
1155                    Atom[7],Atom[8] = G2spc.SytSym(XYZ,SGData)
1156                    Atom.append(ran.randint(0,sys.maxint))
1157                    Atoms.append(Atom)
1158    elif Ptype == 'macromolecular':
1159        for key in keyList:
1160            if 'AT' in key[6:8]:
1161                S = EXPphase[key]
1162                Atom = [S[56:60],S[50:54].strip().upper(),S[54:56],
1163                    S[46:51].strip(),S[:8].strip(),'',
1164                    float(S[16:24]),float(S[24:32]),float(S[32:40]),
1165                    float(S[8:16]),'1',1,'I',float(S[40:46]),0,0,0,0,0,0]
1166                XYZ = Atom[6:9]
1167                Atom[10],Atom[11] = G2spc.SytSym(XYZ,SGData)
1168                Atom.append(ran.randint(0,sys.maxint))
1169                Atoms.append(Atom)
1170    Volume = G2lat.calc_V(G2lat.cell2A(abc+angles))
1171    if shNcof:
1172        shCoef = {}
1173        nRec = [i+1 for i in range((shNcof-1)/6+1)]
1174        for irec in nRec:
1175            ODkey = keyList[0][:6]+'OD'+'%3dA'%(irec)
1176            indx = EXPphase[ODkey].split()
1177            ODkey = ODkey[:-1]+'B'
1178            vals = EXPphase[ODkey].split()
1179            for i,val in enumerate(vals):
1180                key = 'C(%s,%s,%s)'%(indx[3*i],indx[3*i+1],indx[3*i+2])
1181                shCoef[key] = float(val)
1182        textureData['SH Coeff'] = [False,shCoef]
1183       
1184    Phase = SetNewPhase(Name=PhaseName,SGData=SGData,cell=abc+angles+[Volume,])
1185    general = Phase['General']
1186    general['Type'] = Ptype
1187    general['SH Texture'] = textureData
1188    Phase['Atoms'] = Atoms
1189    return Phase
1190       
1191def ReadPDBPhase(filename):
1192    EightPiSq = 8.*math.pi**2
1193    file = open(filename, 'Ur')
1194    Phase = {}
1195    Title = ''
1196    Compnd = ''
1197    Atoms = []
1198    A = np.zeros(shape=(3,3))
1199    S = file.readline()
1200    while S:
1201        Atom = []
1202        if 'TITLE' in S[:5]:
1203            Title = S[10:72].strip()
1204            S = file.readline()
1205        elif 'COMPND    ' in S[:10]:
1206            Compnd = S[10:72].strip()
1207            S = file.readline()
1208        elif 'CRYST' in S[:5]:
1209            abc = S[7:34].split()
1210            angles = S[34:55].split()
1211            cell=[float(abc[0]),float(abc[1]),float(abc[2]),
1212                float(angles[0]),float(angles[1]),float(angles[2])]
1213            Volume = G2lat.calc_V(G2lat.cell2A(cell))
1214            AA,AB = G2lat.cell2AB(cell)
1215            SpGrp = S[55:65]
1216            E,SGData = G2spc.SpcGroup(SpGrp)
1217            while E:
1218                print G2spc.SGErrors(E)
1219                dlg = wx.TextEntryDialog(None,
1220                    SpGrp[:-1]+' is invalid \nN.B.: make sure spaces separate axial fields in symbol',
1221                    'ERROR in space group symbol','',style=wx.OK)
1222                if dlg.ShowModal() == wx.ID_OK:
1223                    SpGrp = dlg.GetValue()
1224                    E,SGData = G2spc.SpcGroup(SpGrp)
1225                else:
1226                    return None
1227                dlg.Destroy()               
1228            SGlines = G2spc.SGPrint(SGData)
1229            for line in SGlines: print line
1230            S = file.readline()
1231        elif 'SCALE' in S[:5]:
1232            V = (S[10:41].split())
1233            A[int(S[5])-1] = [float(V[0]),float(V[1]),float(V[2])]
1234            S = file.readline()
1235        elif 'ATOM' in S[:4] or 'HETATM' in S[:6]:
1236            XYZ = [float(S[31:39]),float(S[39:47]),float(S[47:55])]
1237            XYZ = np.inner(AB,XYZ)
1238            XYZ = np.where(abs(XYZ)<0.00001,0,XYZ)
1239            SytSym,Mult = G2spc.SytSym(XYZ,SGData)
1240            Uiso = float(S[61:67])/EightPiSq
1241            Type = S[12:14].upper()
1242            if Type[0] in '123456789':
1243                Type = Type[1:]
1244            Atom = [S[22:27].strip(),S[17:20].upper(),S[20:22],
1245                S[12:17].strip(),Type.strip(),'',XYZ[0],XYZ[1],XYZ[2],
1246                float(S[55:61]),SytSym,Mult,'I',Uiso,0,0,0,0,0,0]
1247            S = file.readline()
1248            if 'ANISOU' in S[:6]:
1249                Uij = S[30:72].split()
1250                Uij = [float(Uij[0])/10000.,float(Uij[1])/10000.,float(Uij[2])/10000.,
1251                    float(Uij[3])/10000.,float(Uij[4])/10000.,float(Uij[5])/10000.]
1252                Atom = Atom[:14]+Uij
1253                Atom[12] = 'A'
1254                S = file.readline()
1255            Atom.append(ran.randint(0,sys.maxint))
1256            Atoms.append(Atom)
1257        else:           
1258            S = file.readline()
1259    file.close()
1260    if Title:
1261        PhaseName = Title
1262    elif Compnd:
1263        PhaseName = Compnd
1264    else:
1265        PhaseName = 'None'
1266    Phase = SetNewPhase(Name=PhaseName,SGData=SGData,cell=cell+[Volume,])
1267    Phase['General']['Type'] = 'macromolecular'
1268    Phase['Atoms'] = Atoms
1269   
1270    return Phase
1271
1272class MultipleChoicesDialog(wx.Dialog):
1273    '''A dialog that offers a series of choices, each with a title and a wx.Choice
1274    widget. Intended to be used Modally.
1275    typical input:
1276          choicelist=[ ('a','b','c'), ('test1','test2'),('no choice',)]
1277          headinglist = [ 'select a, b or c', 'select 1 of 2', 'No option here']
1278    selections are placed in self.chosen when OK is pressed
1279    '''
1280    def __init__(self,choicelist,headinglist,
1281                 head='Select options',
1282                 title='Please select from options below',
1283                 parent=None):
1284        self.chosen = []
1285        wx.Dialog.__init__(
1286            self,parent,wx.ID_ANY,head, 
1287            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
1288        panel = wx.Panel(self)
1289        mainSizer = wx.BoxSizer(wx.VERTICAL)
1290        mainSizer.Add((10,10),1)
1291        topLabl = wx.StaticText(panel,wx.ID_ANY,title)
1292        mainSizer.Add(topLabl,0,wx.ALIGN_CENTER_VERTICAL|wx.CENTER,10)
1293        self.ChItems = []
1294        for choice,lbl in zip(choicelist,headinglist):
1295            mainSizer.Add((10,10),1)
1296            self.chosen.append(0)
1297            topLabl = wx.StaticText(panel,wx.ID_ANY,' '+lbl)
1298            mainSizer.Add(topLabl,0,wx.ALIGN_LEFT,10)
1299            self.ChItems.append(wx.Choice(self, wx.ID_ANY, (100, 50), choices = choice))
1300            mainSizer.Add(self.ChItems[-1],0,wx.ALIGN_CENTER,10)
1301
1302        OkBtn = wx.Button(panel,-1,"Ok")
1303        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
1304        cancelBtn = wx.Button(panel,-1,"Cancel")
1305        cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
1306        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
1307        btnSizer.Add((20,20),1)
1308        btnSizer.Add(OkBtn)
1309        btnSizer.Add((20,20),1)
1310        btnSizer.Add(cancelBtn)
1311        btnSizer.Add((20,20),1)
1312        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
1313        panel.SetSizer(mainSizer)
1314        panel.Fit()
1315        self.Fit()
1316       
1317    def OnOk(self,event):
1318        parent = self.GetParent()
1319        if parent is not None: parent.Raise()
1320        # save the results from the choice widgets
1321        self.chosen = []
1322        for w in self.ChItems:
1323            self.chosen.append(w.GetSelection())
1324        self.EndModal(wx.ID_OK)             
1325           
1326    def OnCancel(self,event):
1327        parent = self.GetParent()
1328        if parent is not None: parent.Raise()
1329        self.chosen = []
1330        self.EndModal(wx.ID_CANCEL)             
1331           
1332def ExtractFileFromZip(filename, selection=None, confirmread=True,
1333                       confirmoverwrite=True, parent=None,
1334                       multipleselect=False):
1335    '''If the filename is a zip file, extract a file from that archive.
1336      selection is used to predefine the name of the file to be extracted
1337         filename case and zip directory name are ignored in selection;
1338         the first matching file is used
1339      confirmread if True asks the user to confirm before expanding
1340         the only file in a zip
1341      confirmoverwrite if True asks the user to confirm before
1342        overwriting if the extracted file already exists
1343      multipleselect if True allows more than one zip file to be extracted,
1344        a list of file(s) is returned
1345    If only one file is present, do not ask which one, otherwise offer a
1346       list of choices (unless selection is used)
1347    Return the name of the file that has been created or a list of files (see multipleselect)
1348      If the file is not a zipfile, return the name of the input file.
1349      If the zipfile is empty or no file has been selected, return None
1350    '''
1351    import zipfile # do this now, since we can save startup time by doing this only on need
1352    import shutil
1353    zloc = os.path.split(filename)[0]
1354    if not zipfile.is_zipfile(filename):
1355        #print("not zip")
1356        return filename
1357
1358    z = zipfile.ZipFile(filename,'r')
1359    zinfo = z.infolist()
1360
1361    if len(zinfo) == 0:
1362        #print('Zip has no files!')
1363        zlist = [-1]
1364    if selection:
1365        choices = [os.path.split(i.filename)[1].lower() for i in zinfo]
1366        if selection.lower() in choices:
1367            zlist = [choices.index(selection.lower())]
1368        else:
1369            print('debug: file '+str(selection)+' was not found in '+str(filename))
1370            zlist = [-1]
1371    elif len(zinfo) == 1 and confirmread:
1372        result = wx.ID_NO
1373        dlg = wx.MessageDialog(
1374            parent,
1375            'Is file '+str(zinfo[0].filename)+
1376            ' what you want to extract from '+
1377            str(os.path.split(filename)[1])+'?',
1378            'Confirm file', 
1379            wx.YES_NO | wx.ICON_QUESTION)
1380        try:
1381            result = dlg.ShowModal()
1382        finally:
1383            dlg.Destroy()
1384        if result == wx.ID_NO:
1385            zlist = [-1]
1386        else:
1387            zlist = [0]
1388    elif len(zinfo) == 1:
1389        zlist = [0]
1390    elif multipleselect:
1391        # select one or more from a from list
1392        choices = [i.filename for i in zinfo]
1393        dlg = wx.MultiChoiceDialog(
1394            parent,
1395            'Select file(s) to extract from zip file'+str(filename),
1396            'Choose file(s)',
1397            choices,
1398            wx.CHOICEDLG_STYLE,
1399            )
1400        if dlg.ShowModal() == wx.ID_OK:
1401            zlist = dlg.GetSelections()
1402            dlg.Destroy()
1403        else:
1404            dlg.Destroy()
1405            zlist = []
1406    else:
1407        # select one from a from list
1408        choices = [i.filename for i in zinfo]
1409        dlg = wx.SingleChoiceDialog(
1410            parent,
1411            'Select file to extract from zip file'+str(filename),
1412            'Choose file',
1413            choices,
1414            )
1415        if dlg.ShowModal() == wx.ID_OK:
1416            zlist = [dlg.GetSelection()]
1417            dlg.Destroy()
1418        else:
1419            dlg.Destroy()
1420            zlist = [-1]
1421       
1422    outlist = []
1423    for zindex in zlist:
1424        if zindex >= 0:
1425            efil = os.path.join(zloc, os.path.split(zinfo[zindex].filename)[1])
1426            if os.path.exists(efil) and confirmoverwrite:
1427                result = wx.ID_NO
1428                dlg = wx.MessageDialog(
1429                    parent,
1430                    'File '+str(efil)+' already exists. OK to overwrite it?',
1431                    'Confirm overwrite', 
1432                    wx.YES_NO | wx.ICON_QUESTION)
1433                try:
1434                    result = dlg.ShowModal()
1435                finally:
1436                    dlg.Destroy()
1437                if result == wx.ID_NO:
1438                    zindex = -1
1439        if zindex >= 0:
1440            # extract the file to the current directory, regardless of it's original path
1441            #z.extract(zinfo[zindex],zloc)
1442            eloc,efil = os.path.split(zinfo[zindex].filename)
1443            outfile = os.path.join(zloc, efil)
1444            fpin = z.open(zinfo[zindex])
1445            fpout = file(outfile, "wb")
1446            shutil.copyfileobj(fpin, fpout)
1447            fpin.close()
1448            fpout.close()
1449            outlist.append(outfile)
1450    z.close()
1451    if multipleselect and len(outlist) >= 1:
1452        return outlist
1453    elif len(outlist) == 1:
1454        return outlist[0]
1455    else:
1456        return None
1457
1458######################################################################
1459# base classes for reading various types of data files
1460#   not used directly, only by subclassing
1461######################################################################
1462E,SGData = G2spc.SpcGroup('P 1') # data structure for default space group
1463class ImportBaseclass(object):
1464    '''Defines a base class for the importing of data files (diffraction
1465    data, coordinates,...
1466    '''
1467    def __init__(self,
1468                 formatName,
1469                 longFormatName=None,
1470                 extensionlist=[],
1471                 strictExtension=False,
1472                 ):
1473        self.formatName = formatName # short string naming file type
1474        if longFormatName: # longer string naming file type
1475            self.longFormatName = longFormatName
1476        else:
1477            self.longFormatName = formatName
1478        # define extensions that are allowed for the file type
1479        # for windows, remove any extensions that are duplicate, as case is ignored
1480        if sys.platform == 'windows' and extensionlist:
1481            extensionlist = list(set([s.lower() for s in extensionlist]))
1482        self.extensionlist = extensionlist
1483        # If strictExtension is True, the file will not be read, unless
1484        # the extension matches one in the extensionlist
1485        self.strictExtension = strictExtension
1486        self.warnings = ''
1487        self.errors = ''
1488        # used for readers that will use multiple passes to read
1489        # more than one data block
1490        self.repeat = False
1491        self.repeatcount = 0
1492        #print 'created',self.__class__
1493
1494    def BlockSelector(self, ChoiceList, ParentFrame=None,
1495                      title='Select a block',
1496                      size=None, header='Block Selector'):
1497        ''' Provide a wx dialog to select a block if the file contains more
1498        than one set of data and one must be selected
1499        '''
1500        dlg = wx.SingleChoiceDialog(
1501            ParentFrame,
1502            title, header,
1503            ChoiceList,
1504            )
1505        if size: dlg.SetSize(size)
1506        if dlg.ShowModal() == wx.ID_OK:
1507            sel = dlg.GetSelection()
1508            dlg.Destroy()
1509            return sel
1510        else:
1511            dlg.Destroy()
1512            return None
1513
1514    def MultipleBlockSelector(self, ChoiceList, ParentFrame=None,
1515                      title='Select a block',
1516                      size=None, header='Block Selector'):
1517        ''' Provide a wx dialog to select a block of data if the file contains more
1518        than one set of data and one must be selected.
1519        Returns a list of the selected blocks
1520        '''
1521        dlg = wx.MultiChoiceDialog(
1522            ParentFrame,
1523            title, header,
1524            ChoiceList+['Select all'],
1525            wx.CHOICEDLG_STYLE
1526            )
1527        if size: dlg.SetSize(size)
1528        if dlg.ShowModal() == wx.ID_OK:
1529            sel = dlg.GetSelections()
1530            dlg.Destroy()
1531        else:
1532            dlg.Destroy()
1533            return []
1534        selected = []
1535        if len(ChoiceList) in sel:
1536            return range(len(ChoiceList))
1537        else:
1538            return sel
1539        return selected
1540
1541    def MultipleChoicesDialog(self, choicelist, headinglist, ParentFrame=None, **kwargs):
1542        '''A modal dialog that offers a series of choices, each with a title and a wx.Choice
1543        widget.
1544        typical input:
1545           choicelist=[ ('a','b','c'), ('test1','test2'),('no choice',)]
1546           headinglist = [ 'select a, b or c', 'select 1 of 2', 'No option here']
1547        optional keyword parameters are: head (window title) and title
1548        returns a list of selected indicies for each choice (or None)
1549        '''
1550        result = None
1551        dlg = MultipleChoicesDialog(choicelist,headinglist,
1552                                    parent=ParentFrame, **kwargs)         
1553        if dlg.ShowModal() == wx.ID_OK:
1554            result = dlg.chosen
1555        dlg.Destroy()
1556        return result
1557
1558    def ShowBusy(self):
1559        wx.BeginBusyCursor()
1560
1561    def DoneBusy(self):
1562        wx.EndBusyCursor()
1563       
1564#    def Reader(self, filename, filepointer, ParentFrame=None, **unused):
1565#        '''This method must be supplied in the child class
1566#        it will read the file
1567#        '''
1568#        return True # if read OK
1569#        return False # if an error occurs
1570
1571    def ExtensionValidator(self, filename):
1572        '''This methods checks if the file has the correct extension
1573        Return False if this filename will not be supported by this reader
1574        Return True if the extension matches the list supplied by the reader
1575        Return None if the reader allows un-registered extensions
1576        '''
1577        if filename:
1578            ext = os.path.splitext(filename)[1]
1579            if sys.platform == 'windows': ext = ext.lower()
1580            if ext in self.extensionlist: return True
1581            if self.strictExtension: return False
1582        return None
1583
1584    def ContentsValidator(self, filepointer):
1585        '''This routine will attempt to determine if the file can be read
1586        with the current format.
1587        This will typically be overridden with a method that
1588        takes a quick scan of [some of]
1589        the file contents to do a "sanity" check if the file
1590        appears to match the selected format.
1591        Expected to be called via self.Validator()
1592        '''
1593        #filepointer.seek(0) # rewind the file pointer
1594        return True
1595
1596class ImportPhase(ImportBaseclass):
1597    '''Defines a base class for the reading of files with coordinates
1598    '''
1599    def __init__(self,formatName,longFormatName=None,extensionlist=[],
1600        strictExtension=False,):
1601        # call parent __init__
1602        ImportBaseclass.__init__(self,formatName,longFormatName,
1603            extensionlist,strictExtension)
1604        # define a default Phase structure
1605        self.Phase = SetNewPhase(Name='new phase',SGData=SGData)
1606
1607    def PhaseSelector(self, ChoiceList, ParentFrame=None,
1608        title='Select a phase', size=None,header='Phase Selector'):
1609        ''' Provide a wx dialog to select a phase if the file contains more
1610        than one phase
1611        '''
1612        return self.BlockSelector(ChoiceList,ParentFrame,title,
1613            size,header)
1614
1615######################################################################
1616class ImportStructFactor(ImportBaseclass):
1617    '''Defines a base class for the reading of files with tables
1618    of structure factors
1619    '''
1620    def __init__(self,formatName,longFormatName=None,extensionlist=[],
1621        strictExtension=False,):
1622        ImportBaseclass.__init__(self,formatName,longFormatName,
1623            extensionlist,strictExtension)
1624
1625        # define contents of Structure Factor entry
1626        self.Controls = { # dictionary with plotting controls
1627            'Type' : 'Fosq',
1628            'ifFc' : False,    #
1629            'HKLmax' : [None,None,None],
1630            'HKLmin' : [None,None,None],
1631            'FoMax' : None,   # maximum observed structure factor as Fo
1632            'Zone' : '001',
1633            'Layer' : 0,
1634            'Scale' : 1.0,
1635            'log-lin' : 'lin',
1636            }
1637        self.Parameters = [ # list with data collection parameters
1638            ('SXC',0.70926),
1639            ['SXC',0.70926],
1640            ['Type','Lam']
1641            ]
1642        self.RefList = []
1643
1644    def UpdateParameters(self,Type=None,Wave=None):
1645        HistType = self.Parameters[0][0]
1646        HistWave = self.Parameters[0][1]
1647        if Type is not None:
1648            HistType = Type
1649        if Wave is not None:
1650            HistWave = Wave
1651        self.Parameters = [(HistType,HistWave),[HistType,HistWave],  # overwrite entire list
1652            ['Type','Lam']]
1653           
1654    def UpdateControls(self,Type='Fosq',FcalcPresent=False):
1655        '''Scan through the reflections to update the Controls dictionary
1656        '''
1657        self.Controls['Type'] = Type
1658        self.Controls['ifFc'] = FcalcPresent
1659        HKLmax = [None,None,None]
1660        HKLmin = [None,None,None]
1661        Fo2max = None
1662        for refl in self.RefList:
1663            HKL = refl[:3]
1664            if Fo2max is None:
1665                Fo2max = refl[8]
1666            else:
1667                Fo2max = max(Fo2max,refl[8])
1668            for i,hkl in enumerate(HKL):
1669                if HKLmax[i] is None:
1670                    HKLmax[i] = hkl
1671                    HKLmin[i] = hkl
1672                else:
1673                    HKLmax[i] = max(HKLmax[i],hkl)
1674                    HKLmin[i] = min(HKLmin[i],hkl)
1675        self.Controls['HKLmax'] = HKLmax
1676        self.Controls['HKLmin'] = HKLmin
1677        if Type ==  'Fosq':
1678            self.Controls['FoMax'] = np.sqrt(Fo2max)
1679        elif Type ==  'Fo':
1680            self.Controls['FoMax'] = Fo2max
1681        else:
1682            print "Unsupported Struct Fact type in ImportStructFactor.UpdateControls"
1683            raise Exception,"Unsupported Struct Fact type in ImportStructFactor.UpdateControls"
1684
1685######################################################################
1686class ImportPowderData(ImportBaseclass):
1687    '''Defines a base class for the reading of files with powder data
1688    '''
1689    # define some default instrument parameter files
1690    # just like GSAS, sigh
1691    defaultIparm_lbl = []
1692    defaultIparms = []
1693    defaultIparm_lbl.append('CuKa lab data')
1694    defaultIparms.append({
1695        'INS   HTYPE ':'PXC ',
1696        'INS  1 ICONS':'  1.540500  1.544300       0.0         0       0.7    0       0.5   ',
1697        'INS  1PRCF1 ':'    3    8      0.01                                                ',
1698        'INS  1PRCF11':'   2.000000E+00  -2.000000E+00   5.000000E+00   0.000000E+00        ',
1699        'INS  1PRCF12':'   0.000000E+00   0.000000E+00   0.150000E-01   0.150000E-01        ',
1700        })
1701    defaultIparm_lbl.append('0.6A synch')
1702    defaultIparms.append({
1703        'INS   HTYPE ':'PXC ',
1704        'INS  1 ICONS':'  0.600000  0.000000       0.0         0      0.99    0       0.5   ',
1705        'INS  1PRCF1 ':'    3    8      0.01                                                ',
1706        'INS  1PRCF11':'   1.000000E+00  -1.000000E+00   0.300000E+00   0.000000E+00        ',
1707        'INS  1PRCF12':'   0.000000E+00   0.000000E+00   0.100000E-01   0.100000E-01        ',
1708        })
1709    defaultIparm_lbl.append('1.5A CW neutron data')
1710    defaultIparms.append({
1711        'INS   HTYPE ':'PNC',
1712        'INS  1 ICONS':'   1.54020   0.00000   0.04000         0',
1713        'INS  1PRCF1 ':'    3    8      0.01                                                ',
1714        'INS  1PRCF1 ':'    3    8     0.005',
1715        'INS  1PRCF11':'   0.239700E+03  -0.298200E+03   0.180800E+03   0.000000E+00',
1716        'INS  1PRCF12':'   0.000000E+00   0.000000E+00   0.400000E-01   0.300000E-01',
1717        })
1718    def __init__(self,
1719                 formatName,
1720                 longFormatName=None,
1721                 extensionlist=[],
1722                 strictExtension=False,
1723                 ):
1724        ImportBaseclass.__init__(self,formatName,
1725                                            longFormatName,
1726                                            extensionlist,
1727                                            strictExtension)
1728        self.powderentry = ['',None,None] #  (filename,Pos,Bank)
1729        self.powderdata = [] # Powder dataset
1730        '''A powder data set is a list with items [x,y,w,yc,yb,yd]:
1731                np.array(x), # x-axis values
1732                np.array(y), # powder pattern intensities
1733                np.array(w), # 1/sig(intensity)^2 values (weights)
1734                np.array(yc), # calc. intensities (zero)
1735                np.array(yb), # calc. background (zero)
1736                np.array(yd), # obs-calc profiles
1737        '''                           
1738        self.comments = []
1739        self.idstring = ''
1740        self.Sample = G2pdG.SetDefaultSample()
1741        self.instparm = None # name hint
1742        self.instfile = '' # full path name to instrument parameter file
1743        self.instbank = '' # inst parm bank number
1744        self.instmsg = ''  # a label that gets printed to show
1745                           # where instrument parameters are from
1746        self.numbanks = 1
1747        self.instdict = {} # place items here that will be transferred to the instrument parameters
1748
1749if __name__ == '__main__':
1750    app = wx.PySimpleApp()
1751    frm = wx.Frame(None) # create a frame
1752    frm.Show(True)
1753    filename = '/tmp/notzip.zip'
1754    filename = '/tmp/all.zip'
1755    #filename = '/tmp/11bmb_7652.zip'
1756   
1757    #selection=None, confirmoverwrite=True, parent=None
1758    #print ExtractFileFromZip(filename, selection='11bmb_7652.fxye',parent=frm)
1759    print ExtractFileFromZip(filename,multipleselect=True)
1760                             #confirmread=False, confirmoverwrite=False)
1761
1762    # choicelist=[ ('a','b','c'),
1763    #              ('test1','test2'),('no choice',)]
1764    # titles = [ 'a, b or c', 'tests', 'No option here']
1765    # dlg = MultipleChoicesDialog(
1766    #     choicelist,titles,
1767    #     parent=frm)
1768    # if dlg.ShowModal() == wx.ID_OK:
1769    #     print 'Got OK'
Note: See TracBrowser for help on using the repository browser.