source: trunk/imports/G2sad_xye.py @ 1225

Last change on this file since 1225 was 1225, checked in by vondreele, 8 years ago

multiple revisions for sasd data

  • Property svn:eol-style set to native
File size: 9.8 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2013-12-16 10:43:01 -0600 (Mon, 16 Dec 2013) $
4# $Author: toby $
5# $Revision: 1168 $
6# $URL: https://subversion.xray.aps.anl.gov/pyGSAS/trunk/imports/G2sad_xye.py $
7# $Id: G2sad_xye.py 1168 2013-12-16 16:43:01Z toby $
8########### SVN repository information ###################
9'''
10*Module G2sad_xye: small angle q step .xye data*
11------------------------------------
12
13Routine to read in small angle data from an .xye file
14
15'''
16
17import sys
18import os.path as ospath
19import numpy as np
20import GSASIIIO as G2IO
21import GSASIIpath
22GSASIIpath.SetVersionNumber("$Revision: 1168 $")
23npasind = lambda x: 180.*np.arcsin(x)/np.pi
24
25class xye_ReaderClass(G2IO.ImportSmallAngleData):
26    'Routines to import q SAXD data from a .xye file'
27    def __init__(self):
28        super(self.__class__,self).__init__( # fancy way to self-reference
29            extensionlist=('.xye','.txt','.dat'),
30            strictExtension=False,
31            formatName = 'q step xye',
32            longFormatName = 'q stepped data file'
33            )
34
35    # Validate the contents -- make sure we only have valid lines
36    def ContentsValidator(self, filepointer):
37        'Look through the file for expected types of lines in a valid q-step file'
38        gotCcomment = False
39        begin = True
40        for i,S in enumerate(filepointer):
41            if i > 1000: break
42            if begin:
43                if gotCcomment and S.find('*/') > -1:
44                    begin = False
45                    continue
46                if S.strip().startswith('/*'):
47                    gotCcomment = True
48                    continue   
49                if S[0] == '#':
50                    continue       #ignore comments, if any
51                elif len(S) == 1:
52                    continue        #ignore blank lines
53                elif not gotCcomment:
54                    begin = False
55                # valid line to read?
56            if begin:
57                continue   
58            vals = S.split()
59            if 2 <= len(vals) <= 3:
60                continue
61            else:
62                self.errors = 'Unexpected information in line: '+str(i+1)
63                self.errors += '  '+str(S)
64                return False
65        return True # no errors encountered
66
67    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
68        'Read a q-step file'
69        x = []
70        y = []
71        w = []
72        try:
73            wave = 1.5428   #Cuka default
74            Temperature = 300
75            gotCcomment = False
76            begin = True
77            for i,S in enumerate(filepointer):
78                self.errors = 'Error reading line: '+str(i+1)
79                # or a block of comments delimited by /* and */
80                # or (GSAS style) each line can begin with '#'
81                if begin:
82                    if 'Wave' in S.split('=')[0]:
83                        try:
84                            wave = float(S.split('=')[1])
85                        except:
86                            pass
87                    if gotCcomment:
88                        if S.find('*/') == -1:
89                            self.comments.append(S[:-1])
90                        else:
91                            self.comments.append(S[:-1])
92                            begin = False
93                        continue
94                    if S.strip().startswith('/*'):
95                        self.comments.append(S[:-1])
96                        gotCcomment = True
97                        continue   
98                    if S[0] == '#':
99                        self.comments.append(S[:-1])
100                        continue       #ignore comments, if any
101                    elif len(S) == 1:      #blank line only CR/LF
102                        continue
103                    elif  not gotCcomment:
104                        begin = False
105                # valid line to read
106                if begin:
107                    continue
108                vals = S.split()
109                try:
110                    x.append(float(vals[0]))
111#                    x.append(2.*npasind(wave*float(vals[0])/(4.*np.pi)))
112                    f = float(vals[1])
113                    if f <= 0.0:
114                        y.append(0.0)
115                        w.append(1.0)
116                    elif len(vals) == 3:
117                        y.append(float(vals[1]))
118                        w.append(1.0/float(vals[2])**2)
119                    else:
120                        y.append(float(vals[1]))
121                        w.append(1.0/float(vals[1]))
122                except ValueError:
123                    msg = 'Error in line '+str(i+1)
124                    print msg
125                    break
126            N = len(x)
127            for S in self.comments:
128                if 'Temp' in S.split('=')[0]:
129                    try:
130                        Temperature = float(S.split('=')[1])
131                    except:
132                        pass
133            self.instdict['wave'] = wave
134            self.instdict['type'] = 'LXC'
135            x = np.array(x)
136            if np.any(x > 2.):      #nanometers-1?
137                x /= 10.
138            self.smallangledata = [
139                x, # x-axis values - q
140                np.array(y), # small angle pattern intensities
141                np.array(w), # 1/sig(intensity)^2 values (weights)
142                np.zeros(N), # calc. intensities (zero)
143                np.zeros(N), # obs-calc profiles
144                ]
145            self.smallangleentry[0] = filename
146            self.smallangleentry[2] = 1 # xye file only has one bank
147            self.idstring = ospath.basename(filename)
148            # scan comments for temperature
149            self.Sample['Temperature'] = Temperature
150
151            return True
152        except Exception as detail:
153            self.errors += '\n  '+str(detail)
154            print self.formatName+' read error:'+str(detail) # for testing
155            import traceback
156            traceback.print_exc(file=sys.stdout)
157            return False
158
159class txt_ReaderClass(G2IO.ImportSmallAngleData):
160    'Routines to import q SAXD data from a .txt file'
161    def __init__(self):
162        super(self.__class__,self).__init__( # fancy way to self-reference
163            extensionlist=('.txt','.dat'),
164            strictExtension=False,
165            formatName = 'q step txt',
166            longFormatName = 'q stepped text data file'
167            )
168
169    # Validate the contents -- make sure we only have valid lines
170    def ContentsValidator(self, filepointer):
171        'Look through the file for expected types of lines in a valid txt q-step file'
172        Ndata = 0
173        for i,S in enumerate(filepointer):
174            vals = S.split()
175            if 2 <= len(vals):
176                try:
177                    data = [float(val) for val in vals]
178                    Ndata += 1
179                except ValueError:
180                    pass
181        if not Ndata:     
182            self.errors = 'No 2 or more column numeric data found'
183            return False
184        return True # no errors encountered
185
186    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
187        'Read a q-step file'
188        x = []
189        y = []
190        w = []
191        try:
192            wave = 1.5428   #Cuka default
193            Temperature = 300
194            Ndata = 0
195            for i,S in enumerate(filepointer):
196                if len(S) == 1:     #skip blank line
197                    continue
198                if '=' in S:
199                    self.comments.append(S[:-1])
200                    if 'wave' in S.split('=')[0].lower():
201                        try:
202                            wave = float(S.split('=')[1])
203                        except:
204                            pass
205                    continue
206                vals = S.split()
207                if 2 <= len(vals):
208                    try:
209                        data = [float(val) for val in vals]
210                        x.append(float(data[0]))
211                        f = float(data[1])
212                        if f <= 0.0:
213                            y.append(0.0)
214                            w.append(1.0)
215                        elif len(vals) > 2:
216                            y.append(float(data[1]))
217                            w.append(1.0/float(data[2])**2)
218                        else:
219                            y.append(float(data[1]))
220                            w.append(1.0/float(data[1]))
221                    except ValueError:
222                        msg = 'Error in line '+str(i+1)
223                        print msg
224                        continue
225            N = len(x)
226            for S in self.comments:
227                if 'Temp' in S.split('=')[0]:
228                    try:
229                        Temperature = float(S.split('=')[1])
230                    except:
231                        pass
232            self.instdict['wave'] = wave
233            self.instdict['type'] = 'LXC'
234            x = np.array(x)
235            if np.any(x > 2.):         #q must be nm-1
236                x /= 10.
237#            x = 2.*npasind(wave*x)/(4.*np.pi)   #convert to 2-theta
238            self.smallangledata = [
239                x, # x-axis values q
240                np.array(y), # small angle pattern intensities
241                np.array(w), # 1/sig(intensity)^2 values (weights)
242                np.zeros(N), # calc. intensities (zero)
243                np.zeros(N), # obs-calc profiles
244                ]
245            self.smallangleentry[0] = filename
246            self.smallangleentry[2] = 1 # xye file only has one bank
247            self.idstring = ospath.basename(filename)
248            # scan comments for temperature
249            self.Sample['Temperature'] = Temperature
250   
251            return True
252        except Exception as detail:
253            self.errors += '\n  '+str(detail)
254            print self.formatName+' read error:'+str(detail) # for testing
255            import traceback
256            traceback.print_exc(file=sys.stdout)
257            return False
Note: See TracBrowser for help on using the repository browser.