source: trunk/imports/G2pwd_fxye.py @ 792

Last change on this file since 792 was 792, checked in by vondreele, 10 years ago

change instrument parameters to dict from lists
chase down effects - got them all?
start on TOF; read TimeMap? style data - not complete

  • Property svn:eol-style set to native
File size: 12.8 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            self.TimeMap = False
31            if i==0: # first line is always a comment
32                continue
33            if i==1 and line[:4].lower() == 'inst' and ':' in line:
34                # 2nd line is optional instrument parameter file
35                continue
36            if line[0] == '#': continue
37            if line[:4] == 'BANK':
38                return True
39            if line [:8] == 'TIME_MAP':          #LANSCE TOF data
40                self.TimeMap = True
41                return True
42            else:
43                print 'ContentsValidator: '+self.formatName
44                print 'Unexpected information in line:',i+1 # debug info
45                print line
46                return False
47        return False # no bank records
48
49    def Reader(self,filename,filepointer, ParentFrame=None, **kwarg):
50        clockWd = None
51       
52        def GetFXYEdata(File,Pos,Bank):
53            File.seek(Pos)
54            x = []
55            y = []
56            w = []
57            S = File.readline()
58            while S and S[:4] != 'BANK':
59                vals = S.split()
60                x.append(float(vals[0])/100.)               #CW: from centidegrees to degrees
61                f = float(vals[1])
62                if f <= 0.0:
63                    y.append(0.0)
64                    w.append(1.0)
65                else:
66                    y.append(float(vals[1]))
67                    w.append(1.0/float(vals[2])**2)
68                S = File.readline()
69            N = len(x)
70            return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]   
71           
72        def GetFXYdata(File,Pos,Bank):
73            File.seek(Pos)
74            x = []
75            y = []
76            w = []
77            S = File.readline()
78            while S and S[:4] != 'BANK':
79                vals = S.split()
80                x.append(float(vals[0])/100.)               #CW: from centidegrees to degrees
81                f = float(vals[1])
82                if f > 0.0:
83                    y.append(f)
84                    w.append(1.0/f)
85                else:             
86                    y.append(0.0)
87                    w.append(1.0)
88                S = File.readline()
89            N = len(x)
90            return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
91           
92        def GetESDdata(File,Pos,Bank):
93            File.seek(Pos)
94            cons = Bank.split()
95            if clockWd:
96                start = 0
97                step = 1
98            else:
99                start = float(cons[5])/100.0               #CW: from centidegrees to degrees
100                step = float(cons[6])/100.0
101            x = []
102            y = []
103            w = []
104            S = File.readline()
105            j = 0
106            while S and S[:4] != 'BANK':
107                for i in range(0,80,16):
108                    xi = start+step*j
109                    yi = sfloat(S[i:i+8])
110                    ei = sfloat(S[i+8:i+16])
111                    x.append(xi)
112                    if yi > 0.0:
113                        y.append(yi)
114                        w.append(1.0/ei**2)
115                    else:             
116                        y.append(0.0)
117                        w.append(1.0)
118                    j += 1
119                S = File.readline()
120            N = len(x)
121            if clockWd:
122                x,cw = Tmap2TOF(self.TimeMap,clockWd)
123                x = x[:-2]+cw[:-1]/2.
124                return [x,np.array(y)/cw[:-1],np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
125            else:
126                return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
127       
128        def GetSTDdata(File,Pos,Bank):
129            File.seek(Pos)
130            cons = Bank.split()
131            Nch = int(cons[2])
132            if clockWd:
133                start = 0
134                step = 1
135            else:
136                start = float(cons[5])/100.0               #CW: from centidegrees to degrees
137                step = float(cons[6])/100.0
138            x = []
139            y = []
140            w = []
141            S = File.readline()
142            j = 0
143            while S and S[:4] != 'BANK':
144                for i in range(0,80,8):
145                    xi = start+step*j
146                    ni = max(sint(S[i:i+2]),1)
147                    yi = max(sfloat(S[i+2:i+8]),0.0)
148                    if yi:
149                        vi = yi/ni
150                    else:
151                        yi = 0.0
152                        vi = 1.0
153                    j += 1
154                    if j < Nch:
155                        x.append(xi)
156                        y.append(yi)
157                        w.append(1.0/vi)
158                S = File.readline()
159            N = len(x)
160            if clockWd:
161                x,cw = Tmap2TOF(self.TimeMap,clockWd)
162                x = x[:-2]+cw[:-1]/2.
163                return [x,np.array(y)/cw[:-1],np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
164            else:
165                return [np.array(x),np.array(y),np.array(w),np.zeros(N),np.zeros(N),np.zeros(N)]
166           
167        def GetTimeMap(File,Pos,TimeMap):
168            File.seek(Pos)
169            cons = TimeMap.split()
170            Nch = int(cons[1])
171            Nrec = int(cons[2])
172            clockWd = float(cons[4])/1000.          #in mus
173            TMap = np.zeros(Nch+2,dtype=int)
174            ind = 0
175            for i in range(Nrec):
176                S = File.readline().rstrip('\n')
177                vals = S.split()
178                for val in vals:
179                    TMap[ind] = int(val)
180                    ind += 1
181            TMap = np.reshape(TMap,(-1,3))
182            TMax = TMap[-1][0]
183            Nch = TMap[-2][0]+(TMax-TMap[-2][1]+TMap[-2][2]-1)/TMap[-2][2]
184            TMap[-1] = [Nch+1,TMax,0]
185            TMap = TMap.T
186            TMap[0] -= 1
187            return TMap.T,clockWd
188           
189        def Tmap2TOF(TMap,clockWd):
190            TOF = []
191            chWdt = []
192            Tch,T,Step = TMap[0]
193            for tmap in TMap[1:]:
194                tch,t,step = tmap
195                TOF += [T+Step*(i-Tch) for i in range(Tch,tch)]
196                Tch,T,Step = tmap
197            TOF = np.array(TOF)*clockWd
198            chWdt = np.diff(TOF)
199            return TOF,chWdt
200
201        x = []
202        y = []
203        w = []
204        Banks = []
205        Pos = []
206        rdbuffer = kwarg.get('buffer')
207        title = ''
208        comments = None
209        selections = None
210
211        # reload previously saved values
212        if self.repeat and rdbuffer is not None:
213            Banks = rdbuffer.get('Banks')
214            Pos = rdbuffer.get('Pos')
215            selections = rdbuffer.get('selections')
216            comments = rdbuffer.get('comments')
217
218        # read through the file and find the beginning of each bank
219        # Save the offset (Pos), BANK line (Banks), comments for each
220        # bank
221        if len(Banks) != len(Pos) or len(Banks) == 0:
222            try:
223                i = -1
224                while True:
225                    i += 1
226                    S = filepointer.readline()
227                    if len(S) == 0: break
228                       
229                    if i==0: # first line is always a comment
230                        title = S[:-1]
231                        comments = [[title,]]
232                        continue
233                    if i==1 and S[:4].lower() == 'inst' and ':' in S:
234                        # 2nd line is instrument parameter file (optional)
235                        self.instparm = S.split(':')[1].strip()
236                        continue
237                    if S[0] == '#': # allow comments anywhere in the file
238                        # comments in fact should only preceed BANK lines
239                        comments[-1].append(S[:-1])
240                        continue
241                    if S[:4] == 'BANK':
242                        comments.append([title,])
243                        Banks.append(S)
244                        Pos.append(filepointer.tell())
245                    if S[:8] == 'TIME_MAP':
246                        self.TimeMap,clockWd = GetTimeMap(filepointer,filepointer.tell(),S)
247            except Exception as detail:
248                print self.formatName+' scan error:'+str(detail) # for testing
249                import traceback
250                traceback.print_exc(file=sys.stdout)
251                return False
252
253        # Now select the bank to read
254        if not Banks: # use of ContentsValidator should prevent this error
255            print self.formatName+' scan error: no BANK records'
256            selblk = None # no block to choose
257            return False
258        elif len(Banks) == 1: # only one Bank, don't ask
259            selblk = 0
260        elif self.repeat and selections is not None:
261            # we were called to repeat the read
262            print 'debug: repeat #',self.repeatcount,'selection',selections[self.repeatcount]
263            selblk = selections[self.repeatcount]
264            self.repeatcount += 1
265            if self.repeatcount >= len(selections): self.repeat = False
266        else:                       # choose from options
267            selections = self.MultipleBlockSelector(
268                Banks,
269                ParentFrame=ParentFrame,
270                title='Select Bank(s) to read from the list below',
271                size=(600,100),
272                header='Dataset Selector')
273            if len(selections) == 0: return False
274            selblk = selections[0] # select first in list
275            if len(selections) > 1: # prepare to loop through again
276                self.repeat = True
277                self.repeatcount = 1
278                if rdbuffer is not None:
279                    rdbuffer['Banks'] = Banks
280                    rdbuffer['Pos'] = Pos
281                    rdbuffer['selections'] = selections
282                    rdbuffer['comments'] = comments
283
284        # got a selection, now read it
285        Bank = Banks[selblk]
286        try:
287            if 'FXYE' in Bank:
288                self.powderdata = GetFXYEdata(filepointer,
289                                              Pos[selblk],Banks[selblk])
290            elif 'FXY' in Bank:
291                self.powderdata = GetFXYdata(filepointer,
292                                             Pos[selblk],Banks[selblk])
293            elif 'ESD' in Bank:
294                self.powderdata = GetESDdata(filepointer,
295                                             Pos[selblk],Banks[selblk])
296            elif 'STD' in Bank:
297                self.powderdata = GetSTDdata(filepointer,
298                                             Pos[selblk],Banks[selblk])
299            else:
300                self.powderdata = GetSTDdata(filepointer,
301                                             Pos[selblk],Banks[selblk])
302        except Exception as detail:
303            print self.formatName+' read error:'+str(detail) # for testing
304            import traceback
305            traceback.print_exc(file=sys.stdout)
306            return False
307        if comments is not None:
308            self.comments = comments[selblk]
309        self.powderentry[0] = filename
310        self.powderentry[1] = Pos # position offset (never used, I hope)
311        self.powderentry[2] = selblk+1 # bank number
312        self.idstring = ospath.basename(filename) + ' Bank '+str(selblk+1)
313        self.numbanks=len(Banks)
314        # scan comments for temperature
315        Temperature = 300
316        for S in self.comments:
317            if 'Temp' in S.split('=')[0]:
318                try:
319                    Temperature = float(S.split('=')[1])
320                except:
321                    pass
322        self.Sample['Temperature'] = Temperature
323        return True
324       
325
326def sfloat(S):
327    'convert a string to a float, treating an all-blank string as zero'
328    if S.strip():
329        return float(S)
330    else:
331        return 0.0
332
333def sint(S):
334    'convert a string to an integer, treating an all-blank string as zero'
335    if S.strip():
336        return int(S)
337    else:
338        return 0
Note: See TracBrowser for help on using the repository browser.