source: trunk/imports/G2sfact_CIF.py @ 623

Last change on this file since 623 was 623, checked in by vondreele, 10 years ago

remove powder read from Data menu
remove 'menu' from import menus
use longFormatName as help for import menu items
remove _init_coll_Import_Items
added updateHKLFdata to process HKLF data sets

File size: 9.4 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2012-02-13 11:33:35 -0600 (Mon, 13 Feb 2012) $
4# $Author: vondreele & toby $
5# $Revision: 482 $
6# $URL: https://subversion.xor.aps.anl.gov/pyGSAS/trunk/G2importphase.py $
7# $Id: G2importphase.py 482 2012-02-13 17:33:35Z 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 CifFile as cif # PyCifRW from James Hester
16import urllib
17
18class CIFhklReader(G2IO.ImportStructFactor):
19    'Routines to import Phase information from a CIF file'
20    def __init__(self):
21        super(self.__class__,self).__init__( # fancy way to self-reference
22            extensionlist=('.CIF','.cif','.HKL','.hkl'),
23            strictExtension=False,
24            formatName = 'CIF',
25            longFormatName = 'CIF format structure factor file (.cif or .hkl)'
26            )
27    # Validate the contents
28    def ContentsValidator(self, filepointer):
29        for i,line in enumerate(filepointer):
30            if i >= 1000: break
31            ''' Encountered only blank lines or comments in first 1000
32            lines. This is unlikely, but assume it is CIF since we are
33            even less likely to find a file with nothing but hashes and
34            blank lines'''
35            line = line.strip()
36            if len(line) == 0:
37                continue # ignore blank lines
38            elif line.startswith('#'):
39                continue # ignore comments
40            elif line.startswith('data_'):
41                return True
42            else:
43                return False # found something else
44        return True
45    def Reader(self,filename,filepointer, ParentFrame=None, **kwarg):
46        hklitems = ('_refln_index_h','_refln_index_k','_refln_index_l')
47        cellitems = (
48            '_cell_length_a','_cell_length_b','_cell_length_c',
49            '_cell_angle_alpha','_cell_angle_beta','_cell_angle_gamma',)
50        phasenamefields = (
51            '_chemical_name_common',
52            '_pd_phase_name',
53            '_chemical_formula_sum'
54            )
55        rdbuffer = kwarg.get('buffer')
56        cf = None
57        try:
58            if self.repeat and rdbuffer is not None:
59                cf = rdbuffer.get('lastcif')
60                print 'Reuse previously parsed CIF'
61            if cf is None:
62                self.ShowBusy() # this can take a while
63                ciffile = 'file:'+urllib.pathname2url(filename)
64                cf = cif.ReadCif(ciffile)
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                if '_refln_f_squared_meas' in itemkeys:
158                    try:
159                        Fsq = float(item[itemkeys['_refln_f_squared_meas']])
160                        ref[8] = Fsq
161                        ref[5] = Fsq
162                    except:
163                        pass
164                    if  '_refln_f_squared_sigma' in itemkeys:
165                        try:
166                            ref[6] = float(item[itemkeys['_refln_f_squared_sigma']])
167                        except:
168                            pass                           
169                elif '_refln_f_meas' in itemkeys:
170                    try:
171                        Fsq = float(item[itemkeys['_refln_f_meas']])**2
172                        ref[8] = Fsq
173                        ref[5] = Fsq
174                    except:
175                        pass                               
176                    if  '_refln_f_sigma' in itemkeys:
177                        try:
178                            ref[6] = 2.*sqrt(ref[8])*float(item[itemkeys['_refln_f_sigma']])
179                        except:
180                            pass                               
181                if '_refln_f_squared_calc' in itemkeys:
182                    try:
183                        Fsq = float(item[itemkeys['_refln_f_squared_calc']])
184                        ref[9] = Fsq
185                        ref[7] = Fsq
186                    except:
187                        pass                               
188                elif '_refln_f_calc' in itemkeys:
189                    try:
190                        Fsq = float(item[itemkeys['_refln_f_calc']])**2
191                        ref[9] = Fsq
192                        ref[7] = Fsq
193                    except:
194                        pass                               
195                if '_refln_phase_calc' in itemkeys:
196                    try:
197                        ref[10] = float(item[itemkeys['_refln_phase_calc']])
198                    except:
199                        pass                               
200                self.RefList.append(ref)
201            self.UpdateControls(Type='Fosq',FcalcPresent=FcalcPresent) # set Fobs type & if Fcalc values are loaded
202            if blk.get('_diffrn_radiation_probe'):
203                if blk['_diffrn_radiation_probe'] == 'neutron':
204                    type = 'SNC'
205            else:
206                type = 'SXC'
207            if blk.get('_diffrn_radiation_wavelength'):
208                wave = blk['_diffrn_radiation_wavelength']
209            else:
210                wave = None
211            self.UpdateParameters(Type=type,Wave=wave) # histogram type
212            return True
213        except Exception as detail:
214            print self.formatName+' read error:'+str(detail) # for testing
215            import traceback
216            traceback.print_exc(file=sys.stdout)
217        return False
Note: See TracBrowser for help on using the repository browser.