source: trunk/imports/G2pwd_xye.py @ 5017

Last change on this file since 5017 was 5017, checked in by vondreele, 3 months ago

modify xye importer to use qye data from POWGEN CW processing; assumes wave=0.965 & converts to 2-theta.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 8.2 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2021-08-27 13:04:47 +0000 (Fri, 27 Aug 2021) $
4# $Author: vondreele $
5# $Revision: 5017 $
6# $URL: trunk/imports/G2pwd_xye.py $
7# $Id: G2pwd_xye.py 5017 2021-08-27 13:04:47Z vondreele $
8########### SVN repository information ###################
9'''
10*Module G2pwd_xye: Topas .xye data*
11------------------------------------
12
13Routine to read in powder data from a Topas-compatible .xye file
14
15'''
16
17from __future__ import division, print_function
18import os.path as ospath
19import numpy as np
20import GSASIIobj as G2obj
21import GSASIIpath
22
23asind = lambda x: 180.*np.arcsin(x)/np.pi
24
25GSASIIpath.SetVersionNumber("$Revision: 5017 $")
26class xye_ReaderClass(G2obj.ImportPowderData):
27    'Routines to import powder data from a .xye/.chi file'
28    def __init__(self):
29        super(self.__class__,self).__init__( # fancy way to self-reference
30            extensionlist=('.xye','.qye','.chi','.qchi',),
31            strictExtension=False,
32            formatName = 'Topas xye or 2th Fit2D chi',
33            longFormatName = 'Topas .xye/.qye or 2th Fit2D .chi/.qchi powder data file'
34            )
35        self.scriptable = True
36
37    # Validate the contents -- make sure we only have valid lines
38    def ContentsValidator(self, filename):
39        'Look through the file for expected types of lines in a valid Topas file'
40        gotCcomment = False
41        begin = True
42        self.GSAS = False
43        self.Chi = False
44        Qchi = False
45        self.Wave = None
46        fp = open(filename,'r')
47        if '.chi' in filename:
48            self.Chi = True
49        if '.qchi' in filename:
50            Qchi = True
51        if2theta = False
52        ifQ = False
53        for i,S in enumerate(fp):
54            if not S:
55                break
56            if i > 1000: break
57            if begin:
58                if self.Chi or Qchi:
59                    if i < 4:
60                        if  '2-theta' in S.lower():
61                            if2theta = True
62                        elif  'q ' in S.lower():
63                            ifQ = True
64                            wave = ''
65                            wave = S.split()[1:]
66                            if wave: 
67                                try:
68                                    self.Wave = float(wave[0])
69                                except:
70                                    pass
71                            if not self.Wave:
72                                self.errors = 'No wavelength in a Q chi file'
73                                fp.close()
74                                return False
75                        continue
76                    else:
77                        begin = False
78                else:
79                    if2theta = True
80                    if  i == 0 and 'xydata' in S.lower():
81                        continue   # fullprof header
82                    if gotCcomment and S.find('*/') > -1:
83                        begin = False
84                        continue
85                    if S.strip().startswith('/*'):
86                        gotCcomment = True
87                        continue   
88                    if S[0] in ["'",'#','!']:
89                        if 'q' in S and not self.Wave:
90                            wave = S.split()[-1]
91                            if wave: 
92                                try:
93                                    self.Wave = float(wave[0])
94                                except:
95                                    self.Wave = 0.965   #special for POWGEN "pink" CW data
96                        continue       #ignore comments, if any
97                    elif S.startswith('TITLE'):
98                        continue
99                    else:
100                        begin = False
101                # valid line to read?
102            #vals = S.split()
103            if ifQ:
104                pass
105            elif not if2theta:
106                self.errors = 'Not a 2-theta chi file'
107                fp.close()
108                return False
109            vals = S.replace(',',' ').replace(';',' ').split()
110            if len(vals) == 2 or len(vals) == 3:
111                continue
112            else:
113                self.errors = 'Unexpected information in line: '+str(i+1)
114                if all([ord(c) < 128 and ord(c) != 0 for c in str(S)]): # show only if ASCII
115                    self.errors += '  '+str(S)
116                else: 
117                    self.errors += '  (binary)'
118                fp.close()
119                return False
120        fp.close()
121        return True # no errors encountered
122
123    def Reader(self,filename, ParentFrame=None, **unused):
124        'Read a Topas file'
125        x = []
126        y = []
127        w = []
128        gotCcomment = False
129        begin = True
130        fp = open(filename,'r')
131        for i,S in enumerate(fp):
132            self.errors = 'Error reading line: '+str(i+1)
133            # or a block of comments delimited by /* and */
134            # or (GSAS style) each line can begin with '#'
135            # or WinPLOTR style, a '!'
136            if begin:
137                if self.Chi:
138                    if i < 4:
139                        continue
140                    else:
141                        begin = False
142                else:       
143                    if gotCcomment and S.find('*/') > -1:
144                        self.comments.append(S[:-1])
145                        begin = False
146                        continue
147                    if S.strip().startswith('/*'):
148                        self.comments.append(S[:-1])
149                        gotCcomment = True
150                        continue   
151                    if S[0] in ["'",'#','!']:
152                        self.comments.append(S[:-1])
153                        continue       #ignore comments, if any
154                    elif  i == 0 and 'xydata' in S.lower():
155                        continue   # fullprof header
156                    elif S.startswith('TITLE'):
157                        self.comments = [S]
158                        continue
159                    else:
160                        begin = False
161            # valid line to read
162            #vals = S.split()
163            vals = S.replace(',',' ').replace(';',' ').split()
164            if len(vals) < 2:
165                print ('Line '+str(i+1)+' cannot be read:\n\t'+S)
166                continue
167            try:
168                if self.Wave:
169                    try:
170                        val = min(0.995,self.Wave/(4.*np.pi/float(vals[0])))  #set max at 168deg
171                        x.append(2.0*asind(val))
172                    except:
173                        msg = 'Error converting '+str(vals[0]
174                        ) + 'with wavelength ' + str(self.Wave) 
175                        break
176                else:
177                    x.append(float(vals[0]))
178                f = float(vals[1])
179                if f <= 0.0:
180                    y.append(0.0)
181                    w.append(0.0)
182                elif len(vals) == 3:
183                    y.append(float(vals[1]))
184                    w.append(1.0/float(vals[2])**2)
185                else:
186                    y.append(float(vals[1]))
187                    w.append(1.0/float(vals[1]))
188            except ValueError:
189                msg = 'Error parsing number in line '+str(i+1)
190                if GSASIIpath.GetConfigValue('debug'):
191                    print (msg)
192                    print (S.strip())
193                break
194            except:
195                msg = 'Error in line '+str(i+1)
196                if GSASIIpath.GetConfigValue('debug'):
197                    print (msg)
198                    print (S.strip())
199                break
200        N = len(x)
201        self.powderdata = [
202            np.array(x), # x-axis values
203            np.array(y), # powder pattern intensities
204            np.array(w), # 1/sig(intensity)^2 values (weights)
205            np.zeros(N), # calc. intensities (zero)
206            np.zeros(N), # calc. background (zero)
207            np.zeros(N), # obs-calc profiles
208            ]
209        self.powderentry[0] = filename
210        #self.powderentry[1] = pos # bank offset (N/A here)
211        #self.powderentry[2] = 1 # xye file only has one bank
212        self.idstring = ospath.basename(filename)
213        # scan comments for temperature
214        Temperature = 300
215        for S in self.comments:
216            if 'temp' in S.lower().split('=')[0]:
217                try:
218                    Temperature = float(S.split('=')[1])
219                except:
220                    pass
221        self.Sample['Temperature'] = Temperature
222        fp.close()
223        return True
Note: See TracBrowser for help on using the repository browser.