source: trunk/imports/G2phase_CIF.py @ 1883

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

revise cif importer to handle atoms without type. Atom name is stripped of numbers, '+' & '-'. Warning message changed.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 26.9 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2015-06-08 18:26:43 +0000 (Mon, 08 Jun 2015) $
4# $Author: vondreele $
5# $Revision: 1883 $
6# $URL: trunk/imports/G2phase_CIF.py $
7# $Id: G2phase_CIF.py 1883 2015-06-08 18:26:43Z vondreele $
8########### SVN repository information ###################
9'''
10*Module G2phase_CIF: Coordinates from CIF*
11------------------------------------------
12
13Parses a CIF using  PyCifRW from James Hester and pulls out the
14structural information.
15
16If a CIF generated by ISODISTORT is encountered, extra information is
17added to the phase entry and constraints are generated.
18
19'''
20# Routines to import Phase information from CIF files
21import sys
22import random as ran
23import numpy as np
24import re
25import GSASIIIO as G2IO
26import GSASIIobj as G2obj
27import GSASIIspc as G2spc
28import GSASIIElem as G2elem
29import GSASIIlattice as G2lat
30import GSASIIpy3 as G2p3
31import GSASIIpath
32GSASIIpath.SetVersionNumber("$Revision: 1883 $")
33import CifFile as cif # PyCifRW from James Hester
34
35class CIFPhaseReader(G2IO.ImportPhase):
36    'Implements a phase importer from a possibly multi-block CIF file'
37    def __init__(self):
38        super(self.__class__,self).__init__( # fancy way to say ImportPhase.__init__
39            extensionlist=('.CIF','.cif','.txt'),
40            strictExtension=False,
41            formatName = 'CIF',
42            longFormatName = 'Crystallographic Information File import'
43            )
44       
45    def ContentsValidator(self, filepointer):
46        return self.CIFValidator(filepointer)
47
48    def Reader(self,filename,filepointer, ParentFrame=None, usedRanIdList=[], **unused):
49        self.isodistort_warnings = ''
50        self.Phase = G2IO.SetNewPhase(Name='new phase',SGData=G2IO.P1SGData) # create a new empty phase dict
51        # make sure the ranId is really unique!
52        while self.Phase['ranId'] in usedRanIdList:
53            self.Phase['ranId'] = ran.randint(0,sys.maxint)
54        returnstat = False
55        cellitems = (
56            '_cell_length_a','_cell_length_b','_cell_length_c',
57            '_cell_angle_alpha','_cell_angle_beta','_cell_angle_gamma',)
58        cellwaveitems = (
59            '_cell_wave_vector_seq_id',
60            '_cell_wave_vector_x','_cell_wave_vector_y','_cell_wave_vector_z')
61        reqitems = (
62             '_atom_site_fract_x',
63             '_atom_site_fract_y',
64             '_atom_site_fract_z',
65            )
66        phasenamefields = (
67            '_chemical_name_common',
68            '_pd_phase_name',
69            '_chemical_formula_sum'
70            )
71        try:
72            self.ShowBusy() # this can take a while
73            try:
74                cf = G2IO.ReadCIF(filename)
75            except Exception as detail:
76                self.errors = "Parse or reading of file failed in pyCifRW; check syntax of file in enCIFer or CheckCIF"
77                return False
78            finally:
79                self.DoneBusy()
80            # scan blocks for structural info
81            self.errors = 'Error during scan of blocks for datasets'
82            str_blklist = []
83            for blk in cf.keys():
84                for r in reqitems+cellitems:
85                    if r not in cf[blk].keys():
86                        break
87                else:
88                    str_blklist.append(blk)
89            if not str_blklist:
90                selblk = None # no block to choose
91            elif len(str_blklist) == 1: # only one choice
92                selblk = 0
93            else:                       # choose from options
94                choice = []
95                for blknm in str_blklist:
96                    choice.append('')
97                    # accumumlate some info about this phase
98                    choice[-1] += blknm + ': '
99                    for i in phasenamefields: # get a name for the phase
100                        name = cf[blknm].get(i).strip()
101                        if name is None or name == '?' or name == '.':
102                            continue
103                        else:
104                            choice[-1] += name.strip()[:20] + ', '
105                            break
106                    na = len(cf[blknm].get("_atom_site_fract_x"))
107                    if na == 1:
108                        choice[-1] += '1 atom'
109                    else:
110                        choice[-1] += ('%d' % nd) + ' atoms'
111                    choice[-1] += ', cell: '
112                    fmt = "%.2f,"
113                    for i,key in enumerate(cellitems):
114                        if i == 3: fmt = "%.f,"
115                        if i == 5: fmt = "%.f"
116                        choice[-1] += fmt % cif.get_number_with_esd(
117                            cf[blknm].get(key))[0]
118                    sg = cf[blknm].get("_symmetry_space_group_name_H-M",'')
119                    if not sg: sg = cf[blknm].get("_space_group_name_H-M_alt",'')
120                    if sg: choice[-1] += ', (' + sg.strip() + ')'
121                selblk = self.PhaseSelector(
122                    choice,
123                    ParentFrame=ParentFrame,
124                    title= 'Select a phase from one the CIF data_ blocks below',
125                    size=(600,100)
126                    )
127            self.errors = 'Error during reading of selected block'
128            if selblk is None:
129                returnstat = False # no block selected or available
130            else:
131                blknm = str_blklist[selblk]
132                blk = cf[str_blklist[selblk]]
133                E = True
134                Super = False
135                SpGrp = blk.get("_symmetry_space_group_name_H-M",'')
136                if not SpGrp:
137                    SpGrp = blk.get("_space_group_name_H-M_alt",'')
138                if not SpGrp:
139                    sspgrp = blk.get("_space_group_ssg_name",'').split('(')
140                    SpGrp = sspgrp[0]
141                    SuperSg = '('+sspgrp[1].replace('\\','')
142                    Super = True
143                    SuperVec = [[0,0,.1],False,4]
144                # try normalizing the space group, to see if we can pick the space group out of a table
145                SpGrpNorm = G2spc.StandardizeSpcName(SpGrp)
146                if SpGrpNorm:
147                    E,SGData = G2spc.SpcGroup(SpGrpNorm)
148                # nope, try the space group "out of the Box"
149                if E and SpGrp:
150                    E,SGData = G2spc.SpcGroup(SpGrp)
151                if E:
152                    if not SpGrp:
153                        self.warnings += 'No space group name was found in the CIF.'
154                        self.warnings += '\nThe space group has been set to "P 1". '
155                        self.warnings += "Change this in phase's General tab."
156                    else:
157                        self.warnings += 'ERROR in space group symbol '+SpGrp
158                        self.warnings += '\nThe space group has been set to "P 1". '
159                        self.warnings += "Change this in phase's General tab."
160                        self.warnings += '\nAre there spaces separating axial fields?\n\nError msg: '
161                        self.warnings += G2spc.SGErrors(E)
162                    SGData = G2IO.SGData # P 1
163                self.Phase['General']['SGData'] = SGData
164                # cell parameters
165                cell = []
166                for lbl in cellitems:
167                    cell.append(cif.get_number_with_esd(blk[lbl])[0])
168                Volume = G2lat.calc_V(G2lat.cell2A(cell))
169                self.Phase['General']['Cell'] = [False,]+cell+[Volume,]
170                # read in atoms
171                self.errors = 'Error during reading of atoms'
172                atomlbllist = [] # table to look up atom IDs
173                atomloop = blk.GetLoop('_atom_site_label')
174                atomkeys = [i.lower() for i in atomloop.keys()]
175                if not blk.get('_atom_site_type_symbol'):
176                    self.isodistort_warnings += '\natom types are missing. \n Check & revise atom types as needed'
177                if blk.get('_atom_site_aniso_label'):
178                    anisoloop = blk.GetLoop('_atom_site_aniso_label')
179                    anisokeys = [i.lower() for i in anisoloop.keys()]
180                else:
181                    anisoloop = None
182                    anisokeys = []
183                self.Phase['Atoms'] = []
184                G2AtomDict = {  '_atom_site_type_symbol' : 1,
185                                '_atom_site_label' : 0,
186                                '_atom_site_fract_x' : 3,
187                                '_atom_site_fract_y' : 4,
188                                '_atom_site_fract_z' : 5,
189                                '_atom_site_occupancy' : 6,
190                                '_atom_site_aniso_u_11' : 11,
191                                '_atom_site_aniso_u_22' : 12,
192                                '_atom_site_aniso_u_33' : 13,
193                                '_atom_site_aniso_u_12' : 14,
194                                '_atom_site_aniso_u_13' : 15,
195                                '_atom_site_aniso_u_23' : 16, }
196                ranIdlookup = {}
197                for aitem in atomloop:
198                    atomlist = ['','','',0,0,0,1.0,'',0,'I',0.01,0,0,0,0,0,0,0]
199                    atomlist[-1] = ran.randint(0,sys.maxint) # add a random Id
200                    while atomlist[-1] in ranIdlookup:
201                        atomlist[-1] = ran.randint(0,sys.maxint) # make it unique
202                    for val,key in zip(aitem,atomkeys):
203                        col = G2AtomDict.get(key)
204                        if col >= 3:
205                            atomlist[col] = cif.get_number_with_esd(val)[0]
206                        elif col is not None:
207                            atomlist[col] = val
208                        elif key in ('_atom_site_thermal_displace_type',
209                                   '_atom_site_adp_type'):   #Iso or Aniso?
210                            if val.lower() == 'uani':
211                                atomlist[9] = 'A'
212                        elif key == '_atom_site_u_iso_or_equiv':
213                            atomlist[10] =cif.get_number_with_esd(val)[0]
214                    if not atomlist[1] and atomlist[0]:
215                        typ = atomlist[0].rstrip('0123456789-+')
216                        if G2elem.CheckElement(typ):
217                            atomlist[1] = typ
218                        if not atomlist[1]: atomlist[1] = 'Xe'
219                    ulbl = '_atom_site_aniso_label'
220                    if  atomlist[9] == 'A' and atomlist[0] in blk.get(ulbl):
221                        for val,key in zip(anisoloop.GetKeyedPacket(ulbl,atomlist[0]),
222                                           anisokeys):
223                            col = G2AtomDict.get(key)
224                            if col:
225                                atomlist[col] = cif.get_number_with_esd(val)[0]
226                    atomlist[7],atomlist[8] = G2spc.SytSym(atomlist[3:6],SGData)
227                    atomlist[1] = G2elem.FixValence(atomlist[1])
228                    self.Phase['Atoms'].append(atomlist)
229                    ranIdlookup[atomlist[0]] = atomlist[-1]
230                    if atomlist[0] in atomlbllist:
231                        self.warnings += ' ERROR: repeated atom label: '+atomlist[0]
232                    else:
233                        atomlbllist.append(atomlist[0])
234                if len(atomlbllist) != len(self.Phase['Atoms']):
235                    self.isodistort_warnings += '\nRepeated atom labels prevents ISODISTORT decode'
236                for lbl in phasenamefields: # get a name for the phase
237                    name = blk.get(lbl)
238                    if name is None:
239                        continue
240                    name = name.strip()
241                    if name == '?' or name == '.':
242                        continue
243                    else:
244                        break
245                else: # no name found, use block name for lack of a better choice
246                    name = blknm
247                self.Phase['General']['Name'] = name.strip()[:20]
248                self.Phase['General']['Super'] = Super
249                if Super:
250                    self.Phase['General']['Type'] = 'modulated'
251                    self.Phase['General']['SuperVec'] = SuperVec
252                    self.Phase['General']['SuperSg'] = SuperSg
253                    self.Phase['General']['SSGData'] = G2spc.SSpcGroup(SGData,SuperSg)[1]
254                if not self.isodistort_warnings:
255                    if blk.get('_iso_displacivemode_label') or blk.get('_iso_occupancymode_label'):
256                        self.errors = "Error while processing ISODISTORT constraints"
257                        self.ISODISTORT_proc(blk,atomlbllist,ranIdlookup)
258                else:
259                    self.warnings += self.isodistort_warnings
260                returnstat = True
261        except Exception as detail:
262            self.errors += '\n  '+str(detail)
263            print 'CIF error:',detail # for testing
264            print sys.exc_info()[0] # for testing
265            import traceback
266            print traceback.format_exc()
267            returnstat = False
268        return returnstat
269
270    def ISODISTORT_proc(self,blk,atomlbllist,ranIdlookup):
271        'Process ISODISTORT items to create constraints etc.'
272        varLookup = {'dx':'dAx','dy':'dAy','dz':'dAz','do':'Afrac'}
273        'Maps ISODISTORT parm names to GSAS-II names'
274        #----------------------------------------------------------------------
275        # read in the ISODISTORT displacement modes
276        #----------------------------------------------------------------------
277        self.Constraints = []
278        explaination = {}
279        if blk.get('_iso_displacivemode_label'):
280            modelist = []
281            shortmodelist = []
282            for lbl in blk.get('_iso_displacivemode_label'):
283                modelist.append(lbl)
284                # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
285                # where SSSSS is the parent spacegroup, [x,y,z] is a location
286                regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
287                # this extracts the AAAAA and BBBBB parts of the string
288                if regexp:
289                    lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
290                G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
291            # read in the coordinate offset variables names and map them to G2 names/objects
292            coordVarLbl = []
293            G2varLbl = []
294            G2varObj = []
295            error = False
296            for lbl in blk.get('_iso_deltacoordinate_label'):
297                coordVarLbl.append(lbl)
298                if '_' in lbl:
299                    albl = lbl[:lbl.rfind('_')]
300                    vlbl = lbl[lbl.rfind('_')+1:]
301                else:
302                    self.warnings += ' ERROR: _iso_deltacoordinate_label not parsed: '+lbl
303                    error = True
304                    continue
305                if albl not in atomlbllist:
306                    self.warnings += ' ERROR: _iso_deltacoordinate_label atom not found: '+lbl
307                    error = True
308                    continue
309                else:
310                    anum = atomlbllist.index(albl)
311                var = varLookup.get(vlbl)
312                if not var:
313                    self.warnings += ' ERROR: _iso_deltacoordinate_label variable not found: '+lbl
314                    error = True
315                    continue
316                G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID
317                G2varObj.append(G2obj.G2VarObj(
318                    (self.Phase['ranId'],None,var,ranIdlookup[albl])
319                    ))
320            if error:
321                raise Exception,"Error decoding variable labels"
322
323            if len(G2varObj) != len(modelist):
324                print "non-square input"
325                raise Exception,"Rank of _iso_displacivemode != _iso_deltacoordinate"
326
327            error = False
328            ParentCoordinates = {}
329            for lbl,exp in zip(
330                blk.get('_iso_coordinate_label'),
331                blk.get('_iso_coordinate_formula'),
332                ):
333                if '_' in lbl:
334                    albl = lbl[:lbl.rfind('_')]
335                    vlbl = lbl[lbl.rfind('_')+1:]
336                else:
337                    self.warnings += ' ERROR: _iso_coordinate_label not parsed: '+lbl
338                    error = True
339                    continue
340                if vlbl not in 'xyz' or len(vlbl) != 1:
341                    self.warnings += ' ERROR: _iso_coordinate_label coordinate not parsed: '+lbl
342                    error = True
343                    continue
344                i = 'xyz'.index(vlbl)
345                if not ParentCoordinates.get(albl):
346                    ParentCoordinates[albl] = [None,None,None]
347                if '+' in exp:
348                    val = exp.split('+')[0].strip()
349                    val = G2p3.FormulaEval(val)
350                    if val is None:
351                        self.warnings += ' ERROR: _iso_coordinate_formula coordinate not interpreted: '+lbl
352                        error = True
353                        continue
354                    ParentCoordinates[albl][i] = val
355                else:
356                    ParentCoordinates[albl][i] = G2p3.FormulaEval(exp)
357            if error:
358                print self.warnings
359                raise Exception,"Error decoding variable labels"
360            # get mapping of modes to atomic coordinate displacements
361            displacivemodematrix = np.zeros((len(G2varObj),len(G2varObj)))
362            for row,col,val in zip(
363                blk.get('_iso_displacivemodematrix_row'),
364                blk.get('_iso_displacivemodematrix_col'),
365                blk.get('_iso_displacivemodematrix_value'),):
366                displacivemodematrix[int(row)-1,int(col)-1] = float(val)
367            # Invert to get mapping of atom displacements to modes
368            displacivemodeInvmatrix = np.linalg.inv(displacivemodematrix)
369            # create the constraints
370            for i,row in enumerate(displacivemodeInvmatrix):
371                constraint = []
372                for j,(lbl,k) in enumerate(zip(coordVarLbl,row)):
373                    if k == 0: continue
374                    constraint.append([k,G2varObj[j]])
375                constraint += [shortmodelist[i],False,'f']
376                self.Constraints.append(constraint)
377            #----------------------------------------------------------------------
378            # save the ISODISTORT info for "mode analysis"
379            if 'ISODISTORT' not in self.Phase: self.Phase['ISODISTORT'] = {}
380            self.Phase['ISODISTORT'].update({
381                'IsoModeList' : modelist,
382                'G2ModeList' : shortmodelist,
383                'IsoVarList' : coordVarLbl,
384                'G2VarList' : G2varObj,
385                'ParentStructure' : ParentCoordinates,
386                'Var2ModeMatrix' : displacivemodeInvmatrix,
387                'Mode2VarMatrix' : displacivemodematrix,
388                })
389            # make explaination dictionary
390            for mode,shortmode in zip(modelist,shortmodelist):
391                explaination[shortmode] = "ISODISTORT full name "+str(mode)
392        #----------------------------------------------------------------------
393        # now read in the ISODISTORT occupancy modes
394        #----------------------------------------------------------------------
395        if blk.get('_iso_occupancymode_label'):
396            modelist = []
397            shortmodelist = []
398            for lbl in blk.get('_iso_occupancymode_label'):
399                modelist.append(lbl)
400                # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
401                # where SSSSS is the parent spacegroup, [x,y,z] is a location
402                regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
403                # this extracts the AAAAA and BBBBB parts of the string
404                if regexp:
405                    lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
406                lbl = lbl.replace('order','o')
407                G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
408            # read in the coordinate offset variables names and map them to G2 names/objects
409            occVarLbl = []
410            G2varLbl = []
411            G2varObj = []
412            error = False
413            for lbl in blk.get('_iso_deltaoccupancy_label'):
414                occVarLbl.append(lbl)
415                if '_' in lbl:
416                    albl = lbl[:lbl.rfind('_')]
417                    vlbl = lbl[lbl.rfind('_')+1:]
418                else:
419                    self.warnings += ' ERROR: _iso_deltaoccupancy_label not parsed: '+lbl
420                    error = True
421                    continue
422                if albl not in atomlbllist:
423                    self.warnings += ' ERROR: _iso_deltaoccupancy_label atom not found: '+lbl
424                    error = True
425                    continue
426                else:
427                    anum = atomlbllist.index(albl)
428                var = varLookup.get(vlbl)
429                if not var:
430                    self.warnings += ' ERROR: _iso_deltaoccupancy_label variable not found: '+lbl
431                    error = True
432                    continue
433                G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID
434                G2varObj.append(G2obj.G2VarObj(
435                    (self.Phase['ranId'],None,var,ranIdlookup[albl])
436                    ))
437            if error:
438                raise Exception,"Error decoding variable labels"
439
440            if len(G2varObj) != len(modelist):
441                print "non-square input"
442                raise Exception,"Rank of _iso_occupancymode != _iso_deltaoccupancy"
443
444            error = False
445            ParentCoordinates = {}
446            for lbl,exp in zip(
447                blk.get('_iso_occupancy_label'),
448                blk.get('_iso_occupancy_formula'),
449                ):
450                if '_' in lbl:
451                    albl = lbl[:lbl.rfind('_')]
452                    vlbl = lbl[lbl.rfind('_')+1:]
453                else:
454                    self.warnings += ' ERROR: _iso_occupancy_label not parsed: '+lbl
455                    error = True
456                    continue
457                if vlbl != 'occ':
458                    self.warnings += ' ERROR: _iso_occupancy_label coordinate not parsed: '+lbl
459                    error = True
460                    continue
461                if '+' in exp:
462                    val = exp.split('+')[0].strip()
463                    val = G2p3.FormulaEval(val)
464                    if val is None:
465                        self.warnings += ' ERROR: _iso_occupancy_formula coordinate not interpreted: '+lbl
466                        error = True
467                        continue
468                    ParentCoordinates[albl] = val
469            if error:
470                raise Exception,"Error decoding occupancy labels"
471            # get mapping of modes to atomic coordinate displacements
472            occupancymodematrix = np.zeros((len(G2varObj),len(G2varObj)))
473            for row,col,val in zip(
474                blk.get('_iso_occupancymodematrix_row'),
475                blk.get('_iso_occupancymodematrix_col'),
476                blk.get('_iso_occupancymodematrix_value'),):
477                occupancymodematrix[int(row)-1,int(col)-1] = float(val)
478            # Invert to get mapping of atom displacements to modes
479            occupancymodeInvmatrix = np.linalg.inv(occupancymodematrix)
480            # create the constraints
481            for i,row in enumerate(occupancymodeInvmatrix):
482                constraint = []
483                for j,(lbl,k) in enumerate(zip(occVarLbl,row)):
484                    if k == 0: continue
485                    constraint.append([k,G2varObj[j]])
486                constraint += [shortmodelist[i],False,'f']
487                self.Constraints.append(constraint)
488            #----------------------------------------------------------------------
489            # save the ISODISTORT info for "mode analysis"
490            if 'ISODISTORT' not in self.Phase: self.Phase['ISODISTORT'] = {}
491            self.Phase['ISODISTORT'].update({
492                'OccModeList' : modelist,
493                'G2OccModeList' : shortmodelist,
494                'OccVarList' : occVarLbl,
495                'G2OccVarList' : G2varObj,
496                'BaseOcc' : ParentCoordinates,
497                'Var2OccMatrix' : occupancymodeInvmatrix,
498                'Occ2VarMatrix' : occupancymodematrix,
499                })
500            # make explaination dictionary
501            for mode,shortmode in zip(modelist,shortmodelist):
502                explaination[shortmode] = "ISODISTORT full name "+str(mode)
503        #----------------------------------------------------------------------
504        # done with read
505        #----------------------------------------------------------------------
506        if explaination: self.Constraints.append(explaination)
507
508        # # debug: show the mode var to mode relations
509        # for i,row in enumerate(displacivemodeInvmatrix):
510        #     l = ''
511        #     for j,(lbl,k) in enumerate(zip(coordVarLbl,row)):
512        #         if k == 0: continue
513        #         if l: l += ' + '
514        #         #l += lbl+' * '+str(k)
515        #         l += G2varLbl[j]+' * '+str(k)
516        #     print str(i) + ': '+shortmodelist[i]+' = '+l
517        # print 70*'='
518
519        # # debug: Get the ISODISTORT offset values
520        # coordVarDelta = {}
521        # for lbl,val in zip(
522        #     blk.get('_iso_deltacoordinate_label'),
523        #     blk.get('_iso_deltacoordinate_value'),):
524        #     coordVarDelta[lbl] = float(val)
525        # modeVarDelta = {}
526        # for lbl,val in zip(
527        #     blk.get('_iso_displacivemode_label'),
528        #     blk.get('_iso_displacivemode_value'),):
529        #     modeVarDelta[lbl] = cif.get_number_with_esd(val)[0]
530
531        # print 70*'='
532        # # compute the mode values from the reported coordinate deltas
533        # for i,row in enumerate(displacivemodeInvmatrix):
534        #     l = ''
535        #     sl = ''
536        #     s = 0.
537        #     for lbl,k in zip(coordVarLbl,row):
538        #         if k == 0: continue
539        #         if l: l += ' + '
540        #         l += lbl+' * '+str(k)
541        #         if sl: sl += ' + '
542        #         sl += str(coordVarDelta[lbl])+' * '+str(k)
543        #         s += coordVarDelta[lbl] * k
544        #     print 'a'+str(i)+' = '+l
545        #     print '\t= '+sl
546        #     print  modelist[i],shortmodelist[i],modeVarDelta[modelist[i]],s
547        #     print
548
549        # print 70*'='
550        # # compute the coordinate displacements from the reported mode values
551        # for i,lbl,row in zip(range(len(coordVarLbl)),coordVarLbl,displacivemodematrix):
552        #     l = ''
553        #     sl = ''
554        #     s = 0.0
555        #     for j,k in enumerate(row):
556        #         if k == 0: continue
557        #         if l: l += ' + '
558        #         l += 'a'+str(j+1)+' * '+str(k)
559        #         if sl: sl += ' + '
560        #         sl += str(shortmodelist[j]) +' = '+ str(modeVarDelta[modelist[j]]) + ' * '+str(k)
561        #         s += modeVarDelta[modelist[j]] * k
562        #     print lbl+' = '+l
563        #     print '\t= '+sl
564        #     print lbl,G2varLbl[i],coordVarDelta[lbl],s
565        #     print
566
567        # determine the coordinate delta values from deviations from the parent structure
568        # for atmline in self.Phase['Atoms']:
569        #     lbl = atmline[0]
570        #     x,y,z = atmline[3:6]
571        #     if lbl not in ParentCoordinates:
572        #         print lbl,x,y,z
573        #         continue
574        #     px,py,pz = ParentCoordinates[lbl]
575        #     print lbl,x,y,z,x-px,y-py,z-pz
Note: See TracBrowser for help on using the repository browser.