source: trunk/imports/G2pwd_BrukerRAW.py @ 3979

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

fix problem reading two different vintages of Bruker raw1.01 files; they differ by 40 bytes for start of pattern

File size: 10.1 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2014-12-27 11:14:59 -0600 (Sat, 27 Dec 2014) $
4# $Author: vondreele $
5# $Revision: 1620 $
6# $URL: https://subversion.xray.aps.anl.gov/pyGSAS/trunk/imports/G2pwd_xye.py $
7# $Id: G2pwd_xye.py 1620 2014-12-27 17:14:59Z vondreele $
8########### SVN repository information ###################
9'''
10*Module G2pwd_BrukerRAW: Bruker v.1-v.3 .raw data*
11---------------------------------------------------
12
13Routine to read in powder data from a Bruker versions 1-3 .raw file
14
15'''
16
17from __future__ import division, print_function
18import os.path as ospath
19import struct as st
20import numpy as np
21import GSASIIobj as G2obj
22import GSASIIpath
23GSASIIpath.SetVersionNumber("$Revision: 1620 $")
24class raw_ReaderClass(G2obj.ImportPowderData):
25    'Routines to import powder data from a binary Bruker .RAW file'
26    def __init__(self):
27        super(self.__class__,self).__init__( # fancy way to self-reference
28            extensionlist=('.RAW',),
29            strictExtension=False,
30            formatName = 'Bruker RAW',
31            longFormatName = 'Bruker .RAW powder data file'
32            )
33        self.scriptable = True
34
35    # Validate the contents -- make sure we only have valid lines
36    def Read(self,fp,nbytes):
37        data = fp.read(nbytes)
38        if 'bytes' in str(type(data)):
39            data = data.decode('latin-1')
40        return data
41   
42    def ContentsValidator(self, filename):
43        'Look through the file for expected types of lines in a valid Bruker RAW file'
44        fp = open(filename,'rb')
45        head = self.Read(fp,7)
46        if 'bytes' in str(type(head)):
47            head = head.decode('latin-1')
48        if head[:4] == 'RAW ':
49            self.formatName = 'Bruker RAW ver. 1'
50        elif head[:4] == 'RAW2':
51            self.formatName = 'Bruker RAW ver. 2'
52        elif head == 'RAW1.01':
53            self.formatName = 'Bruker RAW ver. 3'
54        elif head == 'RAW4.00':
55            self.formatName = 'Bruker RAW ver. 4'
56            self.errors += "Sorry, this is a Version 4 Bruker file. "
57            self.errors += "We need documentation for it so that it can be implemented in GSAS-II. "
58            self.errors += "Use PowDLL (http://users.uoi.gr/nkourkou/powdll/) to convert it to ASCII xy."
59            print(self.errors)
60            fp.close()
61            return False
62        else:
63            self.errors = 'Unexpected information in header: '
64            if all([ord(c) < 128 and ord(c) != 0 for c in str(head)]): # show only if ASCII
65                self.errors += '  '+str(head)
66            else: 
67                self.errors += '  (binary)'
68            fp.close()
69            return False
70        fp.close()
71        return True
72           
73    def Reader(self,filename, ParentFrame=None, **kwarg):
74        'Read a Bruker RAW file'
75        self.comments = []
76        self.powderentry[0] = filename
77        fp = open(filename,'rb')
78        if 'ver. 1' in self.formatName:
79            raise Exception    #for now
80        elif 'ver. 2' in self.formatName:
81            fp.seek(4)
82            nBlock = int(st.unpack('<i',fp.read(4))[0])
83            fp.seek(168)
84            self.comments.append('Date/Time='+self.Read(fp,20))
85            self.comments.append('Anode='+self.Read(fp,2))
86            self.comments.append('Ka1=%.5f'%(st.unpack('<f',fp.read(4))[0]))
87            self.comments.append('Ka2=%.5f'%(st.unpack('<f',fp.read(4))[0]))
88            self.comments.append('Ka2/Ka1=%.5f'%(st.unpack('<f',fp.read(4))[0]))
89            fp.seek(206)
90            self.comments.append('Kb=%.5f'%(st.unpack('<f',fp.read(4))[0]))
91            pos = 256
92            fp.seek(pos)
93            blockNum = kwarg.get('blocknum',0)
94            self.idstring = ospath.basename(filename) + ' Scan '+str(blockNum)
95            if blockNum <= nBlock:
96                for iBlock in range(blockNum):
97                    headLen = int(st.unpack('<H',fp.read(2))[0])
98                    nSteps = int(st.unpack('<H',fp.read(2))[0])
99                    if iBlock+1 == blockNum:
100                        fp.seek(pos+12)
101                        step = st.unpack('<f',fp.read(4))[0]
102                        start2Th = st.unpack('<f',fp.read(4))[0]
103                        pos += headLen      #position at start of data block
104                        fp.seek(pos)                                   
105                        x = np.array([start2Th+i*step for i in range(nSteps)])
106                        y = np.array([max(1.,st.unpack('<f',fp.read(4))[0]) for i in range(nSteps)])
107                        y = np.where(y<0.,y,1.)
108                        w = 1./y
109                        self.powderdata = [x,y,w,np.zeros(nSteps),np.zeros(nSteps),np.zeros(nSteps)]
110                        break
111                    pos += headLen+4*nSteps
112                    fp.seek(pos)
113                if blockNum == nBlock:
114                    self.repeat = False                                   
115                else:
116                    self.repeat = True
117            fp.close()
118        elif 'ver. 3' in self.formatName:
119            fp.seek(12)
120            nBlock = int(st.unpack('<i',fp.read(4))[0])
121            self.comments.append('Date='+self.Read(fp,10))
122            self.comments.append('Time='+self.Read(fp,10))
123            fp.seek(326)
124            self.comments.append('Sample='+self.Read(fp,60))
125            fp.seek(564)
126            radius = st.unpack('<f',fp.read(4))[0]
127            self.comments.append('Gonio. radius=%.2f'%(radius))
128            self.Sample['Gonio. radius'] = radius
129            fp.seek(608)
130            self.comments.append('Anode='+self.Read(fp,4))
131            fp.seek(616)
132            self.comments.append('Ka mean=%.5f'%(st.unpack('<d',fp.read(8))[0]))
133            self.comments.append('Ka1=%.5f'%(st.unpack('<d',fp.read(8))[0]))
134            self.comments.append('Ka2=%.5f'%(st.unpack('<d',fp.read(8))[0]))
135            self.comments.append('Kb=%.5f'%(st.unpack('<d',fp.read(8))[0]))
136            self.comments.append('Ka2/Ka1=%.5f'%(st.unpack('<d',fp.read(8))[0]))
137            pos = 712
138            fp.seek(pos)      #position at 1st block header
139            blockNum = kwarg.get('blocknum',0)
140            self.idstring = ospath.basename(filename) + ' Scan '+str(blockNum)
141            if blockNum <= nBlock:
142                for iBlock in range(blockNum):
143                    headLen = int(st.unpack('<i',fp.read(4))[0])
144                    nSteps = int(st.unpack('<i',fp.read(4))[0])
145                    if not nSteps: break
146                    if nBlock > 1:
147                        fp.seek(pos+256)
148                        headLen += st.unpack('<i',fp.read(4))[0]
149                    else:
150                        headLen += 40
151                    if iBlock+1 == blockNum:
152                        fp.seek(pos+8)
153                        st.unpack('<d',fp.read(8))[0]
154                        start2Th = st.unpack('<d',fp.read(8))[0]
155                        fp.seek(pos+212)
156                        temp = st.unpack('<f',fp.read(4))[0]
157                        if temp > 0.:
158                            self.Sample['Temperature'] = temp                                                       
159                        fp.seek(pos+176)
160                        step = st.unpack('<d',fp.read(8))[0]
161                        pos += headLen      #position at start of data block
162                        fp.seek(pos)
163                        x = np.array([start2Th+i*step for i in range(nSteps)])
164                        try:
165                            y = np.array([max(1.,st.unpack('<f',fp.read(4))[0]) for i in range(nSteps)])
166                        except: #this is absurd
167                            fp.seek(pos-40)
168                            y = np.array([max(1.,st.unpack('<f',fp.read(4))[0]) for i in range(nSteps)])
169                        w = 1./y
170                        self.powderdata = [x,y,w,np.zeros(nSteps),np.zeros(nSteps),np.zeros(nSteps)]
171                        break
172                    pos += headLen+4*nSteps
173                    fp.seek(pos)
174                if blockNum == nBlock:
175                    self.repeat = False
176                else:
177                    self.repeat = True
178            fp.close()
179           
180        elif 'ver. 4' in self.formatName:   #does not work - format still elusive
181            fp.seek(12)   #ok
182            self.comments.append('Date='+self.Read(fp,10))
183            self.comments.append('Time='+self.Read(fp,10))
184            fp.seek(144)
185            self.comments.append('Sample='+self.Read(fp,60))
186            fp.seek(564)  # where is it?
187            radius = st.unpack('<f',fp.read(4))[0]
188            self.comments.append('Gonio. radius=%.2f'%(radius))
189            self.Sample['Gonio. radius'] = radius
190            fp.seek(516)  #ok
191            self.comments.append('Anode='+self.Read(fp,4))
192            fp.seek(472)  #ok
193            self.comments.append('Ka mean=%.5f'%(st.unpack('<d',fp.read(8))[0]))
194            self.comments.append('Ka1=%.5f'%(st.unpack('<d',fp.read(8))[0]))
195            self.comments.append('Ka2=%.5f'%(st.unpack('<d',fp.read(8))[0]))
196            self.comments.append('Kb=%.5f'%(st.unpack('<d',fp.read(8))[0]))
197            self.comments.append('Ka2/Ka1=%.5f'%(st.unpack('<d',fp.read(8))[0]))
198            fp.seek(pos)  #deliberate fail here - pos not known from file contents
199            self.idstring = ospath.basename(filename) + ' Scan '+str(1)
200            nSteps = int(st.unpack('<i',fp.read(4))[0])
201            st.unpack('<d',fp.read(8))[0]
202            start2Th = st.unpack('<d',fp.read(8))[0]
203            fp.seek(pos+176)
204            step = st.unpack('<d',fp.read(8))[0]
205            pos += headLen      #position at start of data block
206            fp.seek(pos)                                   
207            x = np.array([start2Th+i*step for i in range(nSteps)])
208            y = np.array([max(1.,st.unpack('<f',fp.read(4))[0]) for i in range(nSteps)])
209            w = 1./y
210            self.powderdata = [x,y,w,np.zeros(nSteps),np.zeros(nSteps),np.zeros(nSteps)]
211            fp.close()
212        else:
213            return False
214           
215        return True
Note: See TracBrowser for help on using the repository browser.