source: trunk/imports/G2sad_xye.py @ 1300

Last change on this file since 1300 was 1300, checked in by vondreele, 9 years ago

Add additional column to SASD profile - contains fixed background
remove contour plotting from SASD data
Add background file to SASD models GUI
this change breaks old SASD gpx files, they will need to be recreated!

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