source: trunk/imports/G2phase_CIF.py @ 1985

Last change on this file since 1985 was 1985, checked in by toby, 6 years ago

fix CIF import where ? is used for Uiso value and where iso/aniso type is inferred

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