source: trunk/imports/G2sfact_CIF.py @ 1106

Last change on this file since 1106 was 1106, checked in by vondreele, 8 years ago

modify reflection array to be a dictionary with 4 items: RefList?, Uniq, Phi & FF. Each is list. Use patches to convert old format to new in various places.
Fix bug in simulate PWDR code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 10.1 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2013-10-15 17:25:24 +0000 (Tue, 15 Oct 2013) $
4# $Author: vondreele $
5# $Revision: 1106 $
6# $URL: trunk/imports/G2sfact_CIF.py $
7# $Id: G2sfact_CIF.py 1106 2013-10-15 17:25:24Z vondreele $
8########### SVN repository information ###################
9# routines to read in structure factors from a CIF
10#
11import sys
12import numpy as np
13import os.path
14import GSASIIIO as G2IO
15import GSASIIpath
16GSASIIpath.SetVersionNumber("$Revision: 1106 $")
17import CifFile as cif # PyCifRW from James Hester
18
19class CIFhklReader(G2IO.ImportStructFactor):
20    'Routines to import Phase information from a CIF file'
21    def __init__(self):
22        super(self.__class__,self).__init__( # fancy way to self-reference
23            extensionlist = ('.CIF','.cif','.FCF','.fcf','.HKL','.hkl'),
24            strictExtension = False,
25            formatName = 'CIF',
26            longFormatName = 'CIF format structure factor file (.cif or .hkl)'
27            )
28    # Validate the contents
29    def ContentsValidator(self, filepointer):
30        for i,line in enumerate(filepointer):
31            if i >= 1000: break
32            ''' Encountered only blank lines or comments in first 1000
33            lines. This is unlikely, but assume it is CIF since we are
34            even less likely to find a file with nothing but hashes and
35            blank lines'''
36            line = line.strip()
37            if len(line) == 0:
38                continue # ignore blank lines
39            elif line.startswith('#'):
40                continue # ignore comments
41            elif line.startswith('data_'):
42                return True
43            else:
44                return False # found something else
45        return True
46    def Reader(self,filename,filepointer, ParentFrame=None, **kwarg):
47        hklitems = ('_refln_index_h','_refln_index_k','_refln_index_l')
48        cellitems = (
49            '_cell_length_a','_cell_length_b','_cell_length_c',
50            '_cell_angle_alpha','_cell_angle_beta','_cell_angle_gamma',)
51        phasenamefields = (
52            '_chemical_name_common',
53            '_pd_phase_name',
54            '_chemical_formula_sum'
55            )
56        rdbuffer = kwarg.get('buffer')
57        cf = None
58        try:
59            if self.repeat and rdbuffer is not None:
60                cf = rdbuffer.get('lastcif')
61                print 'Reuse previously parsed CIF'
62            if cf is None:
63                self.ShowBusy() # this can take a while
64                cf = G2IO.ReadCIF(filename)
65                self.DoneBusy()
66            # scan blocks for reflections
67            blklist = []
68            blktype = []
69            for blk in cf.keys():
70                blkkeys = [k.lower() for k in cf[blk].keys()]
71                gotFo = True
72                gotFo2 = True
73                for r in hklitems:
74                    if r not in blkkeys:
75                        gotFo = False
76                        gotFo2 = False
77                if '_refln_f_squared_meas' not in blkkeys:
78                    gotFo = False
79                if '_refln_f_squared_meas' not in blkkeys:
80                    gotFo2 = False
81                if gotFo or gotFo2:
82                    blklist.append(blk)
83                    blktype.append(gotFo2)
84            if not blklist:
85                selblk = None # no block to choose
86            elif len(blklist) == 1: # only one choice
87                selblk = 0
88            else:                       # choose from options
89                choice = []
90                for blknm in blklist:
91                    choice.append('')
92                    # accumumlate some info about this phase
93                    choice[-1] += blknm + ': '
94                    for i in phasenamefields: # get a name for the phase
95                        name = cf[blknm].get(i)
96                        if name is None or name == '?' or name == '.':
97                            continue
98                        else:
99                            choice[-1] += name.strip()[:20] + ', '
100                            break
101                    s = ''
102                    fmt = "%.2f,"
103                    for i,key in enumerate(cellitems):
104                        if i == 3: fmt = "%.f,"
105                        if i == 5: fmt = "%.f"
106                        val = cf[blknm].get(key)
107                        if val is None: break
108                        s += fmt % cif.get_number_with_esd(val)[0]
109                    if s: choice[-1] += ', cell: ' + s
110                    sg = cf[blknm].get("_symmetry_space_group_name_H-M")
111                    if sg: choice[-1] += ', (' + sg.strip() + ')'
112                choice.append('Import all of the above')
113                if self.repeat: # we were called to repeat the read
114                    selblk = self.repeatcount
115                    self.repeatcount += 1
116                    if self.repeatcount >= len(blklist): self.repeat = False
117                else:
118                    selblk = self.BlockSelector(
119                        choice,
120                        ParentFrame=ParentFrame,
121                        title='Select a dataset from one the CIF data_ blocks below',
122                        size=(600,100),
123                        header='Dataset Selector')
124            if selblk is None:
125                return False # no block selected or available
126            if selblk >= len(blklist): # all blocks selected
127                selblk = 0
128                self.repeat = True
129                if rdbuffer is not None:
130                    rdbuffer['lastcif'] = cf # save the parsed cif for the next loop
131                self.repeatcount = 1
132            blknm = blklist[selblk]
133            blk = cf[blklist[selblk]]
134            self.objname = os.path.basename(filename)+':'+str(blknm)
135            # read in reflections
136            refloop = blk.GetLoop('_refln_index_h')
137            itemkeys = {}
138            # prepare an index to the CIF reflection loop
139            for i,key in enumerate(refloop.keys()):
140                itemkeys[key.lower()] = i
141            if '_refln_f_squared_calc' in itemkeys:
142                FcalcPresent = True
143            elif '_refln_f_calc' in itemkeys:
144                FcalcPresent = True
145            else:
146                FcalcPresent = False
147            for item in refloop:
148                HKL = []
149                for i in hklitems: # ('_refln_index_h','_refln_index_k','_refln_index_l')
150                    num = itemkeys.get(i)
151                    try:
152                        HKL.append(int(item[num]))
153                    except:
154                        HKL.append('.')
155                #h,k,l,m,dsp,Fo2,sig,Fc2,Fot2,Fct2,phase,...
156                ref = HKL+[0,0,0,0,0,0,0,0,[],[],0,{}] 
157#                ref = HKL+[0,0,0,0,0,0,0,0,0]
158                if '_refln_f_squared_meas' in itemkeys:
159                    try:
160                        Fsq = float(item[itemkeys['_refln_f_squared_meas']])
161                        ref[8] = Fsq
162                        ref[5] = Fsq
163                    except:
164                        try:
165                            Fsq,Esd = item[itemkeys['_refln_f_squared_meas']].split('(')
166                            Fsq = float(Fsq)
167                            ref[8] = Fsq
168                            ref[5] = Fsq
169                            ref[6] = float(Esd[:-1])
170                        except:
171                            pass
172                    if  '_refln_f_squared_sigma' in itemkeys:
173                        try:
174                            ref[6] = float(item[itemkeys['_refln_f_squared_sigma']])
175                        except:
176                            pass                           
177                elif '_refln_f_meas' in itemkeys:
178                    try:
179                        Fsq = float(item[itemkeys['_refln_f_meas']])**2
180                        ref[8] = Fsq
181                        ref[5] = Fsq
182                    except:
183                        try:
184                            Fsq,Esd = item[itemkeys['_refln_f_squared_meas']].split('(')
185                            Fsq = float(Fsq)**2
186                            ref[8] = Fsq
187                            ref[5] = Fsq
188                            ref[6] = 2.0*sqrt(Fsq)*float(Esd[:-1])
189                        except:
190                            pass                               
191                    if  '_refln_f_sigma' in itemkeys:
192                        try:
193                            ref[6] = 2.*sqrt(ref[8])*float(item[itemkeys['_refln_f_sigma']])
194                        except:
195                            pass                               
196                if '_refln_f_squared_calc' in itemkeys:
197                    try:
198                        Fsq = float(item[itemkeys['_refln_f_squared_calc']])
199                        ref[9] = Fsq
200                        ref[7] = Fsq
201                    except:
202                        pass                               
203                elif '_refln_f_calc' in itemkeys:
204                    try:
205                        Fsq = float(item[itemkeys['_refln_f_calc']])**2
206                        ref[9] = Fsq
207                        ref[7] = Fsq
208                    except:
209                        pass                               
210                if '_refln_phase_calc' in itemkeys:
211                    try:
212                        ref[10] = float(item[itemkeys['_refln_phase_calc']])
213                    except:
214                        pass                               
215                self.RefDict['RefList'].append(ref)
216                self.RefDict['Uniq'].append([])
217                self.RefDict['Phi'].append([])
218                self.RefDict['FF'].append({})
219            self.UpdateControls(Type='Fosq',FcalcPresent=FcalcPresent) # set Fobs type & if Fcalc values are loaded
220            if blk.get('_diffrn_radiation_probe'):
221                if blk['_diffrn_radiation_probe'] == 'neutron':
222                    type = 'SNC'
223            else:
224                type = 'SXC'
225            if blk.get('_diffrn_radiation_wavelength'):
226                wave = float(blk['_diffrn_radiation_wavelength'])
227            else:
228                wave = None
229            self.UpdateParameters(Type=type,Wave=wave) # histogram type
230            return True
231        except Exception as detail:
232            print self.formatName+' read error:'+str(detail) # for testing
233            import traceback
234            traceback.print_exc(file=sys.stdout)
235        return False
Note: See TracBrowser for help on using the repository browser.