source: trunk/GSASIIIO.py @ 641

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

add support for zipped data and zip up largest exercise files

  • Property svn:keywords set to Date Author Revision URL Id
File size: 69.3 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 03:23:48 +0000 (Wed, 30 May 2012) $
7# $Author: toby $
8# $Revision: 641 $
9# $URL: trunk/GSASIIIO.py $
10# $Id: GSASIIIO.py 641 2012-05-30 03:23:48Z 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    '''If the filename is a zip file, extract a file from that archive.
1335      selection is used to predefine the name of the file to be extracted
1336         filename case and zip directory name are ignored in selection;
1337         the first matching file is used
1338      confirmread if True asks the user to confirm before expanding
1339         the only file in a zip
1340      confirmoverwrite if True asks the user to confirm before
1341        overwriting if the extracted file already exists
1342    If only one file is present, do not ask which one, otherwise offer a
1343       list of choices (unless selection is used)
1344    Return the name of the file that has been created
1345      If the file is not a zipfile, return the name of the input file.
1346      If the zipfile is empty or no file has been selected, return None
1347    '''
1348    import zipfile # do this now, since we can save startup time by doing this only on need
1349    import shutil
1350    zloc = os.path.split(filename)[0]
1351    if not zipfile.is_zipfile(filename):
1352        #print("not zip")
1353        return filename
1354
1355    z = zipfile.ZipFile(filename,'r')
1356    zinfo = z.infolist()
1357
1358    if len(zinfo) == 0:
1359        #print('Zip has no files!')
1360        zindex = -1
1361    if selection:
1362        choices = [os.path.split(i.filename)[1].lower() for i in zinfo]
1363        if selection.lower() in choices:
1364            zindex = choices.index(selection.lower())
1365        else:
1366            print('debug: file '+str(selection)+' was not found in '+str(filename))
1367            zindex = -1
1368    elif len(zinfo) == 1 and confirmread:
1369        result = wx.ID_NO
1370        dlg = wx.MessageDialog(
1371            parent,
1372            'Is file '+str(zinfo[0].filename)+
1373            ' what you want to extract from '+
1374            str(os.path.split(filename)[1])+'?',
1375            'Confirm file', 
1376            wx.YES_NO | wx.ICON_QUESTION)
1377        try:
1378            result = dlg.ShowModal()
1379        finally:
1380            dlg.Destroy()
1381        if result == wx.ID_NO:
1382            zindex = -1
1383        else:
1384            zindex = 0
1385    elif len(zinfo) == 1:
1386        zindex = 0
1387    else:
1388        # select from list
1389        choices = [i.filename for i in zinfo]
1390        dlg = wx.SingleChoiceDialog(
1391            parent,
1392            'Select file to extract from zip file'+str(filename),
1393            'Choose file',
1394            choices,
1395            )
1396        if dlg.ShowModal() == wx.ID_OK:
1397            zindex = dlg.GetSelection()
1398            dlg.Destroy()
1399        else:
1400            dlg.Destroy()
1401            zindex = -1
1402       
1403    if zindex >= 0:
1404        efil = os.path.join(zloc, os.path.split(zinfo[zindex].filename)[1])
1405        if os.path.exists(efil) and confirmoverwrite:
1406            result = wx.ID_NO
1407            dlg = wx.MessageDialog(
1408                parent,
1409                'File '+str(efil)+' already exists. OK to overwrite it?',
1410                'Confirm overwrite', 
1411                wx.YES_NO | wx.ICON_QUESTION)
1412            try:
1413                result = dlg.ShowModal()
1414            finally:
1415                dlg.Destroy()
1416            if result == wx.ID_NO:
1417                zindex = -1
1418    if zindex >= 0:
1419        # extract the file to the current directory, regardless of it's original path
1420        eloc,efil = os.path.split(zinfo[zindex].filename)
1421        outfile = os.path.join(zloc, efil)
1422        fpin = z.open(zinfo[zindex])
1423        fpout = file(outfile, "wb")
1424        shutil.copyfileobj(fpin, fpout)
1425        fpin.close()
1426        fpout.close()
1427        #z.extract(zinfo[zindex],zloc)
1428        z.close()
1429        return outfile
1430    z.close()
1431    return None
1432
1433######################################################################
1434# base classes for reading various types of data files
1435#   not used directly, only by subclassing
1436######################################################################
1437E,SGData = G2spc.SpcGroup('P 1') # data structure for default space group
1438class ImportBaseclass(object):
1439    '''Defines a base class for the importing of data files (diffraction
1440    data, coordinates,...
1441    '''
1442    def __init__(self,
1443                 formatName,
1444                 longFormatName=None,
1445                 extensionlist=[],
1446                 strictExtension=False,
1447                 ):
1448        self.formatName = formatName # short string naming file type
1449        if longFormatName: # longer string naming file type
1450            self.longFormatName = longFormatName
1451        else:
1452            self.longFormatName = formatName
1453        # define extensions that are allowed for the file type
1454        # for windows, remove any extensions that are duplicate, as case is ignored
1455        if sys.platform == 'windows' and extensionlist:
1456            extensionlist = list(set([s.lower() for s in extensionlist]))
1457        self.extensionlist = extensionlist
1458        # If strictExtension is True, the file will not be read, unless
1459        # the extension matches one in the extensionlist
1460        self.strictExtension = strictExtension
1461        self.warnings = ''
1462        self.errors = ''
1463        # used for readers that will use multiple passes to read
1464        # more than one data block
1465        self.repeat = False
1466        self.repeatcount = 0
1467        #print 'created',self.__class__
1468
1469    def BlockSelector(self, ChoiceList, ParentFrame=None,
1470                      title='Select a block',
1471                      size=None, header='Block Selector'):
1472        ''' Provide a wx dialog to select a block if the file contains more
1473        than one set of data and one must be selected
1474        '''
1475        dlg = wx.SingleChoiceDialog(
1476            ParentFrame,
1477            title, header,
1478            ChoiceList,
1479            )
1480        if size: dlg.SetSize(size)
1481        if dlg.ShowModal() == wx.ID_OK:
1482            sel = dlg.GetSelection()
1483            dlg.Destroy()
1484            return sel
1485        else:
1486            dlg.Destroy()
1487            return None
1488
1489    def MultipleBlockSelector(self, ChoiceList, ParentFrame=None,
1490                      title='Select a block',
1491                      size=None, header='Block Selector'):
1492        ''' Provide a wx dialog to select a block of data if the file contains more
1493        than one set of data and one must be selected.
1494        Returns a list of the selected blocks
1495        '''
1496        dlg = wx.MultiChoiceDialog(
1497            ParentFrame,
1498            title, header,
1499            ChoiceList+['Select all'],
1500            wx.CHOICEDLG_STYLE
1501            )
1502        if size: dlg.SetSize(size)
1503        if dlg.ShowModal() == wx.ID_OK:
1504            sel = dlg.GetSelections()
1505            dlg.Destroy()
1506        else:
1507            dlg.Destroy()
1508            return []
1509        selected = []
1510        if len(ChoiceList) in sel:
1511            return range(len(ChoiceList))
1512        else:
1513            return sel
1514        return selected
1515
1516    def MultipleChoicesDialog(self, choicelist, headinglist, ParentFrame=None, **kwargs):
1517        '''A modal dialog that offers a series of choices, each with a title and a wx.Choice
1518        widget.
1519        typical input:
1520           choicelist=[ ('a','b','c'), ('test1','test2'),('no choice',)]
1521           headinglist = [ 'select a, b or c', 'select 1 of 2', 'No option here']
1522        optional keyword parameters are: head (window title) and title
1523        returns a list of selected indicies for each choice (or None)
1524        '''
1525        result = None
1526        dlg = MultipleChoicesDialog(choicelist,headinglist,
1527                                    parent=ParentFrame, **kwargs)         
1528        if dlg.ShowModal() == wx.ID_OK:
1529            result = dlg.chosen
1530        dlg.Destroy()
1531        return result
1532
1533    def ShowBusy(self):
1534        wx.BeginBusyCursor()
1535
1536    def DoneBusy(self):
1537        wx.EndBusyCursor()
1538       
1539#    def Reader(self, filename, filepointer, ParentFrame=None, **unused):
1540#        '''This method must be supplied in the child class
1541#        it will read the file
1542#        '''
1543#        return True # if read OK
1544#        return False # if an error occurs
1545
1546    def ExtensionValidator(self, filename):
1547        '''This methods checks if the file has the correct extension
1548        Return False if this filename will not be supported by this reader
1549        Return True if the extension matches the list supplied by the reader
1550        Return None if the reader allows un-registered extensions
1551        '''
1552        if filename:
1553            ext = os.path.splitext(filename)[1]
1554            if sys.platform == 'windows': ext = ext.lower()
1555            if ext in self.extensionlist: return True
1556            if self.strictExtension: return False
1557        return None
1558
1559    def ContentsValidator(self, filepointer):
1560        '''This routine will attempt to determine if the file can be read
1561        with the current format.
1562        This will typically be overridden with a method that
1563        takes a quick scan of [some of]
1564        the file contents to do a "sanity" check if the file
1565        appears to match the selected format.
1566        Expected to be called via self.Validator()
1567        '''
1568        #filepointer.seek(0) # rewind the file pointer
1569        return True
1570
1571class ImportPhase(ImportBaseclass):
1572    '''Defines a base class for the reading of files with coordinates
1573    '''
1574    def __init__(self,formatName,longFormatName=None,extensionlist=[],
1575        strictExtension=False,):
1576        # call parent __init__
1577        ImportBaseclass.__init__(self,formatName,longFormatName,
1578            extensionlist,strictExtension)
1579        # define a default Phase structure
1580        self.Phase = SetNewPhase(Name='new phase',SGData=SGData)
1581
1582    def PhaseSelector(self, ChoiceList, ParentFrame=None,
1583        title='Select a phase', size=None,header='Phase Selector'):
1584        ''' Provide a wx dialog to select a phase if the file contains more
1585        than one phase
1586        '''
1587        return self.BlockSelector(ChoiceList,ParentFrame,title,
1588            size,header)
1589
1590######################################################################
1591class ImportStructFactor(ImportBaseclass):
1592    '''Defines a base class for the reading of files with tables
1593    of structure factors
1594    '''
1595    def __init__(self,formatName,longFormatName=None,extensionlist=[],
1596        strictExtension=False,):
1597        ImportBaseclass.__init__(self,formatName,longFormatName,
1598            extensionlist,strictExtension)
1599
1600        # define contents of Structure Factor entry
1601        self.Controls = { # dictionary with plotting controls
1602            'Type' : 'Fosq',
1603            'ifFc' : False,    #
1604            'HKLmax' : [None,None,None],
1605            'HKLmin' : [None,None,None],
1606            'FoMax' : None,   # maximum observed structure factor as Fo
1607            'Zone' : '001',
1608            'Layer' : 0,
1609            'Scale' : 1.0,
1610            'log-lin' : 'lin',
1611            }
1612        self.Parameters = [ # list with data collection parameters
1613            ('SXC',0.70926),
1614            ['SXC',0.70926],
1615            ['Type','Lam']
1616            ]
1617        self.RefList = []
1618
1619    def UpdateParameters(self,Type=None,Wave=None):
1620        HistType = self.Parameters[0][0]
1621        HistWave = self.Parameters[0][1]
1622        if Type is not None:
1623            HistType = Type
1624        if Wave is not None:
1625            HistWave = Wave
1626        self.Parameters = [(HistType,HistWave),[HistType,HistWave],  # overwrite entire list
1627            ['Type','Lam']]
1628           
1629    def UpdateControls(self,Type='Fosq',FcalcPresent=False):
1630        '''Scan through the reflections to update the Controls dictionary
1631        '''
1632        self.Controls['Type'] = Type
1633        self.Controls['ifFc'] = FcalcPresent
1634        HKLmax = [None,None,None]
1635        HKLmin = [None,None,None]
1636        Fo2max = None
1637        for refl in self.RefList:
1638            HKL = refl[:3]
1639            if Fo2max is None:
1640                Fo2max = refl[8]
1641            else:
1642                Fo2max = max(Fo2max,refl[8])
1643            for i,hkl in enumerate(HKL):
1644                if HKLmax[i] is None:
1645                    HKLmax[i] = hkl
1646                    HKLmin[i] = hkl
1647                else:
1648                    HKLmax[i] = max(HKLmax[i],hkl)
1649                    HKLmin[i] = min(HKLmin[i],hkl)
1650        self.Controls['HKLmax'] = HKLmax
1651        self.Controls['HKLmin'] = HKLmin
1652        if Type ==  'Fosq':
1653            self.Controls['FoMax'] = np.sqrt(Fo2max)
1654        elif Type ==  'Fo':
1655            self.Controls['FoMax'] = Fo2max
1656        else:
1657            print "Unsupported Struct Fact type in ImportStructFactor.UpdateControls"
1658            raise Exception,"Unsupported Struct Fact type in ImportStructFactor.UpdateControls"
1659
1660######################################################################
1661class ImportPowderData(ImportBaseclass):
1662    '''Defines a base class for the reading of files with powder data
1663    '''
1664    # define some default instrument parameter files
1665    # just like GSAS, sigh
1666    defaultIparm_lbl = []
1667    defaultIparms = []
1668    defaultIparm_lbl.append('CuKa lab data')
1669    defaultIparms.append({
1670        'INS   HTYPE ':'PXC ',
1671        'INS  1 ICONS':'  1.540500  1.544300       0.0         0       0.7    0       0.5   ',
1672        'INS  1PRCF1 ':'    3    8      0.01                                                ',
1673        'INS  1PRCF11':'   2.000000E+00  -2.000000E+00   5.000000E+00   0.000000E+00        ',
1674        'INS  1PRCF12':'   0.000000E+00   0.000000E+00   0.150000E-01   0.150000E-01        ',
1675        })
1676    defaultIparm_lbl.append('0.6A synch')
1677    defaultIparms.append({
1678        'INS   HTYPE ':'PXC ',
1679        'INS  1 ICONS':'  0.600000  0.000000       0.0         0      0.99    0       0.5   ',
1680        'INS  1PRCF1 ':'    3    8      0.01                                                ',
1681        'INS  1PRCF11':'   1.000000E+00  -1.000000E+00   0.300000E+00   0.000000E+00        ',
1682        'INS  1PRCF12':'   0.000000E+00   0.000000E+00   0.100000E-01   0.100000E-01        ',
1683        })
1684    defaultIparm_lbl.append('1.5A CW neutron data')
1685    defaultIparms.append({
1686        'INS   HTYPE ':'PNC',
1687        'INS  1 ICONS':'   1.54020   0.00000   0.04000         0',
1688        'INS  1PRCF1 ':'    3    8      0.01                                                ',
1689        'INS  1PRCF1 ':'    3    8     0.005',
1690        'INS  1PRCF11':'   0.239700E+03  -0.298200E+03   0.180800E+03   0.000000E+00',
1691        'INS  1PRCF12':'   0.000000E+00   0.000000E+00   0.400000E-01   0.300000E-01',
1692        })
1693    def __init__(self,
1694                 formatName,
1695                 longFormatName=None,
1696                 extensionlist=[],
1697                 strictExtension=False,
1698                 ):
1699        ImportBaseclass.__init__(self,formatName,
1700                                            longFormatName,
1701                                            extensionlist,
1702                                            strictExtension)
1703        self.powderentry = ['',None,None] #  (filename,Pos,Bank)
1704        self.powderdata = [] # Powder dataset
1705        '''A powder data set is a list with items [x,y,w,yc,yb,yd]:
1706                np.array(x), # x-axis values
1707                np.array(y), # powder pattern intensities
1708                np.array(w), # 1/sig(intensity)^2 values (weights)
1709                np.array(yc), # calc. intensities (zero)
1710                np.array(yb), # calc. background (zero)
1711                np.array(yd), # obs-calc profiles
1712        '''                           
1713        self.comments = []
1714        self.idstring = ''
1715        self.Sample = G2pdG.SetDefaultSample()
1716        self.instparm = None # name hint
1717        self.instfile = '' # full path name to instrument parameter file
1718        self.instbank = '' # inst parm bank number
1719        self.instmsg = ''  # a label that gets printed to show
1720                           # where instrument parameters are from
1721        self.numbanks = 1
1722        self.instdict = {} # place items here that will be transferred to the instrument parameters
1723
1724if __name__ == '__main__':
1725    app = wx.PySimpleApp()
1726    frm = wx.Frame(None) # create a frame
1727    frm.Show(True)
1728    filename = '/tmp/notzip.zip'
1729    filename = '/tmp/all.zip'
1730    #filename = '/tmp/11bmb_7652.zip'
1731   
1732    #selection=None, confirmoverwrite=True, parent=None
1733    #print ExtractFileFromZip(filename, selection='11bmb_7652.fxye',parent=frm)
1734    print ExtractFileFromZip(filename)
1735                             #confirmread=False, confirmoverwrite=False)
1736
1737    # choicelist=[ ('a','b','c'),
1738    #              ('test1','test2'),('no choice',)]
1739    # titles = [ 'a, b or c', 'tests', 'No option here']
1740    # dlg = MultipleChoicesDialog(
1741    #     choicelist,titles,
1742    #     parent=frm)
1743    # if dlg.ShowModal() == wx.ID_OK:
1744    #     print 'Got OK'
Note: See TracBrowser for help on using the repository browser.