source: trunk/imports/G2sad_xye.py @ 3136

Last change on this file since 3136 was 3136, checked in by vondreele, 5 years ago

make GSAS-II python 3.6 compliant & preserve python 2.7 use;changes:
do from future import division, print_function for all GSAS-II py sources
all menu items revised to be py 2.7/3.6 compliant
all wx.OPEN --> wx.FD_OPEN in file dialogs
all integer divides (typically for image pixel math) made explicit with ; ambiguous ones made floats as appropriate
all print "stuff" --> print (stuff)
all print >> pFile,'stuff' --> pFile.writeCIFtemplate('stuff')
all read file opens made explicit 'r' or 'rb'
all cPickle imports made for py2.7 or 3.6 as cPickle or _pickle; test for '2' platform.version_tuple[0] for py 2.7
define cPickleload to select load(fp) or load(fp,encoding='latin-1') for loading gpx files; provides cross compatibility between py 2.7/3.6 gpx files
make dict.keys() as explicit list(dict.keys()) as needed (NB: possible source of remaining py3.6 bugs)
make zip(a,b) as explicit list(zip(a,b)) as needed (NB: possible source of remaining py3.6 bugs)
select unichr/chr according test for '2' platform.version_tuple[0] for py 2.7 (G2pwdGUI * G2plot) for special characters
select wg.EVT_GRID_CELL_CHANGE (classic) or wg.EVT_GRID_CELL_CHANGED (phoenix) in grid Bind
maxint --> maxsize; used in random number stuff
raise Exception,"stuff" --> raise Exception("stuff")
wx 'classic' sizer.DeleteWindows?() or 'phoenix' sizer.Clear(True)
wx 'classic' SetToolTipString?(text) or 'phoenix' SetToolTip?(wx.ToolTip?(text)); define SetToolTipString?(self,text) to handle the choice in plots
status.SetFields? --> status.SetStatusText?
'classic' AddSimpleTool? or 'phoenix' self.AddTool? for plot toolbar; Bind different as well
define GetItemPydata? as it doesn't exist in wx 'phoenix'
allow python versions 2.7 & 3.6 to run GSAS-II
Bind override commented out - no logging capability (NB: remove all logging code?)
all import ContentsValidator? open filename & test if valid then close; filepointer removed from Reader
binary importers (mostly images) test for 'byte' type & convert as needed to satisfy py 3.6 str/byte rules

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