source: trunk/G2importsfact_CIF.py @ 580

Last change on this file since 580 was 580, checked in by toby, 10 years ago

finish import structure factor; refactor import classes

File size: 8.4 KB
Line 
1########### SVN repository information ###################
2# $Date: 2012-02-13 11:33:35 -0600 (Mon, 13 Feb 2012) $
3# $Author: vondreele & toby $
4# $Revision: 482 $
5# $URL: https://subversion.xor.aps.anl.gov/pyGSAS/trunk/G2importphase.py $
6# $Id: G2importphase.py 482 2012-02-13 17:33:35Z vondreele $
7########### SVN repository information ###################
8# routines to read in structure factors from a CIF
9#
10import sys
11import numpy as np
12import GSASIIIO as G2IO
13import CifFile as cif # PyCifRW from James Hester
14import urllib
15
16class CIFhklReader(G2IO.ImportStructFactor):
17    'Routines to import Phase information from a CIF file'
18    def __init__(self):
19        super(self.__class__,self).__init__( # fancy way to self-reference
20            extensionlist=('.CIF','.cif'),
21            strictExtension=False,
22            formatName = 'CIF',
23            longFormatName = 'Reflections from CIF'
24            )
25    # Validate the contents
26    def ContentsValidator(self, filepointer):
27        for i,line in enumerate(filepointer):
28            if i >= 1000: break
29            ''' Encountered only blank lines or comments in first 1000
30            lines. This is unlikely, but assume it is CIF since we are
31            even less likely to find a file with nothing but hashes and
32            blank lines'''
33            line = line.strip()
34            if len(line) == 0:
35                continue # ignore blank lines
36            elif line.startswith('#'):
37                continue # ignore comments
38            elif line.startswith('data_'):
39                return True
40            else:
41                return False # found something else
42        return True
43    def Reader(self,filename,filepointer, ParentFrame=None):
44        hklitems = ('_refln_index_h','_refln_index_k','_refln_index_l')
45        cellitems = (
46            '_cell_length_a','_cell_length_b','_cell_length_c',
47            '_cell_angle_alpha','_cell_angle_beta','_cell_angle_gamma',)
48        phasenamefields = (
49            '_chemical_name_common',
50            '_pd_phase_name',
51            '_chemical_formula_sum'
52            )
53        try:
54            self.ShowBusy() # this can take a while
55            ciffile = 'file:'+urllib.pathname2url(filename)
56            cf = cif.ReadCif(ciffile)
57            self.DoneBusy()
58            # scan blocks for reflections
59            blklist = []
60            blktype = []
61            for blk in cf.keys():
62                blkkeys = [k.lower() for k in cf[blk].keys()]
63                gotFo = True
64                gotFo2 = True
65                for r in hklitems:
66                    if r not in blkkeys:
67                        gotFo = False
68                        gotFo2 = False
69                if '_refln_f_squared_meas' not in blkkeys:
70                    gotFo = False
71                if '_refln_f_squared_meas' not in blkkeys:
72                    gotFo2 = False
73                if gotFo or gotFo2:
74                    blklist.append(blk)
75                    blktype.append(gotFo2)
76            if not blklist:
77                selblk = None # no block to choose
78            elif len(blklist) == 1: # only one choice
79                selblk = 0
80            else:                       # choose from options
81                choice = []
82                for blknm in blklist:
83                    choice.append('')
84                    # accumumlate some info about this phase
85                    choice[-1] += blknm + ': '
86                    for i in phasenamefields: # get a name for the phase
87                        name = cf[blknm].get(i)
88                        if name is None or name == '?' or name == '.':
89                            continue
90                        else:
91                            choice[-1] += name.strip()[:20] + ', '
92                            break
93                    s = ''
94                    fmt = "%.2f,"
95                    for i,key in enumerate(cellitems):
96                        if i == 3: fmt = "%.f,"
97                        if i == 5: fmt = "%.f"
98                        val = cf[blknm].get(key)
99                        if val is None: break
100                        s += fmt % cif.get_number_with_esd(
101                            )[0]
102                    if s: choice[-1] += ', cell: ' + s
103                    sg = cf[blknm].get("_symmetry_space_group_name_H-M")
104                    if sg: choice[-1] += ', (' + sg.strip() + ')'
105                selblk = self.BlockSelector(
106                    choice,
107                    ParentFrame=ParentFrame,
108                    title='Select a dataset from one the CIF data_ blocks below',
109                    size=(600,100),
110                    header='Dataset Selector')
111            if selblk is None:
112                return False # no block selected or available
113            else:
114                blknm = blklist[selblk]
115                blk = cf[blklist[selblk]]
116                # read in reflections
117                refloop = blk.GetLoop('_refln_index_h')
118                itemkeys = {}
119                # prepare an index to the CIF reflection loop
120                for i,key in enumerate(refloop.keys()):
121                    itemkeys[key.lower()] = i
122                if '_refln_f_squared_calc' in itemkeys:
123                    FcalcPresent = True
124                elif '_refln_f_calc' in itemkeys:
125                    FcalcPresent = True
126                else:
127                    FcalcPresent = False
128                for item in refloop:
129                    HKL = []
130                    for i in hklitems: # ('_refln_index_h','_refln_index_k','_refln_index_l')
131                        num = itemkeys.get(i)
132                        try:
133                            HKL.append(int(item[num]))
134                        except:
135                            HKL.append('.')
136                    ref = [HKL,0.,0.,0,0,0,0]  # HKL. Fo**2, sig(Fo**2), Fc, Fcp, Fcpp & phase
137                    # get F or F**2 and sigma
138                    if '_refln_f_squared_meas' in itemkeys:
139                        try:
140                            ref[1] = float(item[itemkeys['_refln_f_squared_meas']])
141                        except:
142                            pass
143                        if  '_refln_f_squared_sigma' in itemkeys:
144                            try:
145                                ref[2] = float(item[itemkeys['_refln_f_squared_sigma']])
146                            except:
147                                pass                           
148                    elif '_refln_f_meas' in itemkeys:
149                        try:
150                            ref[1] = float(item[itemkeys['_refln_f_meas']])**2
151                        except:
152                            pass                               
153                        if  '_refln_f_sigma' in itemkeys:
154                            try:
155                                ref[2] = 2.*sqrt(ref[1])*float(item[itemkeys['_refln_f_sigma']])
156                            except:
157                                pass                               
158                    if '_refln_f_squared_calc' in itemkeys:
159                        try:
160                            ref[3] = float(item[itemkeys['_refln_f_squared_calc']])
161                        except:
162                            pass                               
163                    elif '_refln_f_calc' in itemkeys:
164                        try:
165                            ref[3] = float(item[itemkeys['_refln_f_calc']])**2
166                        except:
167                            pass                               
168                    if '_refln_phase_calc' in itemkeys:
169                        try:
170                            ref[6] = float(item[itemkeys['_refln_phase_calc']])
171                        except:
172                            pass                               
173 
174                    self.RefList.append(ref)
175                self.UpdateControls(Type='Fosq',FcalcPresent=FcalcPresent) # set Fobs type & if Fcalc values are loaded
176                if blk.get('_diffrn_radiation_probe'):
177                    if blk['_diffrn_radiation_probe'] == 'neutron':
178                        type = 'SNC'
179                else:
180                    type = 'SXC'
181                if blk.get('_diffrn_radiation_wavelength'):
182                    wave = blk['_diffrn_radiation_wavelength']
183                else:
184                    wave = None
185                self.UpdateParameters(Type=type,Wave=wave) # histogram type
186                return True
187        except Exception as detail:
188            print self.formatName+' read error:'+str(detail) # for testing
189            import traceback
190            traceback.print_exc(file=sys.stdout)
191        return False
Note: See TracBrowser for help on using the repository browser.