source: trunk/imports/G2pwd_fxye.py @ 614

Last change on this file since 614 was 614, checked in by toby, 11 years ago

import GSAS powder data tested; import routines moved to imports

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
55        # reload previously saved values
56        if self.repeat and rdbuffer is not None:
57            Banks = rdbuffer.get('Banks')
58            Pos = rdbuffer.get('Pos')
59            selections = rdbuffer.get('selections')
60            comments = rdbuffer.get('comments')
61
62        # read through the file and find the beginning of each bank
63        # Save the offset (Pos), BANK line (Banks), comments for each
64        # bank
65        if len(Banks) != len(Pos) or len(Banks) == 0:
66            try:
67                i = -1
68                while True:
69                    i += 1
70                    S = filepointer.readline()
71                    if len(S) == 0: break
72                       
73                    if i==0: # first line is always a comment
74                        title = S[:-1]
75                        comments = [[title,]]
76                        continue
77                    if i==1 and S[:4].lower() == 'inst' and ':' in S:
78                        # 2nd line is instrument parameter file (optional)
79                        self.instparm = S.split(':')[1].strip()
80                        continue
81                    if S[0] == '#': # allow comments anywhere in the file
82                        # comments in fact should only preceed BANK lines
83                        comments[-1].append(S[:-1])
84                        continue       #ignore comments, if any
85                    if S[:4] == 'BANK':
86                        comments.append([title,])
87                        Banks.append(S)
88                        Pos.append(filepointer.tell())
89            except Exception as detail:
90                print self.formatName+' scan error:'+str(detail) # for testing
91                import traceback
92                traceback.print_exc(file=sys.stdout)
93                return False
94
95        # Now select the bank to read
96        if not Banks: # use of ContentsValidator should prevent this error
97            print self.formatName+' scan error: no BANK records'
98            selblk = None # no block to choose
99            return False
100        elif len(Banks) == 1: # only one Bank, don't ask
101            selblk = 0
102        elif self.repeat and selections is not None:
103            # we were called to repeat the read
104            print 'debug: repeat #',self.repeatcount,'selection',selections[self.repeatcount]
105            selblk = selections[self.repeatcount]
106            self.repeatcount += 1
107            if self.repeatcount >= len(selections): self.repeat = False
108        else:                       # choose from options
109            selections = self.MultipleBlockSelector(
110                Banks,
111                ParentFrame=ParentFrame,
112                title='Select Bank(s) to read from the list below',
113                size=(600,100),
114                header='Dataset Selector')
115            if len(selections) == 0: return False
116            selblk = selections[0] # select first in list
117            if len(selections) > 1: # prepare to loop through again
118                self.repeat = True
119                self.repeatcount = 1
120                if rdbuffer is not None:
121                    rdbuffer['Banks'] = Banks
122                    rdbuffer['Pos'] = Pos
123                    rdbuffer['selections'] = selections
124                    rdbuffer['comments'] = comments
125
126        # got a selection, now read it
127        Bank = Banks[selblk]
128        try:
129            if 'FXYE' in Bank:
130                self.powderdata = GetFXYEdata(filepointer,
131                                              Pos[selblk],Banks[selblk])
132            elif 'FXY' in Bank:
133                self.powderdata = GetFXYdata(filepointer,
134                                             Pos[selblk],Banks[selblk])
135            elif 'ESD' in Bank:
136                self.powderdata = GetESDdata(filepointer,
137                                             Pos[selblk],Banks[selblk])
138            elif 'STD' in Bank:
139                self.powderdata = GetSTDdata(filepointer,
140                                             Pos[selblk],Banks[selblk])
141            else:
142                self.powderdata = GetSTDdata(filepointer,
143                                             Pos[selblk],Banks[selblk])
144        except Exception as detail:
145            print self.formatName+' read error:'+str(detail) # for testing
146            import traceback
147            traceback.print_exc(file=sys.stdout)
148            return False
149        if comments is not None:
150            self.comments = comments[selblk]
151        self.powderentry[0] = filename
152        self.powderentry[1] = Pos # position offset (never used, I hope)
153        self.powderentry[2] = selblk+1 # bank number
154        self.idstring = ospath.basename(filename) + ' Bank '+str(selblk+1)
155        self.numbanks=len(Banks)
156        # scan comments for temperature
157        Temperature = 300
158        for S in self.comments:
159            if 'Temp' in S.split('=')[0]:
160                try:
161                    Temperature = float(S.split('=')[1])
162                except:
163                    pass
164        self.Sample['Temperature'] = Temperature
165        return True
166       
167def GetFXYEdata(File,Pos,Bank):
168    File.seek(Pos)
169    x = []
170    y = []
171    w = []
172    S = File.readline()
173    while S and S[:4] != 'BANK':
174        vals = S.split()
175        x.append(float(vals[0])/100.)               #CW: from centidegrees to degrees
176        f = float(vals[1])
177        if f <= 0.0:
178            y.append(0.0)
179            w.append(1.0)
180        else:
181            y.append(float(vals[1]))
182            w.append(1.0/float(vals[2])**2)
183        S = File.readline()
184    N = len(x)
185    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]   
186   
187def GetFXYdata(File,Pos,Bank):
188    File.seek(Pos)
189    x = []
190    y = []
191    w = []
192    S = File.readline()
193    while S and S[:4] != 'BANK':
194        vals = S.split()
195        x.append(float(vals[0])/100.)               #CW: from centidegrees to degrees
196        f = float(vals[1])
197        if f > 0.0:
198            y.append(f)
199            w.append(1.0/f)
200        else:             
201            y.append(0.0)
202            w.append(1.0)
203        S = File.readline()
204    N = len(x)
205    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
206   
207def GetESDdata(File,Pos,Bank):
208    File.seek(Pos)
209    cons = Bank.split()
210    start = float(cons[5])/100.0               #CW: from centidegrees to degrees
211    step = float(cons[6])/100.0
212    x = []
213    y = []
214    w = []
215    S = File.readline()
216    j = 0
217    while S and S[:4] != 'BANK':
218        for i in range(0,80,16):
219            xi = start+step*j
220            yi = sfloat(S[i:i+8])
221            ei = sfloat(S[i+8:i+16])
222            x.append(xi)
223            if yi > 0.0:
224                y.append(yi)
225                w.append(1.0/ei**2)
226            else:             
227                y.append(0.0)
228                w.append(1.0)
229            j += 1
230        S = File.readline()
231    N = len(x)
232    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
233
234def GetSTDdata(File,Pos,Bank):
235    File.seek(Pos)
236    cons = Bank.split()
237    Nch = int(cons[2])
238    start = float(cons[5])/100.0               #CW: from centidegrees to degrees
239    step = float(cons[6])/100.0
240    x = []
241    y = []
242    w = []
243    S = File.readline()
244    j = 0
245    while S and S[:4] != 'BANK':
246        for i in range(0,80,8):
247            xi = start+step*j
248            ni = max(sint(S[i:i+2]),1)
249            yi = max(sfloat(S[i+2:i+8]),0.0)
250            if yi:
251                vi = yi/ni
252            else:
253                yi = 0.0
254                vi = 1.0
255            j += 1
256            if j < Nch:
257                x.append(xi)
258                y.append(yi)
259                w.append(1.0/vi)
260        S = File.readline()
261    N = len(x)
262    return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
263
264def sfloat(S):
265    'convert a string to a float, treating an all-blank string as zero'
266    if S.strip():
267        return float(S)
268    else:
269        return 0.0
270
271def sint(S):
272    'convert a string to an integer, treating an all-blank string as zero'
273    if S.strip():
274        return int(S)
275    else:
276        return 0
Note: See TracBrowser for help on using the repository browser.