source: trunk/imports/G2phase_CIF.py @ 1982

Last change on this file since 1982 was 1982, checked in by vondreele, 6 years ago

add messages to cif import fail to identify atoms

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 27.0 KB
Line 
1# -*- coding: utf-8 -*-
2########### SVN repository information ###################
3# $Date: 2015-09-29 20:46:51 +0000 (Tue, 29 Sep 2015) $
4# $Author: vondreele $
5# $Revision: 1982 $
6# $URL: trunk/imports/G2phase_CIF.py $
7# $Id: G2phase_CIF.py 1982 2015-09-29 20:46:51Z 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: 1982 $")
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]:
219                            atomlist[1] = 'Xe'
220                            self.warnings += ' Atom type '+typ+' not recognized; Xe assumed\n'
221                    ulbl = '_atom_site_aniso_label'
222                    if  atomlist[9] == 'A' and atomlist[0] in blk.get(ulbl):
223                        for val,key in zip(anisoloop.GetKeyedPacket(ulbl,atomlist[0]),
224                                           anisokeys):
225                            col = G2AtomDict.get(key)
226                            if col:
227                                atomlist[col] = cif.get_number_with_esd(val)[0]
228                    atomlist[7],atomlist[8] = G2spc.SytSym(atomlist[3:6],SGData)
229                    atomlist[1] = G2elem.FixValence(atomlist[1])
230                    self.Phase['Atoms'].append(atomlist)
231                    ranIdlookup[atomlist[0]] = atomlist[-1]
232                    if atomlist[0] in atomlbllist:
233                        self.warnings += ' ERROR: repeated atom label: '+atomlist[0]
234                    else:
235                        atomlbllist.append(atomlist[0])
236                if len(atomlbllist) != len(self.Phase['Atoms']):
237                    self.isodistort_warnings += '\nRepeated atom labels prevents ISODISTORT decode'
238                for lbl in phasenamefields: # get a name for the phase
239                    name = blk.get(lbl)
240                    if name is None:
241                        continue
242                    name = name.strip()
243                    if name == '?' or name == '.':
244                        continue
245                    else:
246                        break
247                else: # no name found, use block name for lack of a better choice
248                    name = blknm
249                self.Phase['General']['Name'] = name.strip()[:20]
250                self.Phase['General']['Super'] = Super
251                if Super:
252                    self.Phase['General']['Type'] = 'modulated'
253                    self.Phase['General']['SuperVec'] = SuperVec
254                    self.Phase['General']['SuperSg'] = SuperSg
255                    self.Phase['General']['SSGData'] = G2spc.SSpcGroup(SGData,SuperSg)[1]
256                if not self.isodistort_warnings:
257                    if blk.get('_iso_displacivemode_label') or blk.get('_iso_occupancymode_label'):
258                        self.errors = "Error while processing ISODISTORT constraints"
259                        self.ISODISTORT_proc(blk,atomlbllist,ranIdlookup)
260                else:
261                    self.warnings += self.isodistort_warnings
262                returnstat = True
263        except Exception as detail:
264            self.errors += '\n  '+str(detail)
265            print 'CIF error:',detail # for testing
266            print sys.exc_info()[0] # for testing
267            import traceback
268            print traceback.format_exc()
269            returnstat = False
270        return returnstat
271
272    def ISODISTORT_proc(self,blk,atomlbllist,ranIdlookup):
273        'Process ISODISTORT items to create constraints etc.'
274        varLookup = {'dx':'dAx','dy':'dAy','dz':'dAz','do':'Afrac'}
275        'Maps ISODISTORT parm names to GSAS-II names'
276        #----------------------------------------------------------------------
277        # read in the ISODISTORT displacement modes
278        #----------------------------------------------------------------------
279        self.Constraints = []
280        explaination = {}
281        if blk.get('_iso_displacivemode_label'):
282            modelist = []
283            shortmodelist = []
284            for lbl in blk.get('_iso_displacivemode_label'):
285                modelist.append(lbl)
286                # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
287                # where SSSSS is the parent spacegroup, [x,y,z] is a location
288                regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
289                # this extracts the AAAAA and BBBBB parts of the string
290                if regexp:
291                    lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
292                G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
293            # read in the coordinate offset variables names and map them to G2 names/objects
294            coordVarLbl = []
295            G2varLbl = []
296            G2varObj = []
297            error = False
298            for lbl in blk.get('_iso_deltacoordinate_label'):
299                coordVarLbl.append(lbl)
300                if '_' in lbl:
301                    albl = lbl[:lbl.rfind('_')]
302                    vlbl = lbl[lbl.rfind('_')+1:]
303                else:
304                    self.warnings += ' ERROR: _iso_deltacoordinate_label not parsed: '+lbl
305                    error = True
306                    continue
307                if albl not in atomlbllist:
308                    self.warnings += ' ERROR: _iso_deltacoordinate_label atom not found: '+lbl
309                    error = True
310                    continue
311                else:
312                    anum = atomlbllist.index(albl)
313                var = varLookup.get(vlbl)
314                if not var:
315                    self.warnings += ' ERROR: _iso_deltacoordinate_label variable not found: '+lbl
316                    error = True
317                    continue
318                G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID
319                G2varObj.append(G2obj.G2VarObj(
320                    (self.Phase['ranId'],None,var,ranIdlookup[albl])
321                    ))
322            if error:
323                raise Exception,"Error decoding variable labels"
324
325            if len(G2varObj) != len(modelist):
326                print "non-square input"
327                raise Exception,"Rank of _iso_displacivemode != _iso_deltacoordinate"
328
329            error = False
330            ParentCoordinates = {}
331            for lbl,exp in zip(
332                blk.get('_iso_coordinate_label'),
333                blk.get('_iso_coordinate_formula'),
334                ):
335                if '_' in lbl:
336                    albl = lbl[:lbl.rfind('_')]
337                    vlbl = lbl[lbl.rfind('_')+1:]
338                else:
339                    self.warnings += ' ERROR: _iso_coordinate_label not parsed: '+lbl
340                    error = True
341                    continue
342                if vlbl not in 'xyz' or len(vlbl) != 1:
343                    self.warnings += ' ERROR: _iso_coordinate_label coordinate not parsed: '+lbl
344                    error = True
345                    continue
346                i = 'xyz'.index(vlbl)
347                if not ParentCoordinates.get(albl):
348                    ParentCoordinates[albl] = [None,None,None]
349                if '+' in exp:
350                    val = exp.split('+')[0].strip()
351                    val = G2p3.FormulaEval(val)
352                    if val is None:
353                        self.warnings += ' ERROR: _iso_coordinate_formula coordinate not interpreted: '+lbl
354                        error = True
355                        continue
356                    ParentCoordinates[albl][i] = val
357                else:
358                    ParentCoordinates[albl][i] = G2p3.FormulaEval(exp)
359            if error:
360                print self.warnings
361                raise Exception,"Error decoding variable labels"
362            # get mapping of modes to atomic coordinate displacements
363            displacivemodematrix = np.zeros((len(G2varObj),len(G2varObj)))
364            for row,col,val in zip(
365                blk.get('_iso_displacivemodematrix_row'),
366                blk.get('_iso_displacivemodematrix_col'),
367                blk.get('_iso_displacivemodematrix_value'),):
368                displacivemodematrix[int(row)-1,int(col)-1] = float(val)
369            # Invert to get mapping of atom displacements to modes
370            displacivemodeInvmatrix = np.linalg.inv(displacivemodematrix)
371            # create the constraints
372            for i,row in enumerate(displacivemodeInvmatrix):
373                constraint = []
374                for j,(lbl,k) in enumerate(zip(coordVarLbl,row)):
375                    if k == 0: continue
376                    constraint.append([k,G2varObj[j]])
377                constraint += [shortmodelist[i],False,'f']
378                self.Constraints.append(constraint)
379            #----------------------------------------------------------------------
380            # save the ISODISTORT info for "mode analysis"
381            if 'ISODISTORT' not in self.Phase: self.Phase['ISODISTORT'] = {}
382            self.Phase['ISODISTORT'].update({
383                'IsoModeList' : modelist,
384                'G2ModeList' : shortmodelist,
385                'IsoVarList' : coordVarLbl,
386                'G2VarList' : G2varObj,
387                'ParentStructure' : ParentCoordinates,
388                'Var2ModeMatrix' : displacivemodeInvmatrix,
389                'Mode2VarMatrix' : displacivemodematrix,
390                })
391            # make explaination dictionary
392            for mode,shortmode in zip(modelist,shortmodelist):
393                explaination[shortmode] = "ISODISTORT full name "+str(mode)
394        #----------------------------------------------------------------------
395        # now read in the ISODISTORT occupancy modes
396        #----------------------------------------------------------------------
397        if blk.get('_iso_occupancymode_label'):
398            modelist = []
399            shortmodelist = []
400            for lbl in blk.get('_iso_occupancymode_label'):
401                modelist.append(lbl)
402                # assume lbl is of form SSSSS[x,y,z]AAAA(a,b,...)BBBBB
403                # where SSSSS is the parent spacegroup, [x,y,z] is a location
404                regexp = re.match(r'.*?\[.*?\](.*?)\(.*?\)(.*)',lbl)
405                # this extracts the AAAAA and BBBBB parts of the string
406                if regexp:
407                    lbl = regexp.expand(r'\1\2') # parse succeeded, make a short version
408                lbl = lbl.replace('order','o')
409                G2obj.MakeUniqueLabel(lbl,shortmodelist) # make unique and add to list
410            # read in the coordinate offset variables names and map them to G2 names/objects
411            occVarLbl = []
412            G2varLbl = []
413            G2varObj = []
414            error = False
415            for lbl in blk.get('_iso_deltaoccupancy_label'):
416                occVarLbl.append(lbl)
417                if '_' in lbl:
418                    albl = lbl[:lbl.rfind('_')]
419                    vlbl = lbl[lbl.rfind('_')+1:]
420                else:
421                    self.warnings += ' ERROR: _iso_deltaoccupancy_label not parsed: '+lbl
422                    error = True
423                    continue
424                if albl not in atomlbllist:
425                    self.warnings += ' ERROR: _iso_deltaoccupancy_label atom not found: '+lbl
426                    error = True
427                    continue
428                else:
429                    anum = atomlbllist.index(albl)
430                var = varLookup.get(vlbl)
431                if not var:
432                    self.warnings += ' ERROR: _iso_deltaoccupancy_label variable not found: '+lbl
433                    error = True
434                    continue
435                G2varLbl.append('::'+var+':'+str(anum)) # variable name, less phase ID
436                G2varObj.append(G2obj.G2VarObj(
437                    (self.Phase['ranId'],None,var,ranIdlookup[albl])
438                    ))
439            if error:
440                raise Exception,"Error decoding variable labels"
441
442            if len(G2varObj) != len(modelist):
443                print "non-square input"
444                raise Exception,"Rank of _iso_occupancymode != _iso_deltaoccupancy"
445
446            error = False
447            ParentCoordinates = {}
448            for lbl,exp in zip(
449                blk.get('_iso_occupancy_label'),
450                blk.get('_iso_occupancy_formula'),
451                ):
452                if '_' in lbl:
453                    albl = lbl[:lbl.rfind('_')]
454                    vlbl = lbl[lbl.rfind('_')+1:]
455                else:
456                    self.warnings += ' ERROR: _iso_occupancy_label not parsed: '+lbl
457                    error = True
458                    continue
459                if vlbl != 'occ':
460                    self.warnings += ' ERROR: _iso_occupancy_label coordinate not parsed: '+lbl
461                    error = True
462                    continue
463                if '+' in exp:
464                    val = exp.split('+')[0].strip()
465                    val = G2p3.FormulaEval(val)
466                    if val is None:
467                        self.warnings += ' ERROR: _iso_occupancy_formula coordinate not interpreted: '+lbl
468                        error = True
469                        continue
470                    ParentCoordinates[albl] = val
471            if error:
472                raise Exception,"Error decoding occupancy labels"
473            # get mapping of modes to atomic coordinate displacements
474            occupancymodematrix = np.zeros((len(G2varObj),len(G2varObj)))
475            for row,col,val in zip(
476                blk.get('_iso_occupancymodematrix_row'),
477                blk.get('_iso_occupancymodematrix_col'),
478                blk.get('_iso_occupancymodematrix_value'),):
479                occupancymodematrix[int(row)-1,int(col)-1] = float(val)
480            # Invert to get mapping of atom displacements to modes
481            occupancymodeInvmatrix = np.linalg.inv(occupancymodematrix)
482            # create the constraints
483            for i,row in enumerate(occupancymodeInvmatrix):
484                constraint = []
485                for j,(lbl,k) in enumerate(zip(occVarLbl,row)):
486                    if k == 0: continue
487                    constraint.append([k,G2varObj[j]])
488                constraint += [shortmodelist[i],False,'f']
489                self.Constraints.append(constraint)
490            #----------------------------------------------------------------------
491            # save the ISODISTORT info for "mode analysis"
492            if 'ISODISTORT' not in self.Phase: self.Phase['ISODISTORT'] = {}
493            self.Phase['ISODISTORT'].update({
494                'OccModeList' : modelist,
495                'G2OccModeList' : shortmodelist,
496                'OccVarList' : occVarLbl,
497                'G2OccVarList' : G2varObj,
498                'BaseOcc' : ParentCoordinates,
499                'Var2OccMatrix' : occupancymodeInvmatrix,
500                'Occ2VarMatrix' : occupancymodematrix,
501                })
502            # make explaination dictionary
503            for mode,shortmode in zip(modelist,shortmodelist):
504                explaination[shortmode] = "ISODISTORT full name "+str(mode)
505        #----------------------------------------------------------------------
506        # done with read
507        #----------------------------------------------------------------------
508        if explaination: self.Constraints.append(explaination)
509
510        # # debug: show the mode var to mode relations
511        # for i,row in enumerate(displacivemodeInvmatrix):
512        #     l = ''
513        #     for j,(lbl,k) in enumerate(zip(coordVarLbl,row)):
514        #         if k == 0: continue
515        #         if l: l += ' + '
516        #         #l += lbl+' * '+str(k)
517        #         l += G2varLbl[j]+' * '+str(k)
518        #     print str(i) + ': '+shortmodelist[i]+' = '+l
519        # print 70*'='
520
521        # # debug: Get the ISODISTORT offset values
522        # coordVarDelta = {}
523        # for lbl,val in zip(
524        #     blk.get('_iso_deltacoordinate_label'),
525        #     blk.get('_iso_deltacoordinate_value'),):
526        #     coordVarDelta[lbl] = float(val)
527        # modeVarDelta = {}
528        # for lbl,val in zip(
529        #     blk.get('_iso_displacivemode_label'),
530        #     blk.get('_iso_displacivemode_value'),):
531        #     modeVarDelta[lbl] = cif.get_number_with_esd(val)[0]
532
533        # print 70*'='
534        # # compute the mode values from the reported coordinate deltas
535        # for i,row in enumerate(displacivemodeInvmatrix):
536        #     l = ''
537        #     sl = ''
538        #     s = 0.
539        #     for lbl,k in zip(coordVarLbl,row):
540        #         if k == 0: continue
541        #         if l: l += ' + '
542        #         l += lbl+' * '+str(k)
543        #         if sl: sl += ' + '
544        #         sl += str(coordVarDelta[lbl])+' * '+str(k)
545        #         s += coordVarDelta[lbl] * k
546        #     print 'a'+str(i)+' = '+l
547        #     print '\t= '+sl
548        #     print  modelist[i],shortmodelist[i],modeVarDelta[modelist[i]],s
549        #     print
550
551        # print 70*'='
552        # # compute the coordinate displacements from the reported mode values
553        # for i,lbl,row in zip(range(len(coordVarLbl)),coordVarLbl,displacivemodematrix):
554        #     l = ''
555        #     sl = ''
556        #     s = 0.0
557        #     for j,k in enumerate(row):
558        #         if k == 0: continue
559        #         if l: l += ' + '
560        #         l += 'a'+str(j+1)+' * '+str(k)
561        #         if sl: sl += ' + '
562        #         sl += str(shortmodelist[j]) +' = '+ str(modeVarDelta[modelist[j]]) + ' * '+str(k)
563        #         s += modeVarDelta[modelist[j]] * k
564        #     print lbl+' = '+l
565        #     print '\t= '+sl
566        #     print lbl,G2varLbl[i],coordVarDelta[lbl],s
567        #     print
568
569        # determine the coordinate delta values from deviations from the parent structure
570        # for atmline in self.Phase['Atoms']:
571        #     lbl = atmline[0]
572        #     x,y,z = atmline[3:6]
573        #     if lbl not in ParentCoordinates:
574        #         print lbl,x,y,z
575        #         continue
576        #     px,py,pz = ParentCoordinates[lbl]
577        #     print lbl,x,y,z,x-px,y-py,z-pz
Note: See TracBrowser for help on using the repository browser.