source: trunk/imports/G2pwd_rigaku.py @ 4132

Last change on this file since 4132 was 4132, checked in by vondreele, 3 years ago

fix rigaku .ras importer for single scan data sets

  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: $
4# $Author: toby $
5# $Revision: $
6# $URL: $
7# $Id: $
8########### SVN repository information ###################
9
10from __future__ import division, print_function
11import os
12import platform
13import numpy as np
14import GSASIIobj as G2obj
15import GSASIIpath
16GSASIIpath.SetVersionNumber("$Revision: $")
17class Rigaku_txtReaderClass(G2obj.ImportPowderData):
18    '''Routines to import powder data from a Rigaku .txt file with an angle and
19    then 1 or 11(!) intensity values on the line. The example file is proceeded
20    with 10 of blank lines, but I have assumed they could be any sort of text.
21    This code should work with an angle and any number of intensity values/line
22    as long as the number is the same on each line. The step size may not change. The
23    number of comment lines can also change, but should not appear to be intensity
24    values (numbers only).
25    '''
26    def __init__(self):
27        super(self.__class__,self).__init__( # fancy way to self-reference
28            extensionlist=('.txt','.TXT'),
29            strictExtension=True,
30            formatName = 'Rigaku .txt exported',
31            longFormatName = 'Rigaku powder data exported as .txt'
32            )
33        self.scriptable = True
34        self.vals = None
35        self.stepsize = None
36        self.skip = 0
37
38    # Validate the contents -- make sure we only have valid lines and set
39    # values we will need for later read.
40    def ContentsValidator(self, filename):
41        self.vals = None
42        self.stepsize = None
43        j = 0
44        prevAngle = None
45        header = True
46        self.skip = -1
47        fp = open(filename,'r')
48        for i,line in enumerate(fp):
49            sline = line.split()
50            vals = len(sline)
51            if header:
52                self.skip += 1
53                if not line.strip(): continue # ignore blank lines
54                err = False
55                for item in sline:
56                    try:
57                        float(item)
58                    except:
59                        err = True
60                        break
61                if err: continue
62                if vals < 1: continue
63                header = False # found first non-header line
64            if vals < 2:
65                print('Too few values for Rigaku .txt file')
66                fp.close()
67                return False
68            if self.vals is None:
69                self.vals = vals
70            elif self.vals != vals:
71                print('Inconsistent numbers values for Rigaku .txt file on line '+str(i+1))
72                fp.close()
73                return False
74            else:
75                j += 1
76            try: 
77                angle = float(sline[0])
78            except:
79                print('Unable to read angle on line '+str(i+1))
80                fp.close()
81                return False
82            if prevAngle is None:
83                prevAngle = angle
84                continue
85            stepsize = (angle-prevAngle)/(vals-1)
86            prevAngle = angle
87            if self.stepsize is None:
88                self.stepsize = stepsize
89            elif abs(self.stepsize - stepsize) > max(abs(stepsize),abs(self.stepsize))/10000. :
90                print('Inconsistent step size for Rigaku .txt file on line '+
91                        str(i+1) + ' here '+ repr(stepsize) + ' prev '+ repr(self.stepsize))
92                fp.close()
93                return False
94            if j > 30:
95                fp.close()
96                return True
97        fp.close()
98        return False
99           
100    def Reader(self,filename, ParentFrame=None, **kwarg):
101        'Read a Rigaku .txt file'
102        x = []
103        y = []
104        w = []
105        fp = open(filename,'r')
106        for i,line in enumerate(fp):
107            if i < self.skip: continue
108            sline = line.split()
109            try: 
110                angle = float(sline[0])
111            except:
112                print('Unable to read angle on line '+str(i+1))
113                self.errors = 'Error reading line: '+str(i+1)
114                return False
115            for j in sline[1:]:
116                x.append(angle)
117                angle += self.stepsize
118                try: 
119                    y.append(float(j))
120                except:
121                    print('Unable to read intensity on line '+str(i+1))
122                    self.errors = 'Error reading line: '+str(i+1)
123                    return False
124                w.append(1.0/max(1.,float(j)))
125        N = len(x)
126        self.powderdata = [
127            np.array(x), # x-axis values
128            np.array(y), # powder pattern intensities
129            np.array(w), # 1/sig(intensity)^2 values (weights)
130            np.zeros(N), # calc. intensities (zero)
131            np.zeros(N), # calc. background (zero)
132            np.zeros(N), # obs-calc profiles
133            ]
134        self.powderentry[0] = filename
135        #self.powderentry[2] = 1 # xye file only has one bank
136        self.idstring = os.path.basename(filename)
137        return True
138class Rigaku_rasReaderClass(G2obj.ImportPowderData):
139    '''Routines to import powder data from a Rigaku .ras file with multiple scans.
140    All scans will be imported as individual PWDR entries
141    '''
142    def __init__(self):
143        super(self.__class__,self).__init__( # fancy way to self-reference
144            extensionlist=('.ras','.RAS'),
145            strictExtension=True,
146            formatName = 'Rigaku .ras file',
147            longFormatName = 'Rigaku .ras raw multipattern powder data'
148            )
149        self.scriptable = True
150        self.vals = None
151        self.stepsize = None
152        self.skip = 0
153
154    # Validate the contents -- make sure we only have valid lines and set
155    # values we will need for later read.
156    def ContentsValidator(self, filename):
157        if '2' in platform.python_version_tuple()[0]:
158            fp = open(filename,'Ur')
159        else:
160            fp = open(filename,'r',encoding='latin-1')
161        self.vals = None
162        self.stepsize = None
163        fp.seek(0)
164        if fp.readline()[:-1] != '*RAS_DATA_START':
165            self.errors = 'Bad ras file'
166            fp.close()
167            return False
168        nBanks= 0
169        for i,line in enumerate(fp):
170            if line[:-1] == '*RAS_HEADER_START':
171                nBanks += 1
172                self.dnames.append(os.path.basename(filename)+' sample '+(str(nBanks)))
173        if nBanks:
174            if not len(self.selections):
175                self.selections = list(range(nBanks))
176                self.numbanks = nBanks
177        fp.close()
178        return True
179
180    def Reader(self,filename, ParentFrame=None, **kwarg):
181        'Read a Rigaku .ras file'
182        if '2' in platform.python_version_tuple()[0]:
183            fp = open(filename,'Ur')
184        else:
185            fp = open(filename,'r',encoding='latin-1')
186        blockNum = self.selections[0]
187        x = []
188        y = []
189        w = []
190        block = 0
191        while True:
192            line = fp.readline()[:-1]
193            if line != '*RAS_INT_START':
194                continue
195            if block == blockNum:
196                line = fp.readline()[:-1]
197                while True:
198                    if line == '*RAS_INT_END':
199                        break
200                    sline = line.split()
201                    x.append(float(sline[0]))
202                    y.append(float(sline[1]))
203                    w.append(1.0/max(1.,float(y[-1])))
204                    line = fp.readline()[:-1]
205                break
206            block += 1           
207        N = len(x)
208        self.powderdata = [
209            np.array(x), # x-axis values
210            np.array(y), # powder pattern intensities
211            np.array(w), # 1/sig(intensity)^2 values (weights)
212            np.zeros(N), # calc. intensities (zero)
213            np.zeros(N), # calc. background (zero)
214            np.zeros(N), # obs-calc profiles
215            ]
216        self.powderentry[0] = self.dnames[blockNum]
217        self.idstring = self.dnames[blockNum]
218        self.selections.remove(blockNum)
219        self.repeat = False
220        if len(self.selections):
221            self.repeat = True
222        return True
Note: See TracBrowser for help on using the repository browser.