source: trunk/imports/G2pwd_fxye.py @ 615

Last change on this file since 615 was 615, checked in by toby, 12 years ago

add powder CIF importer, minor other updates to readers

File size: 9.9 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2012-02-13 11:33:35 -0600 (Mon, 13 Feb 2012) $
4# $Author: vondreele & toby $
5# $Revision: 482 $
6# $URL: https://subversion.xor.aps.anl.gov/pyGSAS/trunk/G2importphase.py $
7# $Id: G2importphase.py 482 2012-02-13 17:33:35Z vondreele $
8########### SVN repository information ###################
9# a routine to read in powder data from a GSAS-compatible files
10#
11import sys
12import os.path as ospath
13import numpy as np
14import GSASIIIO as G2IO
15
16class GSAS_ReaderClass(G2IO.ImportPowderData):
17    'Routines to import powder data from a GSAS files'
18    def __init__(self):
19        super(self.__class__,self).__init__( # fancy way to self-reference
20            extensionlist=('.fxye','.raw','.gsas','.gsa','.RAW','.GSAS','.GSA'),
21            strictExtension=False,
22            formatName = 'GSAS',
23            longFormatName = 'GSAS powder data files'
24            )
25
26    # Validate the contents -- look for a bank line
27    def ContentsValidator(self, filepointer):
28        #print 'ContentsValidator: '+self.formatName
29        for i,line in enumerate(filepointer):
30            if i==0: # first line is always a comment
31                continue
32            if i==1 and line[:4].lower() == 'inst' and ':' in line:
33                # 2nd line is optional instrument parameter file
34                continue
35            if line[0] == '#': continue
36            if line[:4] == 'BANK':
37                return True
38            else:
39                print 'ContentsValidator: '+self.formatName
40                print 'Unexpected information in line:',i+1 # debug info
41                print line
42                return False
43        return False # no bank records
44
45    def Reader(self,filename,filepointer, ParentFrame=None, **kwarg):
46        x = []
47        y = []
48        w = []
49        Banks = []
50        Pos = []
51        rdbuffer = kwarg.get('buffer')
52        title = ''
53        comments = None
54        selections = None
55
56        # reload previously saved values
57        if self.repeat and rdbuffer is not None:
58            Banks = rdbuffer.get('Banks')
59            Pos = rdbuffer.get('Pos')
60            selections = rdbuffer.get('selections')
61            comments = rdbuffer.get('comments')
62
63        # read through the file and find the beginning of each bank
64        # Save the offset (Pos), BANK line (Banks), comments for each
65        # bank
66        if len(Banks) != len(Pos) or len(Banks) == 0:
67            try:
68                i = -1
69                while True:
70                    i += 1
71                    S = filepointer.readline()
72                    if len(S) == 0: break
73                       
74                    if i==0: # first line is always a comment
75                        title = S[:-1]
76                        comments = [[title,]]
77                        continue
78                    if i==1 and S[:4].lower() == 'inst' and ':' in S:
79                        # 2nd line is instrument parameter file (optional)
80                        self.instparm = S.split(':')[1].strip()
81                        continue
82                    if S[0] == '#': # allow comments anywhere in the file
83                        # comments in fact should only preceed BANK lines
84                        comments[-1].append(S[:-1])
85                        continue       #ignore comments, if any
86                    if S[:4] == 'BANK':
87                        comments.append([title,])
88                        Banks.append(S)
89                        Pos.append(filepointer.tell())
90            except Exception as detail:
91                print self.formatName+' scan error:'+str(detail) # for testing
92                import traceback
93                traceback.print_exc(file=sys.stdout)
94                return False
95
96        # Now select the bank to read
97        if not Banks: # use of ContentsValidator should prevent this error
98            print self.formatName+' scan error: no BANK records'
99            selblk = None # no block to choose
100            return False
101        elif len(Banks) == 1: # only one Bank, don't ask
102            selblk = 0
103        elif self.repeat and selections is not None:
104            # we were called to repeat the read
105            print 'debug: repeat #',self.repeatcount,'selection',selections[self.repeatcount]
106            selblk = selections[self.repeatcount]
107            self.repeatcount += 1
108            if self.repeatcount >= len(selections): self.repeat = False
109        else:                       # choose from options
110            selections = self.MultipleBlockSelector(
111                Banks,
112                ParentFrame=ParentFrame,
113                title='Select Bank(s) to read from the list below',
114                size=(600,100),
115                header='Dataset Selector')
116            if len(selections) == 0: return False
117            selblk = selections[0] # select first in list
118            if len(selections) > 1: # prepare to loop through again
119                self.repeat = True
120                self.repeatcount = 1
121                if rdbuffer is not None:
122                    rdbuffer['Banks'] = Banks
123                    rdbuffer['Pos'] = Pos
124                    rdbuffer['selections'] = selections
125                    rdbuffer['comments'] = comments
126
127        # got a selection, now read it
128        Bank = Banks[selblk]
129        try:
130            if 'FXYE' in Bank:
131                self.powderdata = GetFXYEdata(filepointer,
132                                              Pos[selblk],Banks[selblk])
133            elif 'FXY' in Bank:
134                self.powderdata = GetFXYdata(filepointer,
135                                             Pos[selblk],Banks[selblk])
136            elif 'ESD' in Bank:
137                self.powderdata = GetESDdata(filepointer,
138                                             Pos[selblk],Banks[selblk])
139            elif 'STD' in Bank:
140                self.powderdata = GetSTDdata(filepointer,
141                                             Pos[selblk],Banks[selblk])
142            else:
143                self.powderdata = GetSTDdata(filepointer,
144                                             Pos[selblk],Banks[selblk])
145        except Exception as detail:
146            print self.formatName+' read error:'+str(detail) # for testing
147            import traceback
148            traceback.print_exc(file=sys.stdout)
149            return False
150        if comments is not None:
151            self.comments = comments[selblk]
152        self.powderentry[0] = filename
153        self.powderentry[1] = Pos # position offset (never used, I hope)
154        self.powderentry[2] = selblk+1 # bank number
155        self.idstring = ospath.basename(filename) + ' Bank '+str(selblk+1)
156        self.numbanks=len(Banks)
157        # scan comments for temperature
158        Temperature = 300
159        for S in self.comments:
160            if 'Temp' in S.split('=')[0]:
161                try:
162                    Temperature = float(S.split('=')[1])
163                except:
164                    pass
165        self.Sample['Temperature'] = Temperature
166        return True
167       
168def GetFXYEdata(File,Pos,Bank):
169    File.seek(Pos)
170    x = []
171    y = []
172    w = []
173    S = File.readline()
174    while S and S[:4] != 'BANK':
175        vals = S.split()
176        x.append(float(vals[0])/100.)               #CW: from centidegrees to degrees
177        f = float(vals[1])
178        if f <= 0.0:
179            y.append(0.0)
180            w.append(1.0)
181        else:
182            y.append(float(vals[1]))
183            w.append(1.0/float(vals[2])**2)
184        S = File.readline()
185    N = len(x)
186    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]   
187   
188def GetFXYdata(File,Pos,Bank):
189    File.seek(Pos)
190    x = []
191    y = []
192    w = []
193    S = File.readline()
194    while S and S[:4] != 'BANK':
195        vals = S.split()
196        x.append(float(vals[0])/100.)               #CW: from centidegrees to degrees
197        f = float(vals[1])
198        if f > 0.0:
199            y.append(f)
200            w.append(1.0/f)
201        else:             
202            y.append(0.0)
203            w.append(1.0)
204        S = File.readline()
205    N = len(x)
206    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
207   
208def GetESDdata(File,Pos,Bank):
209    File.seek(Pos)
210    cons = Bank.split()
211    start = float(cons[5])/100.0               #CW: from centidegrees to degrees
212    step = float(cons[6])/100.0
213    x = []
214    y = []
215    w = []
216    S = File.readline()
217    j = 0
218    while S and S[:4] != 'BANK':
219        for i in range(0,80,16):
220            xi = start+step*j
221            yi = sfloat(S[i:i+8])
222            ei = sfloat(S[i+8:i+16])
223            x.append(xi)
224            if yi > 0.0:
225                y.append(yi)
226                w.append(1.0/ei**2)
227            else:             
228                y.append(0.0)
229                w.append(1.0)
230            j += 1
231        S = File.readline()
232    N = len(x)
233    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
234
235def GetSTDdata(File,Pos,Bank):
236    File.seek(Pos)
237    cons = Bank.split()
238    Nch = int(cons[2])
239    start = float(cons[5])/100.0               #CW: from centidegrees to degrees
240    step = float(cons[6])/100.0
241    x = []
242    y = []
243    w = []
244    S = File.readline()
245    j = 0
246    while S and S[:4] != 'BANK':
247        for i in range(0,80,8):
248            xi = start+step*j
249            ni = max(sint(S[i:i+2]),1)
250            yi = max(sfloat(S[i+2:i+8]),0.0)
251            if yi:
252                vi = yi/ni
253            else:
254                yi = 0.0
255                vi = 1.0
256            j += 1
257            if j < Nch:
258                x.append(xi)
259                y.append(yi)
260                w.append(1.0/vi)
261        S = File.readline()
262    N = len(x)
263    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
264
265def sfloat(S):
266    'convert a string to a float, treating an all-blank string as zero'
267    if S.strip():
268        return float(S)
269    else:
270        return 0.0
271
272def sint(S):
273    'convert a string to an integer, treating an all-blank string as zero'
274    if S.strip():
275        return int(S)
276    else:
277        return 0
Note: See TracBrowser for help on using the repository browser.