source: trunk/imports/G2sad_xye.py @ 5114

Last change on this file since 5114 was 5114, checked in by vondreele, 9 months ago

various fixes for EDX data fitting by LeBail?
various fixes for SAD analysis - plotting updates & importer
removed a couple of unused lambdas from G2sasd

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 14.5 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2021-12-21 14:53:00 +0000 (Tue, 21 Dec 2021) $
4# $Author: vondreele $
5# $Revision: 5114 $
6# $URL: trunk/imports/G2sad_xye.py $
7# $Id: G2sad_xye.py 5114 2021-12-21 14:53:00Z vondreele $
8########### SVN repository information ###################
9'''
10*Module G2sad_xye: read small angle data*
11------------------------------------------------
12
13Routines to read in small angle 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: 5114 $")
24npasind = lambda x: 180.*np.arcsin(x)/np.pi
25
26class txt_XRayReaderClass(G2obj.ImportSmallAngleData):
27    'Routines to import X-ray q SAXD data from a .xsad or .xdat file'
28    def __init__(self):
29        super(self.__class__,self).__init__( # fancy way to self-reference
30            extensionlist=('.xsad','.xdat'),
31            strictExtension=False,
32            formatName = 'q (A-1) step X-ray QIE data',
33            longFormatName = 'q (A-1) stepped X-ray text data file in Q,I,E order; E optional'
34            )
35
36    # Validate the contents -- make sure we only have valid lines
37    def ContentsValidator(self, filename):
38        'Look through the file for expected types of lines in a valid q-step file'
39        Ndata = 0
40        fp = open(filename,'r')
41        for i,S in enumerate(fp):
42            vals = S.split()
43            if len(vals) >= 2:
44                try:
45                    data = [float(val) for val in vals]
46                    Ndata += 1
47                except ValueError:
48                    pass
49        fp.close()
50        if not Ndata:     
51            self.errors = 'No 2 or more column numeric data found'
52            return False
53        return True # no errors encountered
54
55    def Reader(self,filename, ParentFrame=None, **unused):
56        print ('Read a q-step text file')
57        x = []
58        y = []
59        w = []
60        wave = 1.5428   #Cuka default
61        Temperature = 300
62        fp = open(filename,'r')
63        for i,S in enumerate(fp):
64            if len(S) == 1:     #skip blank line
65                continue
66            if '=' in S:
67                self.comments.append(S[:-1])
68                if 'wave' in S.split('=')[0].lower():
69                    try:
70                        wave = float(S.split('=')[1])
71                    except:
72                        pass
73                continue
74            vals = S.split()
75            if len(vals) >= 2:
76                try:
77                    data = [float(val) for val in vals]
78                    f = float(data[1])
79                    if f <= 0.0:
80                        break
81                        # del x[-1]
82                        # continue
83                    elif len(vals) > 2:
84                        y.append(float(data[1]))
85                        w.append(1.0/float(data[2])**2)
86                    else:
87                        y.append(float(data[1]))
88                        w.append(1.0/float(data[1]))
89                    x.append(float(data[0]))
90                except ValueError:
91                    msg = 'Error in line :%s'%S
92                    print (msg)
93                    continue
94        fp.close()
95        N = len(x)
96        for S in self.comments:
97            if 'Temp' in S.split('=')[0]:
98                try:
99                    Temperature = float(S.split('=')[1])
100                except:
101                    pass
102        self.instdict['wave'] = wave
103        self.instdict['type'] = 'LXC'
104        x = np.array(x)
105        self.smallangledata = [
106            x, # x-axis values q
107            np.array(y), # small angle pattern intensities
108            np.array(w), # 1/sig(intensity)^2 values (weights)
109            np.zeros(N), # calc. intensities (zero)
110            np.zeros(N), # obs-calc profiles
111            np.zeros(N), # fix bkg
112            ]
113        self.smallangleentry[0] = filename
114        self.smallangleentry[2] = 1 # xye file only has one bank
115        self.idstring = ospath.basename(filename)
116        # scan comments for temperature
117        self.Sample['Temperature'] = Temperature
118
119        return True
120
121class txt_nmXRayReaderClass(G2obj.ImportSmallAngleData):
122    'Routines to import X-ray q SAXD data from a .xsad or .xdat file, q in nm-1'
123    def __init__(self):
124        super(self.__class__,self).__init__( # fancy way to self-reference
125            extensionlist=('.xsad','.xdat'),
126            strictExtension=False,
127            formatName = 'q (nm-1) step X-ray QIE data',
128            longFormatName = 'q (nm-1) stepped X-ray text data file in Q,I,E order; E optional'
129            )
130
131    # Validate the contents -- make sure we only have valid lines
132    def ContentsValidator(self, filename):
133        'Look through the file for expected types of lines in a valid q-step file'
134        Ndata = 0
135        fp = open(filename,'r')
136        for i,S in enumerate(fp):
137            vals = S.split()
138            if len(vals) >= 2:
139                try:
140                    data = [float(val) for val in vals]
141                    Ndata += 1
142                except ValueError:
143                    pass
144        fp.close()
145        if not Ndata:     
146            self.errors = 'No 2 or more column numeric data found'
147            return False
148        return True # no errors encountered
149
150    def Reader(self,filename, ParentFrame=None, **unused):
151        print ('Read a q-step text file')
152        x = []
153        y = []
154        w = []
155        wave = 1.5428   #Cuka default
156        Temperature = 300
157        fp = open(filename,'r')
158        for i,S in enumerate(fp):
159            if len(S) == 1:     #skip blank line
160                continue
161            if '=' in S:
162                self.comments.append(S[:-1])
163                if 'wave' in S.split('=')[0].lower():
164                    try:
165                        wave = float(S.split('=')[1])
166                    except:
167                        pass
168                continue
169            vals = S.split()
170            if len(vals) >= 2:
171                try:
172                    data = [float(val) for val in vals]
173                    f = float(data[1])
174                    if f <= 0.0:
175                        break
176                        # x.pop()
177                        # continue
178                    elif len(vals) > 2:
179                        y.append(float(data[1]))
180                        w.append(1.0/float(data[2])**2)
181                    else:
182                        y.append(float(data[1]))
183                        w.append(1.0/float(data[1]))
184                    x.append(float(data[0])/10.)        #convert nm-1 to A-1
185                except ValueError:
186                    msg = 'Error in line :%s'%S
187                    print (msg)
188                    continue
189        fp.close()
190        N = len(x)
191        for S in self.comments:
192            if 'Temp' in S.split('=')[0]:
193                try:
194                    Temperature = float(S.split('=')[1])
195                except:
196                    pass
197        self.instdict['wave'] = wave
198        self.instdict['type'] = 'LXC'
199        x = np.array(x)
200        self.smallangledata = [
201            x, # x-axis values q
202            np.array(y), # small angle pattern intensities
203            np.array(w), # 1/sig(intensity)^2 values (weights)
204            np.zeros(N), # calc. intensities (zero)
205            np.zeros(N), # obs-calc profiles
206            np.zeros(N), # fix bkg
207            ]
208        self.smallangleentry[0] = filename
209        self.smallangleentry[2] = 1 # xye file only has one bank
210        self.idstring = ospath.basename(filename)
211        # scan comments for temperature
212        self.Sample['Temperature'] = Temperature
213
214        return True
215
216class txt_NeutronReaderClass(G2obj.ImportSmallAngleData):
217    'Routines to import neutron q SAXD data from a .nsad or .ndat file'
218    def __init__(self):
219        super(self.__class__,self).__init__( # fancy way to self-reference
220            extensionlist=('.nsad','.ndat'),
221            strictExtension=False,
222            formatName = 'q (A-1) step neutron QIE data',
223            longFormatName = 'q (A-1) stepped neutron CW text data file in Q,I,E order; E optional'
224            )
225
226    # Validate the contents -- make sure we only have valid lines
227    def ContentsValidator(self, filename):
228        'Look through the file for expected types of lines in a valid q-step file'
229        Ndata = 0
230        fp = open(filename,'r')
231        for i,S in enumerate(fp):
232            vals = S.split()
233            if len(vals) >= 2:
234                try:
235                    data = [float(val) for val in vals]
236                    Ndata += 1
237                except ValueError:
238                    pass
239        fp.close()
240        if not Ndata:     
241            self.errors = 'No 2 or more column numeric data found'
242            return False
243        return True # no errors encountered
244
245    def Reader(self,filename, ParentFrame=None, **unused):
246        print ('Read a q-step text file')
247        x = []
248        y = []
249        w = []
250        wave = 1.5428   #Cuka default
251        Temperature = 300
252        fp = open(filename,'r')
253        for i,S in enumerate(fp):
254            if len(S) == 1:     #skip blank line
255                continue
256            if '=' in S or '#' in S:
257                self.comments.append(S[:-1])
258                if 'wave' in S.split('=')[0].lower():
259                    try:
260                        wave = float(S.split('=')[1])
261                    except:
262                        pass
263                continue
264            vals = S.split()
265            if len(vals) >= 2:
266                try:
267                    data = [float(val) for val in vals]
268                    f = float(data[1])
269                    if f <= 0.0:
270                        break
271                        # y.append(0.0)
272                        # w.append(1.0)
273                    elif len(vals) > 2:
274                        y.append(float(data[1]))
275                        w.append(1.0/float(data[2])**2)
276                    else:
277                        y.append(float(data[1]))
278                        w.append(1.0/float(data[1]))
279                    x.append(float(data[0]))
280                except ValueError:
281                    msg = 'Error in line :%s'%S
282                    print (msg)
283                    continue
284        fp.close()
285        N = len(x)
286        for S in self.comments:
287            if 'Temp' in S.split('=')[0]:
288                try:
289                    Temperature = float(S.split('=')[1])
290                except:
291                    pass
292        self.instdict['wave'] = wave
293        self.instdict['type'] = 'LNC'
294        x = np.array(x)
295        if np.any(x > 2.):         #q must be nm-1
296            x /= 10.
297        self.smallangledata = [
298            x, # x-axis values q
299            np.array(y), # small angle pattern intensities
300            np.array(w), # 1/sig(intensity)^2 values (weights)
301            np.zeros(N), # calc. intensities (zero)
302            np.zeros(N), # obs-calc profiles
303            np.zeros(N), # fix bkg
304            ]
305        self.smallangleentry[0] = filename
306        self.smallangleentry[2] = 1 # xye file only has one bank
307        self.idstring = ospath.basename(filename)
308        # scan comments for temperature
309        self.Sample['Temperature'] = Temperature
310
311        return True
312
313class txt_nmNeutronReaderClass(G2obj.ImportSmallAngleData):
314    'Routines to import neutron q in nm-1 SAXD data from a .nsad or .ndat file'
315    def __init__(self):
316        super(self.__class__,self).__init__( # fancy way to self-reference
317            extensionlist=('.nsad','.ndat'),
318            strictExtension=False,
319            formatName = 'q (nm-1) step neutron QIE data',
320            longFormatName = 'q (nm-1) stepped neutron text data file in Q,I,E order; E optional'
321            )
322
323    # Validate the contents -- make sure we only have valid lines
324    def ContentsValidator(self, filename):
325        'Look through the file for expected types of lines in a valid q-step file'
326        Ndata = 0
327        fp = open(filename,'r')
328        for i,S in enumerate(fp):
329            vals = S.split()
330            if len(vals) >= 2:
331                try:
332                    data = [float(val) for val in vals]
333                    Ndata += 1
334                except ValueError:
335                    pass
336        fp.close()
337        if not Ndata:     
338            self.errors = 'No 2 or more column numeric data found'
339            return False
340        return True # no errors encountered
341
342    def Reader(self,filename, ParentFrame=None, **unused):
343        print ('Read a q-step text file')
344        x = []
345        y = []
346        w = []
347        wave = 1.5428   #Cuka default
348        Temperature = 300
349        fp = open(filename,'r')
350        for i,S in enumerate(fp):
351            if len(S) == 1:     #skip blank line
352                continue
353            if '=' in S or '#' in S:
354                self.comments.append(S[:-1])
355                if 'wave' in S.split('=')[0].lower():
356                    try:
357                        wave = float(S.split('=')[1])
358                    except:
359                        pass
360                continue
361            vals = S.split()
362            if len(vals) >= 2:
363                try:
364                    data = [float(val) for val in vals]
365                    f = float(data[1])
366                    if f <= 0.0:
367                        break
368                        # y.append(0.0)
369                        # w.append(1.0)
370                    elif len(vals) > 2:
371                        y.append(float(data[1]))
372                        w.append(1.0/float(data[2])**2)
373                    else:
374                        y.append(float(data[1]))
375                        w.append(1.0/float(data[1]))
376                    x.append(float(data[0])/10.)    #convert to A-1
377                except ValueError:
378                    msg = 'Error in line :%s'%S
379                    print (msg)
380                    continue
381        fp.close()
382        N = len(x)
383        for S in self.comments:
384            if 'Temp' in S.split('=')[0]:
385                try:
386                    Temperature = float(S.split('=')[1])
387                except:
388                    pass
389        self.instdict['wave'] = wave
390        self.instdict['type'] = 'LNC'
391        x = np.array(x)
392        self.smallangledata = [
393            x, # x-axis values q
394            np.array(y), # small angle pattern intensities
395            np.array(w), # 1/sig(intensity)^2 values (weights)
396            np.zeros(N), # calc. intensities (zero)
397            np.zeros(N), # obs-calc profiles
398            np.zeros(N), # fix bkg
399            ]
400        self.smallangleentry[0] = filename
401        self.smallangleentry[2] = 1 # xye file only has one bank
402        self.idstring = ospath.basename(filename)
403        # scan comments for temperature
404        self.Sample['Temperature'] = Temperature
405
406        return True
Note: See TracBrowser for help on using the repository browser.