source: trunk/imports/G2sfact.py @ 1910

Last change on this file since 1910 was 1910, checked in by vondreele, 7 years ago

fix reading run-on numbers in Shelx HKLF 4 files
implement all I/O for nonmerohedral twin data from HKLF 5 files
Twin GUI stuff set for mero & nonmero twins

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 22.5 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2015-06-26 19:13:27 +0000 (Fri, 26 Jun 2015) $
4# $Author: vondreele $
5# $Revision: 1910 $
6# $URL: trunk/imports/G2sfact.py $
7# $Id: G2sfact.py 1910 2015-06-26 19:13:27Z vondreele $
8########### SVN repository information ###################
9'''
10*Module G2sfact: simple HKL import*
11-----------------------------------
12Read structure factors from a simple hkl file. Two routines are
13provided to read from files containing F or F\ :sup:`2` values.
14
15'''
16import sys
17import numpy as np
18import copy
19import GSASIIIO as G2IO
20import GSASIIpath
21GSASIIpath.SetVersionNumber("$Revision: 1910 $")
22
23def ColumnValidator(parent, filepointer,nCol=5):
24    'Validate a file to check that it contains columns of numbers'
25    l = filepointer.readline()
26    line = 1
27    while l[0] in ['#','(']:        #get past comments & fortran formats, if any
28        l = filepointer.readline()       
29        line += 1
30    for i in range(10): # scan a few lines
31        S = l.split()
32        if len(S) < nCol:
33            parent.errors = 'line '+str(line)+': invalid input\n'+l
34            return False
35        for v in S[:nCol]:
36            try:
37                float(v)
38            except ValueError:
39                parent.errors = 'line '+str(line)+': string found where a number is expected\n'+l
40                return False           
41        l = filepointer.readline()
42        line += 1
43    return True
44
45
46class HKLF_ReaderClass(G2IO.ImportStructFactor):
47    'Routines to import F, sig(F) reflections from a HKLF file'
48    def __init__(self):
49        super(self.__class__,self).__init__( # fancy way to self-reference
50            extensionlist=('.hkl','.HKL'),
51            strictExtension=False,
52            formatName = 'HKL F',
53            longFormatName = 'Simple [hkl, Fo, sig(Fo)] Structure factor text file'
54            )
55
56    def ContentsValidator(self, filepointer):
57        'Make sure file contains the expected columns on numbers'
58        return ColumnValidator(self, filepointer)
59
60    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
61        'Read the file'
62        try:
63            for line,S in enumerate(filepointer):
64                self.errors = '  Error reading line '+str(line+1)
65                if S[0] == '#': continue       #ignore comments, if any
66                h,k,l,Fo,sigFo = S.split()
67                h,k,l = [int(h),int(k),int(l)]
68                if not any([h,k,l]):
69                    break
70                Fo = float(Fo)
71                sigFo = float(sigFo)
72                # h,k,l,m,dsp,Fo2,sig,Fc2,Fot2,Fct2,phase,...
73                self.RefDict['RefList'].append([h,k,l,0,0,Fo**2,2.*Fo*sigFo,0,Fo**2,0,0,0])
74            self.errors = 'Error after reading reflections (unexpected!)'
75            self.RefDict['RefList'] = np.array(self.RefDict['RefList'])
76            self.RefDict['Type'] = 'SXC'
77            self.RefDict['Super'] = 0
78            self.UpdateParameters(Type='SXC',Wave=None) # histogram type
79            return True
80        except Exception as detail:
81            self.errors += '\n  '+str(detail)
82            print '\n\n'+self.formatName+' read error: '+str(detail) # for testing
83            import traceback
84            traceback.print_exc(file=sys.stdout)
85            return False
86
87class HKLF4_ReaderClass(G2IO.ImportStructFactor):
88    'Routines to import F**2, sig(F**2) reflections from a HKLF 4 file'
89    def __init__(self):
90        if 'linux' in sys.platform:  # wx 3.0.0.0 on gtk does not like Unicode in menus
91            formatName = 'HKLF 4'
92            longFormatName = 'Shelx HKLF 4 [hkl, Fo2, sig(Fo2)] Structure factor text file'
93        else:
94            formatName = u'Shelx HKLF 4 F\u00b2'
95            longFormatName = u'Shelx HKLF 4 [hkl, Fo\u00b2, sig(Fo\u00b2)] Structure factor text file'
96        super(self.__class__,self).__init__( # fancy way to self-reference
97            extensionlist=('.hkl','.HKL'),
98            strictExtension=False,
99            formatName=formatName,
100            longFormatName=longFormatName)
101
102    def ContentsValidator(self, filepointer):
103        'Make sure file contains the expected columns on numbers'
104        return ColumnValidator(self, filepointer)
105
106    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
107        'Read the file'
108        try:
109            for line,S in enumerate(filepointer):
110                self.errors = '  Error reading line '+str(line+1)
111                if S[0] == '#': continue       #ignore comments, if any
112                h,k,l,Fo,sigFo = S[:4],S[4:8],S[8:12],S[12:20],S[20:28]
113                h,k,l = [int(h),int(k),int(l)]
114                if not any([h,k,l]):
115                    break
116                Fo = float(Fo)
117                sigFo = float(sigFo)
118                # h,k,l,m,dsp,Fo2,sig,Fc2,Fot2,Fct2,phase,...
119                self.RefDict['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0])
120                #self.RefDict['FF'].append({}) # now done in OnImportSfact
121            self.errors = 'Error after reading reflections (unexpected!)'
122            self.RefDict['RefList'] = np.array(self.RefDict['RefList'])
123            self.RefDict['Type'] = 'SXC'
124            self.RefDict['Super'] = 0
125            self.UpdateParameters(Type='SXC',Wave=None) # histogram type
126            return True
127        except Exception as detail:
128            self.errors += '\n  '+str(detail)
129            print '\n\n'+self.formatName+' read error: '+str(detail) # for testing
130            import traceback
131            traceback.print_exc(file=sys.stdout)
132            return False
133           
134class SHELX5_ReaderClass(G2IO.ImportStructFactor):
135    'Routines to import F**2, sig(F**2) twin/incommensurate reflections from a fixed format SHELX HKLF5 file'
136    def __init__(self):
137        if 'linux' in sys.platform:  # wx 3.0.0.0 on gtk does not like Unicode in menus
138            formatName = 'SHELX HKLF 5 F2 Tw/Incom'
139            longFormatName = 'SHELX HKLF 5 [hklm, Fo2, sig(Fo2), Tind] Twin/incommensurate structure factor text file'
140        else:
141            formatName = u'SHELX HKLF 5 F\u00b2 Tw/Incom'
142            longFormatName = u'SHELX HKLF 5 [hklm, Fo\u00b2, sig(Fo\u00b2), Tind] Twin/incommensurate structure factor text file'       
143        super(self.__class__,self).__init__( # fancy way to self-reference
144            extensionlist=('.hkl','.HKL'),
145            strictExtension=False,
146            formatName=formatName,
147            longFormatName=longFormatName)
148        self.Super = 0
149
150    def ContentsValidator(self, filepointer):
151        'Discover how many characters are in the SHELX file - could be 32-44 depending on satellites'
152        numCols = 0
153        for i,line in enumerate(filepointer):
154            numCols = max(numCols,len(line.split()))
155            if i > 20:
156                break
157        self.Super = numCols-6     #= 0,1,2,or 3
158        if self.Super > 1:
159            raise self.ImportException("Supersymmetry too high; GSAS-II limited to (3+1) supersymmetry")           
160        return True #ColumnValidator(self, filepointer)
161
162    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
163        'Read the file'
164        TwDict = {}
165        TwSet = {}
166        TwMax = 0
167        try:
168            for line,S in enumerate(filepointer):
169                self.errors = '  Error reading line '+str(line+1)
170                if self.Super == 0:
171                    h,k,l,Fo,sigFo,Tw = S[:4],S[4:8],S[8:12],S[12:20],S[20:28],S[28:32]
172                    h,k,l = [int(h),int(k),int(l)]
173                elif self.Super == 1:
174                    h,k,l,m1,Fo,sigFo,Tw = S[:4],S[4:8],S[8:12],S[12:16],S[16:24],S[24:32],S[32:36]
175                    h,k,l,m1 = [int(h),int(k),int(l),int(m1)]
176                Tw = Tw.strip()
177                if not any([h,k,l]):
178                    break
179                if Tw not in ['','0','1']:
180                    TwId = -int(Tw)-1
181                    TwMax = max(TwMax,TwId)
182                    TwSet[TwId] = [h,k,l]
183                else:
184                    if TwSet:
185                        TwDict[len(self.RefDict['RefList'])] = TwSet
186                        TwSet = {}   
187                    Fo = float(Fo)
188                    sigFo = float(sigFo)
189                    # h,k,l,m,dsp,Fo2,sig,Fc2,Fot2,Fct2,phase,...
190                    if self.Super == 0:
191                        self.RefDict['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0])
192                    elif self.Super == 1:
193                        self.RefDict['RefList'].append([h,k,l,m1,0,0,Fo,sigFo,0,Fo,0,0,0])
194            self.errors = 'Error after reading reflections (unexpected!)'
195            self.RefDict['RefList'] = np.array(self.RefDict['RefList'])
196            self.RefDict['Type'] = 'SXC'
197            self.RefDict['Super'] = self.Super
198            self.RefDict['TwDict'] = TwDict
199            self.RefDict['TwMax'] = TwMax
200            self.UpdateParameters(Type='SXC',Wave=None) # histogram type
201            return True
202        except Exception as detail:
203            self.errors += '\n  '+str(detail)
204            print '\n\n'+self.formatName+' read error: '+str(detail) # for testing
205            import traceback
206            traceback.print_exc(file=sys.stdout)
207            return False
208
209class M90_ReaderClass(G2IO.ImportStructFactor):
210    'Routines to import F**2, sig(F**2) reflections from a JANA M90 file'
211    def __init__(self):
212        if 'linux' in sys.platform:  # wx 3.0.0.0 on gtk does not like Unicode in menus
213            longFormatName = 'JANA [hkl, Fo2, sig(Fo2)] Structure factor text file'
214        else:
215            longFormatName = u'JANA [hkl, Fo\u00b2, sig(Fo\u00b2)] Structure factor text file'
216        super(self.__class__,self).__init__( # fancy way to self-reference
217            extensionlist=('.m90','.M90'),
218            strictExtension=False,
219            formatName = u'JANA M90',
220            longFormatName = longFormatName
221            )
222        self.Super = 0
223
224    def ContentsValidator(self, filepointer):
225        'Discover how many columns are in the m90 file - could be 9-12 depending on satellites'
226        numCols = 0
227        for i,line in enumerate(filepointer):
228            if 'Data' in line:
229                startData = i
230                break
231        for i,line in enumerate(filepointer):
232            if i > startData:
233                numCols = max(numCols,len(line.split()))
234            if i > startData+20:
235                break
236        self.Super = numCols-9     #= 0,1,2,or 3
237        if self.Super > 1:
238            raise self.ImportException("Supersymmetry too high; GSAS-II limited to (3+1) supersymmetry")           
239        return True #ColumnValidator(self, filepointer)
240
241    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
242        'Read the file'
243        try:
244            for line,S in enumerate(filepointer):
245                self.errors = '  Error reading line '+str(line+1)
246                if S[0] == '#': continue       #ignore comments, if any
247                try:
248                    if self.Super == 0:
249                        h,k,l,Fo,sigFo = S.split()[:5]
250                        h,k,l = [int(h),int(k),int(l)]
251                    elif self.Super == 1:
252                        h,k,l,m1,Fo,sigFo = S.split()[:6]
253                        h,k,l,m1 = [int(h),int(k),int(l),int(m1)]
254                except ValueError:  #skipping text at front
255                    if not S:
256                        break
257                    text = S.split()
258                    if text[0] == 'lambda':
259                        wave = float(text[1])
260                    continue
261                Fo = float(Fo)
262                sigFo = float(sigFo)
263                # h,k,l,m,dsp,Fo2,sig,Fc2,Fot2,Fct2,phase,...
264                if self.Super == 0:
265                    self.RefDict['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0])
266                elif self.Super == 1:
267                    self.RefDict['RefList'].append([h,k,l,m1,0,0,Fo,sigFo,0,Fo,0,0,0])
268            self.errors = 'Error after reading reflections (unexpected!)'
269            self.RefDict['RefList'] = np.array(self.RefDict['RefList'])
270            self.RefDict['Type'] = 'SXC'
271            self.RefDict['Super'] = self.Super
272            self.UpdateParameters(Type='SXC',Wave=wave) # histogram type
273            return True
274        except Exception as detail:
275            self.errors += '\n  '+str(detail)
276            print '\n\n'+self.formatName+' read error: '+str(detail) # for testing
277            import traceback
278            traceback.print_exc(file=sys.stdout)
279            return False
280           
281class NT_HKLF2_ReaderClass(G2IO.ImportStructFactor):
282    'Routines to import neutron TOF F**2, sig(F**2) reflections from a HKLF file'
283    def __init__(self):
284        if 'linux' in sys.platform:  # wx 3.0.0.0 on gtk does not like Unicode in menus
285            formatName = 'Neutron TOF HKL F2'
286            longFormatName = 'Neutron TOF [hkl, Fo2, sig(Fo2),...] Structure factor text file'
287        else:
288            formatName = u'Neutron TOF HKL F\u00b2'
289            longFormatName = u'Neutron TOF [hkl, Fo\u00b2, sig(Fo\u00b2),...] Structure factor text file'
290        super(self.__class__,self).__init__( # fancy way to self-reference
291            extensionlist=('.hkl','.HKL'),
292            strictExtension=False,
293            formatName=formatName,
294            longFormatName=longFormatName)
295
296    def ContentsValidator(self, filepointer):
297        'Make sure file contains the expected columns on numbers & count number of data blocks - "Banks"'
298        oldNo = -1
299        for line,S in enumerate(filepointer):
300            if not S:   #empty line terminates read
301                break
302            if S[0] == '#': continue       #ignore comments, if any
303            if S.split()[:3] == ['0','0','0']:
304                break
305            bankNo = S.split()[5]
306            if bankNo != oldNo:
307                self.Banks.append({'RefDict':{'RefList':[],}})
308                oldNo = bankNo
309        filepointer.seek(0)
310        return ColumnValidator(self, filepointer,nCol=8)
311
312    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
313        'Read the file'
314        filepointer.seek(0)
315        try:
316            for line,S in enumerate(filepointer):
317                self.errors = '  Error reading line '+str(line+1)
318                if S[0] == '#': continue       #ignore comments, if any
319                data = S.split()
320                h,k,l,Fo,sigFo,bN,wave,tbar = data[:8]  #bN = 1..., 6 dir cos next                   
321                h,k,l = [int(h),int(k),int(l)]
322                if not any([h,k,l]):
323                    break
324                Fo = float(Fo)
325                sigFo = float(sigFo)
326                wave = float(wave)
327                tbar = float(tbar)
328                if len(self.Banks):
329                    self.Banks[int(bN)-1]['RefDict']['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0,wave,tbar])
330                else:
331                # h,k,l,m,dsp,Fo2,sig,Fc2,Fot2,Fct2,phase,...
332                    self.RefDict['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0,wave,tbar])
333            if len(self.Banks):
334                self.UpdateParameters(Type='SNT',Wave=None) # histogram type
335                for Bank in self.Banks:
336                    Bank['RefDict']['RefList'] = np.array(Bank['RefDict']['RefList'])
337                    Bank['RefDict']['Type'] = 'SNT'                   
338                    Bank['RefDict']['Super'] = 0
339            else:
340                self.RefDict['RefList'] = np.array(self.RefDict['RefList'])
341                self.RefDict['Type'] = 'SNT'
342                self.RefDict['Super'] = 0
343                self.errors = 'Error after reading reflections (unexpected!)'
344                self.UpdateParameters(Type='SNT',Wave=None) # histogram type
345            return True
346        except Exception as detail:
347            self.errors += '\n  '+str(detail)
348            print '\n\n'+self.formatName+' read error: '+str(detail) # for testing
349            import traceback
350            traceback.print_exc(file=sys.stdout)
351            return False
352
353class NT_JANA2K_ReaderClass(G2IO.ImportStructFactor):
354    'Routines to import neutron TOF F**2, sig(F**2) reflections from a JANA2000 file'
355    def __init__(self):
356        if 'linux' in sys.platform:  # wx 3.0.0.0 on gtk does not like Unicode in menus
357            formatName = 'Neutron TOF JANA2000 F2'
358            longFormatName = 'Neutron TOF [hkl, Fo2, sig(Fo2),...] Structure factor text file'
359        else:
360            formatName = u'Neutron TOF JANA2000 F\u00b2'
361            longFormatName = u'Neutron TOF [hkl, Fo\u00b2, sig(Fo\u00b2),...] Structure factor text file'
362        super(self.__class__,self).__init__( # fancy way to self-reference
363            extensionlist=('.int','.INT'),
364            strictExtension=False,
365            formatName=formatName,
366            longFormatName=longFormatName)
367
368    def ContentsValidator(self, filepointer):
369        'Make sure file contains the expected columns on numbers & count number of data blocks - "Banks"'
370        oldNo = -1
371        for line,S in enumerate(filepointer):
372            if not S:   #empty line terminates read
373                break
374            if S[0] in ['#','(']: continue       #ignore comments & fortran format line
375            bankNo = S.split()[5]
376            if bankNo != oldNo:
377                self.Banks.append({'RefDict':{'RefList':[],}})
378                oldNo = bankNo
379        filepointer.seek(0)
380        return ColumnValidator(self, filepointer,nCol=10)
381
382    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
383        'Read the file'
384        filepointer.seek(0)
385        try:
386            for line,S in enumerate(filepointer):
387                self.errors = '  Error reading line '+str(line+1)
388                if S[0] in ['#','(']: continue       #ignore comments & fortran format line
389                data = S.split()
390                h,k,l,Fo,sigFo,bN,wave,x,x,tbar = data[:10]  #bN = 1..., 6 dir cos next                   
391                h,k,l = [int(h),int(k),int(l)]
392                if not any([h,k,l]):
393                    break
394                Fo = float(Fo)
395                sigFo = float(sigFo)
396                wave = float(wave)
397                tbar = float(tbar)
398                if len(self.Banks):
399                    self.Banks[int(bN)-1]['RefDict']['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0,wave,tbar])
400                else:
401                # h,k,l,m,dsp,Fo2,sig,Fc2,Fot2,Fct2,phase,...
402                    self.RefDict['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0,wave,tbar])
403            if len(self.Banks):
404                self.UpdateParameters(Type='SNT',Wave=None) # histogram type
405                for Bank in self.Banks:
406                    Bank['RefDict']['RefList'] = np.array(Bank['RefDict']['RefList'])
407                    Bank['RefDict']['Type'] = 'SNT'                   
408                    Bank['RefDict']['Super'] = 0        #for now                   
409            else:
410                self.RefDict['RefList'] = np.array(self.RefDict['RefList'])
411                self.RefDict['Type'] = 'SNT'
412                self.RefDict['Super'] = 0   #for now
413                self.errors = 'Error after reading reflections (unexpected!)'
414                self.UpdateParameters(Type='SNT',Wave=None) # histogram type
415            return True
416        except Exception as detail:
417            self.errors += '\n  '+str(detail)
418            print '\n\n'+self.formatName+' read error: '+str(detail) # for testing
419            import traceback
420            traceback.print_exc(file=sys.stdout)
421            return False
422
423class ISIS_SXD_INT_ReaderClass(G2IO.ImportStructFactor):
424    'Routines to import neutron TOF F**2, sig(F**2) reflections from a ISIS int file'
425    def __init__(self):
426        if 'linux' in sys.platform:  # wx 3.0.0.0 on gtk does not like Unicode in menus
427            formatName = u'Neutron SXD TOF HKL F2'
428            longFormatName = u'Neutron SXD TOF [hkl, Fo2, sig(Fo2),...] Structure factor text file'
429        else:
430            formatName = u'Neutron SXD TOF HKL F\u00b2'
431            longFormatName = u'Neutron SXD TOF [hkl, Fo\u00b2, sig(Fo\u00b2),...] Structure factor text file'
432        super(self.__class__,self).__init__( # fancy way to self-reference
433            extensionlist=('.int','.INT'),
434            strictExtension=False,
435            formatName=formatName,
436            longFormatName=longFormatName)
437
438    def ContentsValidator(self, filepointer):
439        'Make sure file contains the expected columns on numbers & count number of data blocks - "Banks"'
440        oldNo = -1
441        for line,S in enumerate(filepointer):
442            if not S:   #empty line terminates read
443                break
444            if S[0] == '#': continue       #ignore comments, if any
445            if S[0] == '(': continue        #ignore format line
446            bankNo = S.split()[5]
447            if bankNo != oldNo:
448                self.Banks.append({'RefDict':{'RefList':[],}})
449                oldNo = bankNo
450        filepointer.seek(0)
451        return ColumnValidator(self, filepointer,nCol=8)
452
453    def Reader(self,filename,filepointer, ParentFrame=None, **unused):
454        'Read the file'
455        filepointer.seek(0)
456        try:
457            for line,S in enumerate(filepointer):
458                self.errors = '  Error reading line '+str(line+1)
459                if S[0] == '#': continue       #ignore comments, if any
460                if S[0] == '(': continue        #ignore the format line
461                data = S.split()
462                h,k,l,Fo,sigFo,bN,wave,x,x,tbar = data[:10]                   
463                h,k,l = [int(h),int(k),int(l)]
464                if not any([h,k,l]):
465                    break
466                Fo = float(Fo)
467                sigFo = float(sigFo)
468                wave = float(wave)
469                tbar = float(tbar)
470                if len(self.Banks):
471                    self.Banks[int(bN)-1]['RefDict']['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0,wave,tbar])
472                else:
473                # h,k,l,m,dsp,Fo2,sig,Fc2,Fot2,Fct2,phase,...
474                    self.RefDict['RefList'].append([h,k,l,0,0,Fo,sigFo,0,Fo,0,0,0,wave,tbar])
475            if len(self.Banks):
476                self.UpdateParameters(Type='SNT',Wave=None) # histogram type
477                for Bank in self.Banks:
478                    Bank['RefDict']['RefList'] = np.array(Bank['RefDict']['RefList'])
479                    Bank['RefDict']['Type'] = 'SNT'                   
480                    Bank['RefDict']['Super'] = 0
481            else:
482                self.RefDict['RefList'] = np.array(self.RefDict['RefList'])
483                self.RefDict['Type'] = 'SNT'
484                self.RefDict['Super'] = 0
485                self.errors = 'Error after reading reflections (unexpected!)'
486                self.UpdateParameters(Type='SNT',Wave=None) # histogram type
487            return True
488        except Exception as detail:
489            self.errors += '\n  '+str(detail)
490            print '\n\n'+self.formatName+' read error: '+str(detail) # for testing
491            import traceback
492            traceback.print_exc(file=sys.stdout)
493            return False
494
Note: See TracBrowser for help on using the repository browser.