source: trunk/imports/G2rfd_xye.py @ 4364

Last change on this file since 4364 was 4339, checked in by toby, 5 years ago

set svn flags; improve compare F-test & add info & covariance plot

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 12.4 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2020-03-03 21:01:43 +0000 (Tue, 03 Mar 2020) $
4# $Author: toby $
5# $Revision: 4339 $
6# $URL: trunk/imports/G2rfd_xye.py $
7# $Id: G2rfd_xye.py 4339 2020-03-03 21:01:43Z toby $
8########### SVN repository information ###################
9'''
10*Module G2rfd_xye: read reflectometry data*
11------------------------------------------------
12
13Routines to read in reflectometry data from an .xye type file, with
14two-theta or Q steps.
15
16'''
17
18from __future__ import division, print_function
19import os.path as ospath
20import numpy as np
21import GSASIIobj as G2obj
22import GSASIIpath
23GSASIIpath.SetVersionNumber("$Revision: 4339 $")
24npasind = lambda x: 180.*np.arcsin(x)/np.pi
25npsind = lambda x: np.sin(np.pi*x/180.)
26try:  # fails on doc build
27    fourpi = 4.0*np.pi
28    _double_min = np.finfo(float).min
29    _double_max = np.finfo(float).max
30except TypeError:
31    pass
32
33class txt_XRayReaderClass(G2obj.ImportReflectometryData):
34    'Routines to import X-ray q REFD data from a .xrfd or .xdat file'
35    def __init__(self):
36        super(self.__class__,self).__init__( # fancy way to self-reference
37            extensionlist=('.xrfd','.xdat'),
38            strictExtension=False,
39            formatName = 'q (A-1) step X-ray QRE data',
40            longFormatName = 'q (A-1) stepped X-ray text data file in Q,R,E order; E optional'
41            )
42
43    # Validate the contents -- make sure we only have valid lines
44    def ContentsValidator(self, filename):
45        'Look through the file for expected types of lines in a valid q-step file'
46        fp = open(filename,'r')
47        Ndata = 0
48        for i,S in enumerate(fp):
49            if '#' in S[0]:
50                continue
51            vals = S.split()
52            if len(vals) >= 2:
53                try:
54                    data = [float(val) for val in vals]
55                    Ndata += 1
56                except ValueError:
57                    pass
58        fp.close()
59        if not Ndata:     
60            self.errors = 'No 2 or more column numeric data found'
61            return False
62        return True # no errors encountered
63
64    def Reader(self,filename, ParentFrame=None, **unused):
65        print ('Read a q-step text file')
66        x = []
67        y = []
68        w = []
69        sq = []
70        wave = 1.5428   #Cuka default
71        Temperature = 300
72        fp = open(filename,'r')
73        for i,S in enumerate(fp):
74            if len(S) == 1:     #skip blank line
75                continue
76            if '=' in S:
77                self.comments.append(S[:-1])
78                if 'wave' in S.split('=')[0].lower():
79                    try:
80                        wave = float(S.split('=')[1])
81                    except:
82                        pass
83                continue
84            if '#' in S[0]:
85                continue
86            vals = S.split()
87            if len(vals) >= 2:
88                try:
89                    data = [float(val) for val in vals]
90                    x.append(float(data[0]))
91                    f = float(data[1])
92                    if f <= 0.0:
93                        del x[-1]
94                        continue
95                    elif len(vals) > 2:
96                        y.append(float(data[1]))
97                        w.append(1.0/float(data[2])**2)
98                        if len(vals) == 4:
99                            sq.append(float(data[3]))
100                        else:
101                            sq.append(0.)
102                    else:
103                        y.append(float(data[1]))
104                        w.append(1.0/(0.02*float(data[1]))**2)
105                        sq.append(0.)
106                except ValueError:
107                    msg = 'Error in line '+str(i+1)
108                    print (msg)
109                    continue
110        fp.close()
111        N = len(x)
112        for S in self.comments:
113            if 'Temp' in S.split('=')[0]:
114                try:
115                    Temperature = float(S.split('=')[1])
116                except:
117                    pass
118        self.instdict['wave'] = wave
119        self.instdict['type'] = 'RXC'
120        x = np.array(x)
121        self.reflectometrydata = [
122            x, # x-axis values q
123            np.array(y), # small angle pattern intensities
124            np.array(w), # 1/sig(intensity)^2 values (weights)
125            np.zeros(N), # calc. intensities (zero)
126            np.zeros(N), # obs-calc profiles
127            np.array(sq), # fix bkg
128            ]
129        self.reflectometryentry[0] = filename
130        self.reflectometryentry[2] = 1 # xye file only has one bank
131        self.idstring = ospath.basename(filename)
132        # scan comments for temperature
133        self.Sample['Temperature'] = Temperature
134        return True
135
136class txt_NeutronReaderClass(G2obj.ImportReflectometryData):
137    'Routines to import neutron q REFD data from a .nrfd or .ndat file'
138    def __init__(self):
139        super(self.__class__,self).__init__( # fancy way to self-reference
140            extensionlist=('.nrfd','.ndat'),
141            strictExtension=False,
142            formatName = 'q (A-1) step neutron QRE data',
143            longFormatName = 'q (A-1) stepped neutron text data file in Q,R,E order; E optional'
144            )
145
146    # Validate the contents -- make sure we only have valid lines
147    def ContentsValidator(self, filename):
148        'Look through the file for expected types of lines in a valid q-step file'
149        Ndata = 0
150        fp = open(filename,'r')
151        for i,S in enumerate(fp):
152            if '#' in S[0]:
153                continue
154            vals = S.split()
155            if len(vals) >= 2:
156                try:
157                    data = [float(val) for val in vals]
158                    Ndata += 1
159                except ValueError:
160                    pass
161        fp.close()
162        if not Ndata:     
163            self.errors = 'No 2 or more column numeric data found'
164            return False
165        return True # no errors encountered
166
167    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
168        print ('Read a q-step text file')
169        x = []
170        y = []
171        w = []
172        sq = []
173        wave = 1.5428   #Cuka default
174        Temperature = 300
175        fp = open(filename,'r')
176        for i,S in enumerate(fp):
177            if len(S) == 1:     #skip blank line
178                continue
179            if '=' in S:
180                self.comments.append(S[:-1])
181                if 'wave' in S.split('=')[0].lower():
182                    try:
183                        wave = float(S.split('=')[1])
184                    except:
185                        pass
186                continue
187            if '#' in S[0]:
188                continue
189            vals = S.split()
190            if len(vals) >= 2:
191                try:
192                    data = [float(val) for val in vals]
193                    x.append(float(data[0]))
194                    f = float(data[1])
195                    if f <= 0.0:
196                        del x[-1]
197                        continue
198                    elif len(vals) > 2:
199                        y.append(float(data[1]))
200                        w.append(1.0/float(data[2])**2)
201                        if len(vals) == 4:
202                            sq.append(float(data[3]))
203                        else:
204                            sq.append(0.)
205                    else:
206                        y.append(float(data[1]))
207                        w.append(1.0/(0.02*float(data[1]))**2)
208                        sq.append(0.)
209                except ValueError:
210                    msg = 'Error in line '+str(i+1)
211                    print (msg)
212                    continue
213        fp.close()
214        N = len(x)
215        for S in self.comments:
216            if 'Temp' in S.split('=')[0]:
217                try:
218                    Temperature = float(S.split('=')[1])
219                except:
220                    pass
221        self.instdict['wave'] = wave
222        self.instdict['type'] = 'RNC'
223        x = np.array(x)
224        self.reflectometrydata = [
225            x, # x-axis values q
226            np.array(y), # small angle pattern intensities
227            np.array(w), # 1/sig(intensity)^2 values (weights)
228            np.zeros(N), # calc. intensities (zero)
229            np.zeros(N), # obs-calc profiles
230            np.array(sq), # Q FWHM
231            ]
232        self.reflectometryentry[0] = filename
233        self.reflectometryentry[2] = 1 # xye file only has one bank
234        self.idstring = ospath.basename(filename)
235        # scan comments for temperature
236        self.Sample['Temperature'] = Temperature
237        return True
238
239class txt_XRayThetaReaderClass(G2obj.ImportReflectometryData):
240    'Routines to import X-ray theta REFD data from a .xtrfd or .xtdat file'
241    def __init__(self):
242        super(self.__class__,self).__init__( # fancy way to self-reference
243            extensionlist=('.xtrfd','.xtdat'),
244            strictExtension=False,
245            formatName = 'theta step X-ray QRE data',
246            longFormatName = 'theta stepped X-ray text data file in Q,R,E order; E optional'
247            )
248
249    # Validate the contents -- make sure we only have valid lines
250    def ContentsValidator(self, filename):
251        'Look through the file for expected types of lines in a valid q-step file'
252        Ndata = 0
253        self.wavelength = 0.
254        fp = open(filename,'r')
255        for i,S in enumerate(fp):
256            if '#' in S[0]:
257                if 'wavelength' in S[:-1].lower():
258                    self.wavelength = float(S[:-1].split('=')[1])
259                elif 'energy' in S[:-1].lower():
260                    self.wavelength = 12.39842*1000./float(S[:-1].split('=')[1])
261                continue
262            vals = S.split()
263            if len(vals) >= 2:
264                try:
265                    data = [float(val) for val in vals]
266                    Ndata += 1
267                except ValueError:
268                    pass
269        fp.close()
270        if not Ndata:     
271            self.errors = 'No 2 or more column numeric data found'
272            return False
273        elif not self.wavelength:
274            self.errors = 'Missing wavelength or energy in header'
275            return False
276        return True # no errors encountered
277
278    def Reader(self,filename, ParentFrame=None, **unused):
279        print ('Read a q-step text file')
280        x = []
281        y = []
282        w = []
283        sq = []
284        wave = self.wavelength
285        Temperature = 300
286        fp = open(filename,'r')
287        for i,S in enumerate(fp):
288            if len(S) == 1:     #skip blank line
289                continue
290            if '=' in S:
291                self.comments.append(S[:-1])
292                if 'wave' in S.split('=')[0].lower():
293                    try:
294                        wave = float(S.split('=')[1])
295                    except:
296                        pass
297                continue
298            if '#' in S[0]:
299                continue
300            vals = S.split()
301            if len(vals) >= 2:
302                try:
303                    data = [float(val) for val in vals]
304                    x.append(fourpi*npsind(float(data[0]))/wave)
305                    f = float(data[1])
306                    if f <= 0.0:
307                        del x[-1]
308                        continue
309                    elif len(vals) > 2:
310                        y.append(float(data[1]))
311                        w.append(1.0/float(data[2])**2)
312                        if len(vals) == 4:
313                            sq.append(float(data[3]))
314                        else:
315                            sq.append(0.)
316                    else:
317                        y.append(float(data[1]))
318                        w.append(1.0/(0.02*float(data[1]))**2)
319                        sq.append(0.)
320                except ValueError:
321                    msg = 'Error in line '+str(i+1)
322                    print (msg)
323                    continue
324        fp.close()
325        N = len(x)
326        for S in self.comments:
327            if 'Temp' in S.split('=')[0]:
328                try:
329                    Temperature = float(S.split('=')[1])
330                except:
331                    pass
332        self.instdict['wave'] = wave
333        self.instdict['type'] = 'RXC'
334        x = np.array(x)
335        self.reflectometrydata = [
336            x, # x-axis values q
337            np.array(y), # small angle pattern intensities
338            np.array(w), # 1/sig(intensity)^2 values (weights)
339            np.zeros(N), # calc. intensities (zero)
340            np.zeros(N), # obs-calc profiles
341            np.array(sq), # fix bkg
342            ]
343        self.reflectometryentry[0] = filename
344        self.reflectometryentry[2] = 1 # xye file only has one bank
345        self.idstring = ospath.basename(filename)
346        # scan comments for temperature
347        self.Sample['Temperature'] = Temperature
348
349        return True
350
Note: See TracBrowser for help on using the repository browser.