def Exporter(self,event=None): '''Export as a XYZ file ''' # the export process starts here self.InitExport(event) # load all of the tree into a set of dicts self.loadTree() # create a dict with refined values and their uncertainties self.loadParmDict() if self.ExportSelect(): # set export parameters; ask for file name return filename = self.filename for phasenam in self.phasenam: phasedict = self.Phases[phasenam] # pointer to current phase info General = phasedict['General'] i = self.Phases[phasenam]['pId'] Atoms = phasedict['Atoms'] if not len(Atoms): print('**** ERROR - Phase '+str(phasenam)+' has no atoms! ****') continue if len(self.phasenam) > 1: # if more than one filename is included, add a phase # self.filename = os.path.splitext(filename)[1] + "_" + str(i) + self.extension fp = self.OpenFile() cx,ct,cs,cia = General['AtomPtrs'] Cell = General['Cell'][1:7] A,B = G2lat.cell2AB(Cell) fmt = '{:4s}'+3*'{:12.4f}' self.Write('{:6d}'.format(len(Atoms))) self.Write(' ') for atom in Atoms: xyz = np.inner(A,np.array(atom[cx:cx+3])) self.Write(fmt.format(atom[ct],*xyz)) self.CloseFile() print('Phase '+str(phasenam)+' written to XYZ file '+str(self.fullpath))
def DisAglTor(DATData): 'Needs a doc string' SGData = DATData['SGData'] Cell = DATData['Cell'] Amat, Bmat = G2lat.cell2AB(Cell[:6]) covData = {} pfx = '' if 'covData' in DATData: covData = DATData['covData'] pfx = str(DATData['pId']) + '::' Datoms = [] Oatoms = [] for i, atom in enumerate(DATData['Datoms']): symop = atom[-1].split('+') if len(symop) == 1: symop.append('0,0,0') symop[0] = int(symop[0]) symop[1] = eval(symop[1]) atom.append(symop) Datoms.append(atom) oatom = DATData['Oatoms'][i] names = ['', '', ''] if pfx: names = [ pfx + 'dAx:' + str(oatom[0]), pfx + 'dAy:' + str(oatom[0]), pfx + 'dAz:' + str(oatom[0]) ] oatom += [ names, ] Oatoms.append(oatom) atmSeq = [atom[1] + '(' + atom[-2] + ')' for atom in Datoms] if DATData['Natoms'] == 4: #torsion Tors, sig = G2mth.GetDATSig(Oatoms, Datoms, Amat, SGData, covData) print(' Torsion angle for %s atom sequence: %s = %s' % (DATData['Name'], str(atmSeq).replace( "'", "")[1:-1], G2mth.ValEsd(Tors, sig))) print(' NB: Atom sequence determined by selection order') return # done with torsion elif DATData['Natoms'] == 3: #angle Ang, sig = G2mth.GetDATSig(Oatoms, Datoms, Amat, SGData, covData) print(' Angle in %s for atom sequence: %s = %s' % (DATData['Name'], str(atmSeq).replace( "'", "")[1:-1], G2mth.ValEsd(Ang, sig))) print(' NB: Atom sequence determined by selection order') else: #2 atoms - distance Dist, sig = G2mth.GetDATSig(Oatoms, Datoms, Amat, SGData, covData) print(' Distance in %s for atom sequence: %s = %s' % (DATData['Name'], str(atmSeq).replace( "'", "")[1:-1], G2mth.ValEsd(Dist, sig)))
def DisAglTor(DATData): 'Needs a doc string' SGData = DATData['SGData'] Cell = DATData['Cell'] Amat,Bmat = G2lat.cell2AB(Cell[:6]) covData = {} pfx = '' if 'covData' in DATData: covData = DATData['covData'] covMatrix = covData['covMatrix'] varyList = covData['varyList'] pfx = str(DATData['pId'])+'::' Datoms = [] Oatoms = [] for i,atom in enumerate(DATData['Datoms']): symop = atom[-1].split('+') if len(symop) == 1: symop.append('0,0,0') symop[0] = int(symop[0]) symop[1] = eval(symop[1]) atom.append(symop) Datoms.append(atom) oatom = DATData['Oatoms'][i] names = ['','',''] if pfx: names = [pfx+'dAx:'+str(oatom[0]),pfx+'dAy:'+str(oatom[0]),pfx+'dAz:'+str(oatom[0])] oatom += [names,] Oatoms.append(oatom) atmSeq = [atom[1]+'('+atom[-2]+')' for atom in Datoms] if DATData['Natoms'] == 4: #torsion Tors,sig = G2mth.GetDATSig(Oatoms,Datoms,Amat,SGData,covData) print ' Torsion angle for '+DATData['Name']+' atom sequence: ',atmSeq,'=',G2mth.ValEsd(Tors,sig) print ' NB: Atom sequence determined by selection order' return # done with torsion elif DATData['Natoms'] == 3: #angle Ang,sig = G2mth.GetDATSig(Oatoms,Datoms,Amat,SGData,covData) print ' Angle in '+DATData['Name']+' for atom sequence: ',atmSeq,'=',G2mth.ValEsd(Ang,sig) print ' NB: Atom sequence determined by selection order' else: #2 atoms - distance Dist,sig = G2mth.GetDATSig(Oatoms,Datoms,Amat,SGData,covData) print ' Distance in '+DATData['Name']+' for atom sequence: ',atmSeq,'=',G2mth.ValEsd(Dist,sig)
def BestPlane(PlaneData): 'Needs a doc string' def ShowBanner(name): print(80 * '*') print(' Best plane result for phase ' + name) print(80 * '*', '\n') ShowBanner(PlaneData['Name']) Cell = PlaneData['Cell'] Amat, Bmat = G2lat.cell2AB(Cell[:6]) Atoms = PlaneData['Atoms'] sumXYZ = np.zeros(3) XYZ = [] Natoms = len(Atoms) for atom in Atoms: xyz = np.array(atom[3:6]) XYZ.append(xyz) sumXYZ += xyz sumXYZ /= Natoms XYZ = np.array(XYZ) - sumXYZ XYZ = np.inner(Amat, XYZ).T Zmat = np.zeros((3, 3)) for i, xyz in enumerate(XYZ): Zmat += np.outer(xyz.T, xyz) print(' Selected atoms centered at %10.5f %10.5f %10.5f' % (sumXYZ[0], sumXYZ[1], sumXYZ[2])) Evec, Emat = nl.eig(Zmat) Evec = np.sqrt(Evec) / (Natoms - 3) Order = np.argsort(Evec) XYZ = np.inner(XYZ, Emat.T).T XYZ = np.array([XYZ[Order[2]], XYZ[Order[1]], XYZ[Order[0]]]).T print(' Atoms in Cartesian best plane coordinates:') print(' Name X Y Z') for i, xyz in enumerate(XYZ): print(' %6s%10.3f%10.3f%10.3f' % (Atoms[i][1].ljust(6), xyz[0], xyz[1], xyz[2])) print('\n Best plane RMS X =%8.3f, Y =%8.3f, Z =%8.3f' % (Evec[Order[2]], Evec[Order[1]], Evec[Order[0]]))
def BestPlane(PlaneData): 'Needs a doc string' def ShowBanner(name): print 80*'*' print ' Best plane result for phase '+name print 80*'*','\n' ShowBanner(PlaneData['Name']) Cell = PlaneData['Cell'] Amat,Bmat = G2lat.cell2AB(Cell[:6]) Atoms = PlaneData['Atoms'] sumXYZ = np.zeros(3) XYZ = [] Natoms = len(Atoms) for atom in Atoms: xyz = np.array(atom[3:6]) XYZ.append(xyz) sumXYZ += xyz sumXYZ /= Natoms XYZ = np.array(XYZ)-sumXYZ XYZ = np.inner(Amat,XYZ).T Zmat = np.zeros((3,3)) for i,xyz in enumerate(XYZ): Zmat += np.outer(xyz.T,xyz) print ' Selected atoms centered at %10.5f %10.5f %10.5f'%(sumXYZ[0],sumXYZ[1],sumXYZ[2]) Evec,Emat = nl.eig(Zmat) Evec = np.sqrt(Evec)/(Natoms-3) Order = np.argsort(Evec) XYZ = np.inner(XYZ,Emat.T).T XYZ = np.array([XYZ[Order[2]],XYZ[Order[1]],XYZ[Order[0]]]).T print ' Atoms in Cartesian best plane coordinates:' print ' Name X Y Z' for i,xyz in enumerate(XYZ): print ' %6s%10.3f%10.3f%10.3f'%(Atoms[i][1].ljust(6),xyz[0],xyz[1],xyz[2]) print '\n Best plane RMS X =%8.3f, Y =%8.3f, Z =%8.3f'%(Evec[Order[2]],Evec[Order[1]],Evec[Order[0]])
def ReadPDBPhase(self, filename, parent=None): '''Read a phase from a PDB file. ''' EightPiSq = 8. * math.pi**2 self.errors = 'Error opening file' file = open(filename, 'Ur') Phase = {} Title = '' Compnd = '' Atoms = [] A = np.zeros(shape=(3, 3)) S = file.readline() line = 1 SGData = None cell = None while S: self.errors = 'Error reading at line ' + str(line) Atom = [] if 'TITLE' in S[:5]: Title = S[10:72].strip() elif 'COMPND ' in S[:10]: Compnd = S[10:72].strip() elif 'CRYST' in S[:5]: abc = S[7:34].split() angles = S[34:55].split() cell = [ float(abc[0]), float(abc[1]), float(abc[2]), float(angles[0]), float(angles[1]), float(angles[2]) ] Volume = G2lat.calc_V(G2lat.cell2A(cell)) AA, AB = G2lat.cell2AB(cell) SpGrp = S[55:65] E, SGData = G2spc.SpcGroup(SpGrp) # space group processing failed, try to look up name in table if E: SpGrpNorm = G2spc.StandardizeSpcName(SpGrp) if SpGrpNorm: E, SGData = G2spc.SpcGroup(SpGrpNorm) while E: print G2spc.SGErrors(E) dlg = wx.TextEntryDialog( parent, SpGrp[:-1] + ' is invalid \nN.B.: make sure spaces separate axial fields in symbol', 'ERROR in space group symbol', '', style=wx.OK) if dlg.ShowModal() == wx.ID_OK: SpGrp = dlg.GetValue() E, SGData = G2spc.SpcGroup(SpGrp) else: SGData = G2IO.SGData # P 1 self.warnings += '\nThe space group was not interpreted and has been set to "P 1".' self.warnings += "Change this in phase's General tab." dlg.Destroy() SGlines = G2spc.SGPrint(SGData) for l in SGlines: print l elif 'SCALE' in S[:5]: V = S[10:41].split() A[int(S[5]) - 1] = [float(V[0]), float(V[1]), float(V[2])] elif 'ATOM' in S[:4] or 'HETATM' in S[:6]: if not SGData: self.warnings += '\nThe space group was not read before atoms and has been set to "P 1". ' self.warnings += "Change this in phase's General tab." SGData = G2IO.SGData # P 1 XYZ = [float(S[31:39]), float(S[39:47]), float(S[47:55])] XYZ = np.inner(AB, XYZ) XYZ = np.where(abs(XYZ) < 0.00001, 0, XYZ) SytSym, Mult = G2spc.SytSym(XYZ, SGData) Uiso = float(S[61:67]) / EightPiSq Type = S[12:14].lower() if Type[0] in '123456789': Type = Type[1:] Atom = [ S[22:27].strip(), S[17:20].upper(), S[20:22], S[12:17].strip(), Type.strip().capitalize(), '', XYZ[0], XYZ[1], XYZ[2], float(S[55:61]), SytSym, Mult, 'I', Uiso, 0, 0, 0, 0, 0, 0 ] S = file.readline() line += 1 if 'ANISOU' in S[:6]: Uij = S[30:72].split() Uij = [ float(Uij[0]) / 10000., float(Uij[1]) / 10000., float(Uij[2]) / 10000., float(Uij[3]) / 10000., float(Uij[4]) / 10000., float(Uij[5]) / 10000. ] Atom = Atom[:14] + Uij Atom[12] = 'A' Atom.append(ran.randint(0, sys.maxint)) Atoms.append(Atom) S = file.readline() line += 1 file.close() self.errors = 'Error after read complete' if Title: PhaseName = Title elif Compnd: PhaseName = Compnd else: PhaseName = 'None' if not SGData: raise self.ImportException("No space group (CRYST entry) found") if not cell: raise self.ImportException("No cell (CRYST entry) found") Phase = G2IO.SetNewPhase(Name=PhaseName, SGData=SGData, cell=cell + [ Volume, ]) Phase['General']['Type'] = 'macromolecular' Phase['General']['AtomPtrs'] = [6, 4, 10, 12] Phase['Atoms'] = Atoms return Phase
def PrintDistAngle(DisAglCtls,DisAglData,out=sys.stdout): '''Print distances and angles :param dict DisAglCtls: contains distance/angle radii usually defined using :func:`GSASIIctrlGUI.DisAglDialog` :param dict DisAglData: contains phase data: Items 'OrigAtoms' and 'TargAtoms' contain the atoms to be used for distance/angle origins and atoms to be used as targets. Item 'SGData' has the space group information (see :ref:`Space Group object<SGData_table>`) :param file out: file object for output. Defaults to sys.stdout. ''' def MyPrint(s): out.write(s+'\n') # print(s,file=out) # use in Python 3 def ShowBanner(name): MyPrint(80*'*') MyPrint(' Interatomic Distances and Angles for phase '+name) MyPrint((80*'*')+'\n') ShowBanner(DisAglCtls['Name']) SGData = DisAglData['SGData'] SGtext,SGtable = G2spc.SGPrint(SGData) for line in SGtext: MyPrint(line) if len(SGtable) > 1: for i,item in enumerate(SGtable[::2]): if 2*i+1 == len(SGtable): line = ' %s'%(item.ljust(30)) else: line = ' %s %s'%(item.ljust(30),SGtable[2*i+1].ljust(30)) MyPrint(line) else: MyPrint(' ( 1) %s'%(SGtable[0])) #triclinic case Cell = DisAglData['Cell'] Amat,Bmat = G2lat.cell2AB(Cell[:6]) covData = {} if 'covData' in DisAglData: covData = DisAglData['covData'] pfx = str(DisAglData['pId'])+'::' A = G2lat.cell2A(Cell[:6]) cellSig = G2stIO.getCellEsd(pfx,SGData,A,covData) names = [' a = ',' b = ',' c = ',' alpha = ',' beta = ',' gamma = ',' Volume = '] valEsd = [G2mth.ValEsd(Cell[i],cellSig[i],True) for i in range(7)] line = '\n Unit cell:' for name,vals in zip(names,valEsd): line += name+vals MyPrint(line) else: MyPrint('\n Unit cell: a = '+('%.5f'%Cell[0])+' b = '+('%.5f'%Cell[1])+' c = '+('%.5f'%Cell[2])+ ' alpha = '+('%.3f'%Cell[3])+' beta = '+('%.3f'%Cell[4])+' gamma = '+ ('%.3f'%Cell[5])+' Volume = '+('%.3f'%Cell[6])) AtomLabels,DistArray,AngArray = RetDistAngle(DisAglCtls,DisAglData) origAtoms = DisAglData['OrigAtoms'] for Oatom in origAtoms: i = Oatom[0] Dist = DistArray[i] nDist = len(Dist) angles = np.zeros((nDist,nDist)) angsig = np.zeros((nDist,nDist)) for k,j,tup in AngArray[i]: angles[k][j],angsig[k][j] = angles[j][k],angsig[j][k] = tup line = '' for i,x in enumerate(Oatom[3:6]): line += ('%12.5f'%x).rstrip('0') MyPrint('\n Distances & angles for '+Oatom[1]+' at '+line.rstrip()) MyPrint(80*'*') line = '' for dist in Dist[:-1]: line += '%12s'%(AtomLabels[dist[0]].center(12)) MyPrint(' To cell +(sym. op.) dist. '+line.rstrip()) for i,dist in enumerate(Dist): line = '' for j,angle in enumerate(angles[i][0:i]): sig = angsig[i][j] if angle: if sig: line += '%12s'%(G2mth.ValEsd(angle,sig,True).center(12)) else: val = '%.3f'%(angle) line += '%12s'%(val.center(12)) else: line += 12*' ' if dist[4]: #sig exists! val = G2mth.ValEsd(dist[3],dist[4]) else: val = '%8.4f'%(dist[3]) tunit = '[%2d%2d%2d]'% dist[1] MyPrint((' %8s%10s+(%4d) %12s'%(AtomLabels[dist[0]].ljust(8),tunit.ljust(10),dist[2],val.center(12)))+line.rstrip())
def RetDistAngle(DisAglCtls,DisAglData): '''Compute and return distances and angles :param dict DisAglCtls: contains distance/angle radii usually defined using :func:`GSASIIctrlGUI.DisAglDialog` :param dict DisAglData: contains phase data: Items 'OrigAtoms' and 'TargAtoms' contain the atoms to be used for distance/angle origins and atoms to be used as targets. Item 'SGData' has the space group information (see :ref:`Space Group object<SGData_table>`) :returns: AtomLabels,DistArray,AngArray where: **AtomLabels** is a dict of atom labels, keys are the atom number **DistArray** is a dict keyed by the origin atom number where the value is a list of distance entries. The value for each distance is a list containing: 0) the target atom number (int); 1) the unit cell offsets added to x,y & z (tuple of int values) 2) the symmetry operator number (which may be modified to indicate centering and center of symmetry) 3) an interatomic distance in A (float) 4) an uncertainty on the distance in A or 0.0 (float) **AngArray** is a dict keyed by the origin (central) atom number where the value is a list of angle entries. The value for each angle entry consists of three values: 0) a distance item reference for one neighbor (int) 1) a distance item reference for a second neighbor (int) 2) a angle, uncertainty pair; the s.u. may be zero (tuple of two floats) The AngArray distance reference items refer directly to the index of the items in the DistArray item for the list of distances for the central atom. ''' import numpy.ma as ma SGData = DisAglData['SGData'] Cell = DisAglData['Cell'] Amat,Bmat = G2lat.cell2AB(Cell[:6]) covData = {} if 'covData' in DisAglData: covData = DisAglData['covData'] covMatrix = covData['covMatrix'] varyList = covData['varyList'] pfx = str(DisAglData['pId'])+'::' Factor = DisAglCtls['Factors'] Radii = dict(zip(DisAglCtls['AtomTypes'],zip(DisAglCtls['BondRadii'],DisAglCtls['AngleRadii']))) indices = (-2,-1,0,1,2) Units = np.array([[h,k,l] for h in indices for k in indices for l in indices]) origAtoms = DisAglData['OrigAtoms'] targAtoms = DisAglData['TargAtoms'] AtomLabels = {} for Oatom in origAtoms: AtomLabels[Oatom[0]] = Oatom[1] for Oatom in targAtoms: AtomLabels[Oatom[0]] = Oatom[1] DistArray = {} AngArray = {} for Oatom in origAtoms: DistArray[Oatom[0]] = [] AngArray[Oatom[0]] = [] OxyzNames = '' IndBlist = [] Dist = [] Vect = [] VectA = [] angles = [] for Tatom in targAtoms: Xvcov = [] TxyzNames = '' if 'covData' in DisAglData: OxyzNames = [pfx+'dAx:%d'%(Oatom[0]),pfx+'dAy:%d'%(Oatom[0]),pfx+'dAz:%d'%(Oatom[0])] TxyzNames = [pfx+'dAx:%d'%(Tatom[0]),pfx+'dAy:%d'%(Tatom[0]),pfx+'dAz:%d'%(Tatom[0])] Xvcov = G2mth.getVCov(OxyzNames+TxyzNames,varyList,covMatrix) result = G2spc.GenAtom(Tatom[3:6],SGData,False,Move=False) BsumR = (Radii[Oatom[2]][0]+Radii[Tatom[2]][0])*Factor[0] AsumR = (Radii[Oatom[2]][1]+Radii[Tatom[2]][1])*Factor[1] for [Txyz,Top,Tunit,Spn] in result: Dx = (Txyz-np.array(Oatom[3:6]))+Units dx = np.inner(Amat,Dx) dist = ma.masked_less(np.sqrt(np.sum(dx**2,axis=0)),0.5) IndB = ma.nonzero(ma.masked_greater(dist-BsumR,0.)) if np.any(IndB): for indb in IndB: for i in range(len(indb)): if str(dx.T[indb][i]) not in IndBlist: IndBlist.append(str(dx.T[indb][i])) unit = Units[indb][i] tunit = (unit[0]+Tunit[0],unit[1]+Tunit[1],unit[2]+Tunit[2]) pdpx = G2mth.getDistDerv(Oatom[3:6],Tatom[3:6],Amat,unit,Top,SGData) sig = 0.0 if len(Xvcov): sig = np.sqrt(np.inner(pdpx,np.inner(pdpx,Xvcov))) Dist.append([Oatom[0],Tatom[0],tunit,Top,ma.getdata(dist[indb])[i],sig]) if (Dist[-1][-2]-AsumR) <= 0.: Vect.append(dx.T[indb][i]/Dist[-1][-2]) VectA.append([OxyzNames,np.array(Oatom[3:6]),TxyzNames,np.array(Tatom[3:6]),unit,Top]) else: Vect.append([0.,0.,0.]) VectA.append([]) for D in Dist: DistArray[Oatom[0]].append(D[1:]) Vect = np.array(Vect) angles = np.zeros((len(Vect),len(Vect))) angsig = np.zeros((len(Vect),len(Vect))) for i,veca in enumerate(Vect): if np.any(veca): for j,vecb in enumerate(Vect): if np.any(vecb): angles[i][j],angsig[i][j] = G2mth.getAngSig(VectA[i],VectA[j],Amat,SGData,covData) if i <= j: continue AngArray[Oatom[0]].append((i,j, G2mth.getAngSig(VectA[i],VectA[j],Amat,SGData,covData))) return AtomLabels,DistArray,AngArray
def ReadEXPPhase(self, G2frame, filepointer): '''Read a phase from a GSAS .EXP file. ''' shModels = ['cylindrical', 'none', 'shear - 2/m', 'rolling - mmm'] textureData = { 'Order': 0, 'Model': 'cylindrical', 'Sample omega': [False, 0.0], 'Sample chi': [False, 0.0], 'Sample phi': [False, 0.0], 'SH Coeff': [False, {}], 'SHShow': False, 'PFhkl': [0, 0, 1], 'PFxyz': [0, 0, 1], 'PlotType': 'Pole figure' } shNcof = 0 S = 1 NPhas = [] Expr = [{}, {}, {}, {}, {}, {}, {}, {}, {}] # GSAS can have at most 9 phases for line, S in enumerate(filepointer): self.errors = 'Error reading at line ' + str(line + 1) if 'EXPR NPHAS' in S[:12]: NPhas = S[12:-1].split() if 'CRS' in S[:3]: N = int(S[3:4]) - 1 Expr[N][S[:12]] = S[12:-1] PNames = [] if not NPhas: raise self.ImportException("No EXPR NPHAS record found") self.errors = 'Error interpreting file' for n, N in enumerate(NPhas): if N != '0': result = n key = 'CRS' + str(n + 1) + ' PNAM' PNames.append(Expr[n][key]) if len(PNames) == 0: raise self.ImportException("No phases found") elif len(PNames) > 1: dlg = wx.SingleChoiceDialog(G2frame, 'Which phase to read?', 'Read phase data', PNames, wx.CHOICEDLG_STYLE) try: if dlg.ShowModal() == wx.ID_OK: result = dlg.GetSelection( ) # I think this breaks is there are skipped phases. Cant this happen? finally: dlg.Destroy() EXPphase = Expr[result] keyList = list(EXPphase.keys()) keyList.sort() SGData = {} MPtype = '' if NPhas[result] == '1': Ptype = 'nuclear' elif NPhas[result] == '2': Ptype = 'nuclear' MPtype = 'magnetic' MagDmin = 1.0 elif NPhas[result] == '3': Ptype = 'magnetic' MagDmin = 1.0 elif NPhas[result] == '4': Ptype = 'macromolecular' elif NPhas[result] == '10': Ptype = 'Pawley' else: raise self.ImportException("Phase type not recognized") for key in keyList: if 'PNAM' in key: PhaseName = EXPphase[key].strip() elif 'ABC ' in key: abc = [ float(EXPphase[key][:10]), float(EXPphase[key][10:20]), float(EXPphase[key][20:30]) ] elif 'ANGLES' in key: angles = [ float(EXPphase[key][:10]), float(EXPphase[key][10:20]), float(EXPphase[key][20:30]) ] elif 'SG SYM' in key: SpGrp = EXPphase[key][:15].strip() E, SGData = G2spc.SpcGroup(SpGrp) if E: SGData = G2obj.P1SGData # P 1 -- unlikely to need this! self.warnings += '\nThe GSAS space group was not interpreted(!) and has been set to "P 1".' self.warnings += "Change this in phase's General tab." elif 'SPNFLP' in key: SpnFlp = np.array( [int(float(s)) for s in EXPphase[key].split()]) SpnFlp = np.where(SpnFlp == 0, 1, SpnFlp) SpnFlp = [ 1, ] + list(SpnFlp) if SGData['SpGrp'][0] in ['A', 'B', 'C', 'I', 'R', 'F']: SpnFlp = list(SpnFlp) + [1, 1, 1, 1] elif 'MXDSTR' in key: MagDmin = float(EXPphase[key][:10]) elif 'OD ' in key: SHdata = EXPphase[key].split() # may not have all 9 values SHvals = 9 * [0] for i in range(9): try: float(SHdata[i]) SHvals[i] = SHdata[i] except: pass textureData['Order'] = int(SHvals[0]) textureData['Model'] = shModels[int(SHvals[2])] textureData['Sample omega'] = [False, float(SHvals[6])] textureData['Sample chi'] = [False, float(SHvals[7])] textureData['Sample phi'] = [False, float(SHvals[8])] shNcof = int(SHvals[1]) Volume = G2lat.calc_V(G2lat.cell2A(abc + angles)) Atoms = [] MAtoms = [] Bmat = G2lat.cell2AB(abc + angles)[1] if Ptype == 'macromolecular': for key in keyList: if 'AT' in key[6:8]: S = EXPphase[key] Atom = [ S[56:60].strip(), S[50:54].strip().upper(), S[54:56], S[46:51].strip(), S[:8].strip().capitalize(), '', float(S[16:24]), float(S[24:32]), float(S[32:40]), float(S[8:16]), '1', 1, 'I', float(S[40:46]), 0, 0, 0, 0, 0, 0 ] XYZ = Atom[6:9] Atom[10], Atom[11] = G2spc.SytSym(XYZ, SGData)[:2] Atom.append(ran.randint(0, sys.maxsize)) Atoms.append(Atom) else: for key in keyList: if 'AT' in key: if key[11:] == 'A': S = EXPphase[key] elif key[11:] == 'B': S1 = EXPphase[key] Atom = [ S[50:58].strip(), S[:10].strip().capitalize(), '', float(S[10:20]), float(S[20:30]), float(S[30:40]), float(S[40:50]), '', int(S[60:62]), S1[62:63] ] #float(S[40:50]),'',int(S[60:62]),S1[130:131]] if Atom[9] == 'I': Atom += [float(S1[0:10]), 0., 0., 0., 0., 0., 0.] elif Atom[9] == 'A': Atom += [ 0.0, float(S1[0:10]), float(S1[10:20]), float(S1[20:30]), float(S1[30:40]), float(S1[40:50]), float(S1[50:60]) ] else: print('Error in line with key: ' + key) Atom += [0., 0., 0., 0., 0., 0., 0.] XYZ = Atom[3:6] Atom[7], Atom[8] = G2spc.SytSym(XYZ, SGData)[:2] Atom.append(ran.randint(0, sys.maxsize)) Atoms.append(Atom) elif key[11:] == 'M' and key[6:8] == 'AT': S = EXPphase[key] mom = np.array( [float(S[:10]), float(S[10:20]), float(S[20:30])]) mag = np.sqrt(np.sum(mom**2)) mom = np.inner(Bmat, mom) * mag MAtoms.append(Atom) MAtoms[-1] = Atom[:7] + list(mom) + Atom[7:] if shNcof: shCoef = {} nRec = [i + 1 for i in range((shNcof - 1) // 6 + 1)] for irec in nRec: ODkey = keyList[0][:6] + 'OD' + '%3dA' % (irec) indx = EXPphase[ODkey].split() ODkey = ODkey[:-1] + 'B' vals = EXPphase[ODkey].split() for i, val in enumerate(vals): key = 'C(%s,%s,%s)' % (indx[3 * i], indx[3 * i + 1], indx[3 * i + 2]) shCoef[key] = float(val) textureData['SH Coeff'] = [False, shCoef] if not SGData: raise self.ImportException("No space group found in phase") if not abc: raise self.ImportException("No cell lengths found in phase") if not angles: raise self.ImportException("No cell angles found in phase") if not Atoms: raise self.ImportException("No atoms found in phase") self.Phase['General'].update({ 'Type': Ptype, 'Name': PhaseName, 'Cell': [ False, ] + abc + angles + [ Volume, ], 'SGData': SGData }) if MPtype == 'magnetic': self.MPhase['General'].update({ 'Type': 'magnetic', 'Name': PhaseName + ' mag', 'Cell': [ False, ] + abc + angles + [ Volume, ], 'SGData': SGData }) else: self.MPhase = None if Ptype == 'macromolecular': self.Phase['General']['AtomPtrs'] = [6, 4, 10, 12] self.Phase['Atoms'] = Atoms elif Ptype == 'magnetic': self.Phase['General']['AtomPtrs'] = [3, 1, 10, 12] self.Phase['General']['SGData']['SGSpin'] = SpnFlp self.Phase['General']['MagDmin'] = MagDmin self.Phase['Atoms'] = MAtoms else: #nuclear self.Phase['General']['AtomPtrs'] = [3, 1, 7, 9] self.Phase['General']['SH Texture'] = textureData self.Phase['Atoms'] = Atoms if MPtype == 'magnetic': self.MPhase['General']['AtomPtrs'] = [3, 1, 10, 12] self.MPhase['General']['SGData']['SGSpin'] = SpnFlp self.MPhase['General']['MagDmin'] = MagDmin self.MPhase['Atoms'] = MAtoms
def ReadPDBPhase(self,filename,parent=None): '''Read a phase from a PDB file. ''' EightPiSq = 8.*math.pi**2 self.errors = 'Error opening file' file = open(filename, 'Ur') Phase = {} Title = '' Compnd = '' Atoms = [] A = np.zeros(shape=(3,3)) S = file.readline() line = 1 SGData = None cell = None while S: self.errors = 'Error reading at line '+str(line) Atom = [] if 'TITLE' in S[:5]: Title = S[10:72].strip() elif 'COMPND ' in S[:10]: Compnd = S[10:72].strip() elif 'CRYST' in S[:5]: abc = S[7:34].split() angles = S[34:55].split() cell=[float(abc[0]),float(abc[1]),float(abc[2]), float(angles[0]),float(angles[1]),float(angles[2])] Volume = G2lat.calc_V(G2lat.cell2A(cell)) AA,AB = G2lat.cell2AB(cell) SpGrp = S[55:65] E,SGData = G2spc.SpcGroup(SpGrp) # space group processing failed, try to look up name in table if E: SpGrpNorm = G2spc.StandardizeSpcName(SpGrp) if SpGrpNorm: E,SGData = G2spc.SpcGroup(SpGrpNorm) while E: print G2spc.SGErrors(E) dlg = wx.TextEntryDialog(parent, SpGrp[:-1]+' is invalid \nN.B.: make sure spaces separate axial fields in symbol', 'ERROR in space group symbol','',style=wx.OK) if dlg.ShowModal() == wx.ID_OK: SpGrp = dlg.GetValue() E,SGData = G2spc.SpcGroup(SpGrp) else: SGData = G2IO.SGData # P 1 self.warnings += '\nThe space group was not interpreted and has been set to "P 1".' self.warnings += "Change this in phase's General tab." dlg.Destroy() SGlines = G2spc.SGPrint(SGData) for l in SGlines: print l elif 'SCALE' in S[:5]: V = S[10:41].split() A[int(S[5])-1] = [float(V[0]),float(V[1]),float(V[2])] elif 'ATOM' in S[:4] or 'HETATM' in S[:6]: if not SGData: self.warnings += '\nThe space group was not read before atoms and has been set to "P 1". ' self.warnings += "Change this in phase's General tab." SGData = G2IO.SGData # P 1 XYZ = [float(S[31:39]),float(S[39:47]),float(S[47:55])] XYZ = np.inner(AB,XYZ) XYZ = np.where(abs(XYZ)<0.00001,0,XYZ) SytSym,Mult = G2spc.SytSym(XYZ,SGData) Uiso = float(S[61:67])/EightPiSq Type = S[12:14].lower() if Type[0] in '123456789': Type = Type[1:] Atom = [S[22:27].strip(),S[17:20].upper(),S[20:22], S[12:17].strip(),Type.strip().capitalize(),'',XYZ[0],XYZ[1],XYZ[2], float(S[55:61]),SytSym,Mult,'I',Uiso,0,0,0,0,0,0] S = file.readline() line += 1 if 'ANISOU' in S[:6]: Uij = S[30:72].split() Uij = [float(Uij[0])/10000.,float(Uij[1])/10000.,float(Uij[2])/10000., float(Uij[3])/10000.,float(Uij[4])/10000.,float(Uij[5])/10000.] Atom = Atom[:14]+Uij Atom[12] = 'A' Atom.append(ran.randint(0,sys.maxint)) Atoms.append(Atom) S = file.readline() line += 1 file.close() self.errors = 'Error after read complete' if Title: PhaseName = Title elif Compnd: PhaseName = Compnd else: PhaseName = 'None' if not SGData: raise self.ImportException("No space group (CRYST entry) found") if not cell: raise self.ImportException("No cell (CRYST entry) found") Phase = G2IO.SetNewPhase(Name=PhaseName,SGData=SGData,cell=cell+[Volume,]) Phase['General']['Type'] = 'macromolecular' Phase['General']['AtomPtrs'] = [6,4,10,12] Phase['Atoms'] = Atoms return Phase
def PrintDistAngle(DisAglCtls,DisAglData,out=sys.stdout): '''Print distances and angles :param dict DisAglCtls: contains distance/angle radii usually defined using :func:`GSASIIgrid.DisAglDialog` :param dict DisAglData: contains phase data: Items 'OrigAtoms' and 'TargAtoms' contain the atoms to be used for distance/angle origins and atoms to be used as targets. Item 'SGData' has the space group information (see :ref:`Space Group object<SGData_table>`) :param file out: file object for output. Defaults to sys.stdout. ''' import numpy.ma as ma def MyPrint(s): out.write(s+'\n') # print(s,file=out) # use in Python 3 def ShowBanner(name): MyPrint(80*'*') MyPrint(' Interatomic Distances and Angles for phase '+name) MyPrint((80*'*')+'\n') ShowBanner(DisAglCtls['Name']) SGData = DisAglData['SGData'] SGtext,SGtable = G2spc.SGPrint(SGData) for line in SGtext: MyPrint(line) if len(SGtable): for i,item in enumerate(SGtable[::2]): line = ' %s %s'%(item.ljust(30),SGtable[2*i+1].ljust(30)) MyPrint(line) else: MyPrint(' ( 1) %s'%(SGtable[0])) Cell = DisAglData['Cell'] Amat,Bmat = G2lat.cell2AB(Cell[:6]) covData = {} if 'covData' in DisAglData: covData = DisAglData['covData'] covMatrix = covData['covMatrix'] varyList = covData['varyList'] pfx = str(DisAglData['pId'])+'::' A = G2lat.cell2A(Cell[:6]) cellSig = G2stIO.getCellEsd(pfx,SGData,A,covData) names = [' a = ',' b = ',' c = ',' alpha = ',' beta = ',' gamma = ',' Volume = '] valEsd = [G2mth.ValEsd(Cell[i],cellSig[i],True) for i in range(7)] line = '\n Unit cell:' for name,vals in zip(names,valEsd): line += name+vals MyPrint(line) else: MyPrint('\n Unit cell: a = '+('%.5f'%Cell[0])+' b = '+('%.5f'%Cell[1])+' c = '+('%.5f'%Cell[2])+ ' alpha = '+('%.3f'%Cell[3])+' beta = '+('%.3f'%Cell[4])+' gamma = '+ ('%.3f'%Cell[5])+' volume = '+('%.3f'%Cell[6])) AtomLabels,DistArray,AngArray = RetDistAngle(DisAglCtls,DisAglData) origAtoms = DisAglData['OrigAtoms'] targAtoms = DisAglData['TargAtoms'] for Oatom in origAtoms: i = Oatom[0] Dist = DistArray[i] nDist = len(Dist) angles = np.zeros((nDist,nDist)) angsig = np.zeros((nDist,nDist)) for k,j,tup in AngArray[i]: angles[k][j],angsig[k][j] = angles[j][k],angsig[j][k] = tup line = '' for i,x in enumerate(Oatom[3:6]): line += ('%12.5f'%x).rstrip('0') MyPrint('\n Distances & angles for '+Oatom[1]+' at '+line.rstrip()) MyPrint(80*'*') line = '' for dist in Dist[:-1]: line += '%12s'%(AtomLabels[dist[0]].center(12)) MyPrint(' To cell +(sym. op.) dist. '+line.rstrip()) for i,dist in enumerate(Dist): line = '' for j,angle in enumerate(angles[i][0:i]): sig = angsig[i][j] if angle: if sig: line += '%12s'%(G2mth.ValEsd(angle,sig,True).center(12)) else: val = '%.3f'%(angle) line += '%12s'%(val.center(12)) else: line += 12*' ' if dist[4]: #sig exists! val = G2mth.ValEsd(dist[3],dist[4]) else: val = '%8.4f'%(dist[3]) tunit = '[%2d%2d%2d]'% dist[1] MyPrint((' %8s%10s+(%4d) %12s'%(AtomLabels[dist[0]].ljust(8),tunit.ljust(10),dist[2],val.center(12)))+line.rstrip())
def RetDistAngle(DisAglCtls,DisAglData): '''Compute and return distances and angles :param dict DisAglCtls: contains distance/angle radii usually defined using :func:`GSASIIgrid.DisAglDialog` :param dict DisAglData: contains phase data: Items 'OrigAtoms' and 'TargAtoms' contain the atoms to be used for distance/angle origins and atoms to be used as targets. Item 'SGData' has the space group information (see :ref:`Space Group object<SGData_table>`) :returns: AtomLabels,DistArray,AngArray where: **AtomLabels** is a dict of atom labels, keys are the atom number **DistArray** is a dict keyed by the origin atom number where the value is a list of distance entries. The value for each distance is a list containing: 0) the target atom number (int); 1) the unit cell offsets added to x,y & z (tuple of int values) 2) the symmetry operator number (which may be modified to indicate centering and center of symmetry) 3) an interatomic distance in A (float) 4) an uncertainty on the distance in A or 0.0 (float) **AngArray** is a dict keyed by the origin (central) atom number where the value is a list of angle entries. The value for each angle entry consists of three values: 0) a distance item reference for one neighbor (int) 1) a distance item reference for a second neighbor (int) 2) a angle, uncertainty pair; the s.u. may be zero (tuple of two floats) The AngArray distance reference items refer directly to the index of the items in the DistArray item for the list of distances for the central atom. ''' import numpy.ma as ma SGData = DisAglData['SGData'] Cell = DisAglData['Cell'] Amat,Bmat = G2lat.cell2AB(Cell[:6]) covData = {} if 'covData' in DisAglData: covData = DisAglData['covData'] covMatrix = covData['covMatrix'] varyList = covData['varyList'] pfx = str(DisAglData['pId'])+'::' A = G2lat.cell2A(Cell[:6]) cellSig = G2stIO.getCellEsd(pfx,SGData,A,covData) names = [' a = ',' b = ',' c = ',' alpha = ',' beta = ',' gamma = ',' Volume = '] valEsd = [G2mth.ValEsd(Cell[i],cellSig[i],True) for i in range(7)] Factor = DisAglCtls['Factors'] Radii = dict(zip(DisAglCtls['AtomTypes'],zip(DisAglCtls['BondRadii'],DisAglCtls['AngleRadii']))) indices = (-1,0,1) Units = np.array([[h,k,l] for h in indices for k in indices for l in indices]) origAtoms = DisAglData['OrigAtoms'] targAtoms = DisAglData['TargAtoms'] AtomLabels = {} for Oatom in origAtoms: AtomLabels[Oatom[0]] = Oatom[1] for Oatom in targAtoms: AtomLabels[Oatom[0]] = Oatom[1] DistArray = {} AngArray = {} for Oatom in origAtoms: DistArray[Oatom[0]] = [] AngArray[Oatom[0]] = [] OxyzNames = '' IndBlist = [] Dist = [] Vect = [] VectA = [] angles = [] for Tatom in targAtoms: Xvcov = [] TxyzNames = '' if 'covData' in DisAglData: OxyzNames = [pfx+'dAx:%d'%(Oatom[0]),pfx+'dAy:%d'%(Oatom[0]),pfx+'dAz:%d'%(Oatom[0])] TxyzNames = [pfx+'dAx:%d'%(Tatom[0]),pfx+'dAy:%d'%(Tatom[0]),pfx+'dAz:%d'%(Tatom[0])] Xvcov = G2mth.getVCov(OxyzNames+TxyzNames,varyList,covMatrix) result = G2spc.GenAtom(Tatom[3:6],SGData,False,Move=False) BsumR = (Radii[Oatom[2]][0]+Radii[Tatom[2]][0])*Factor[0] AsumR = (Radii[Oatom[2]][1]+Radii[Tatom[2]][1])*Factor[1] for Txyz,Top,Tunit in result: Dx = (Txyz-np.array(Oatom[3:6]))+Units dx = np.inner(Amat,Dx) dist = ma.masked_less(np.sqrt(np.sum(dx**2,axis=0)),0.5) IndB = ma.nonzero(ma.masked_greater(dist-BsumR,0.)) if np.any(IndB): for indb in IndB: for i in range(len(indb)): if str(dx.T[indb][i]) not in IndBlist: IndBlist.append(str(dx.T[indb][i])) unit = Units[indb][i] tunit = (unit[0]+Tunit[0],unit[1]+Tunit[1],unit[2]+Tunit[2]) pdpx = G2mth.getDistDerv(Oatom[3:6],Tatom[3:6],Amat,unit,Top,SGData) sig = 0.0 if len(Xvcov): sig = np.sqrt(np.inner(pdpx,np.inner(Xvcov,pdpx))) Dist.append([Oatom[0],Tatom[0],tunit,Top,ma.getdata(dist[indb])[i],sig]) if (Dist[-1][-2]-AsumR) <= 0.: Vect.append(dx.T[indb][i]/Dist[-1][-2]) VectA.append([OxyzNames,np.array(Oatom[3:6]),TxyzNames,np.array(Tatom[3:6]),unit,Top]) else: Vect.append([0.,0.,0.]) VectA.append([]) for D in Dist: DistArray[Oatom[0]].append(D[1:]) Vect = np.array(Vect) angles = np.zeros((len(Vect),len(Vect))) angsig = np.zeros((len(Vect),len(Vect))) for i,veca in enumerate(Vect): if np.any(veca): for j,vecb in enumerate(Vect): if np.any(vecb): angles[i][j],angsig[i][j] = G2mth.getAngSig(VectA[i],VectA[j],Amat,SGData,covData) if i <= j: continue AngArray[Oatom[0]].append((i,j, G2mth.getAngSig(VectA[i],VectA[j],Amat,SGData,covData))) return AtomLabels,DistArray,AngArray
def ReadINSPhase(self, filename, parent=None): '''Read a phase from a INS file. ''' Shelx = [ 'TITL', 'CELL', 'ZERR', 'LATT', 'SYMM', 'SFAC', 'DISP', 'UNIT', 'LAUE', 'EADP', 'MORE', 'TIME', 'HKLF', 'OMIT', 'SHEL', 'BASF', 'TWIN', 'EXTI', 'SWAT', 'HOPE', 'MERG', 'SPEC', 'RESI', 'RTAB', 'MPLA', 'HFIX', 'MOVE', 'ANIS', 'AFIX', 'FRAG', 'FEND', 'EXYZ', 'EDAP', 'EQIV', 'CONN', 'PART', 'BIND', 'FREE', 'DFIX', 'DANG', 'BUMP', 'SAME', 'SADI', 'CHIV', 'FLAT', 'DELU', 'SIMU', 'DEFS', 'ISOR', 'NCSY', 'SUMP', 'L.S.', 'CGLS', 'BLOC', 'DAMP', 'STIR', 'WGHT', 'FVAR', 'BOND', 'CONF', 'MPLA', 'HTAB', 'LIST', 'ACTA', 'SIZE', 'TEMP', 'WPDB', 'FMAP', 'GRID', 'PLAN', 'MOLE' ] self.errors = 'Error opening file' fp = open(filename, 'Ur') Phase = {} Title = '' Atoms = [] aTypes = [] S = fp.readline() line = 1 SGData = None cell = None while S: if '!' in S: S = S.split('!')[0] self.errors = 'Error reading at line ' + str(line) Atom = [] if 'TITL' in S[:4].upper(): Title = S[4:72].strip() elif not S.strip(): pass elif 'CELL' in S[:4].upper(): cellRec = S.split() abc = cellRec[2:5] angles = cellRec[5:8] cell = [ float(abc[0]), float(abc[1]), float(abc[2]), float(angles[0]), float(angles[1]), float(angles[2]) ] Volume = G2lat.calc_V(G2lat.cell2A(cell)) AA, AB = G2lat.cell2AB(cell) SGData = G2obj.P1SGData # P 1 self.warnings += '\nThe space group is not given in an ins file and has been set to "P 1".' self.warnings += "\nChange this in phase's General tab; NB: it might be in the Phase name." elif S[:4].upper() in 'SFAC': aTypes = S[4:].split() if 'H' in aTypes: self.warnings += '\n\nHydrogen atoms found; consider replacing them with stereochemically tied ones' self.warnings += '\nas Shelx constraints & HFIX commands are ignored.' self.warnings += "\nDo 'Edit/Insert H atoms' in this phase's Atoms tab after deleting the old ones." elif S[0] == 'Q': pass elif '\x1a' in S[:4]: pass elif S[:3].upper() == 'REM': pass elif S[:3].upper() == 'END': pass elif S[:4].strip().upper( ) not in Shelx: #this will find an atom record! AtRec = S.split() Atype = aTypes[int(AtRec[1]) - 1] Aname = AtRec[0] Afrac = abs(float(AtRec[5])) % 10. x, y, z = AtRec[2:5] XYZ = np.array([float(x), float(y), float(z)]) XYZ = np.where(np.abs(XYZ) < 0.00001, 0, XYZ) SytSym, Mult = G2spc.SytSym(XYZ, SGData)[:2] if '=' not in S: IA = 'I' Uiso = float(AtRec[6]) if Uiso < 0. or Uiso > 1.0: Uiso = 0.025 Uij = [0. for i in range(6)] else: IA = 'A' Uiso = 0. Ustr = AtRec[6:8] S = fp.readline() if '!' in S: S = S.split('!')[0] AtRec = S.split() line += 1 Ustr += AtRec Uij = [float(Ustr[i]) for i in range(6)] Uij = Uij[0:3] + [Uij[5], Uij[4], Uij[3]] Atom = [ Aname, Atype, '', XYZ[0], XYZ[1], XYZ[2], Afrac, SytSym, Mult, IA, Uiso ] Atom += Uij Atom.append(ran.randint(0, sys.maxsize)) Atoms.append(Atom) S = fp.readline() line += 1 fp.close() self.errors = 'Error after read complete' Phase = G2obj.SetNewPhase(Name='ShelX phase', SGData=SGData, cell=cell + [ Volume, ]) Phase['General']['Name'] = Title Phase['General']['Type'] = 'nuclear' Phase['General']['AtomPtrs'] = [3, 1, 7, 9] Phase['Atoms'] = Atoms return Phase
def Exporter(self,event=None): '''Export as a PDB file ''' def PDBheader(): self.Write("HEADER phase "+str(phasenam)+" from "+str(self.G2frame.GSASprojectfile)) self.Write("TITLE") self.Write("COMPND") self.Write("SOURCE") self.Write("KEYWDS") self.Write("EXPDTA X-RAY POWDER DIFFRACTION") self.Write("REVDAT") self.Write("JRNL") self.Write("REMARK 1") self.Write("REMARK 2") self.Write("REMARK 2 RESOLUTION. 2.66 ANGSTROMS.") self.Write("REMARK 2 POWDER DIFFRACTION MINIMUM D-SPACING.") def PDBremark250(): self.Write('REMARK 250') self.Write('REMARK 250 REFINEMENT.') self.Write('REMARK 250 PROGRAM : GSAS-II') self.Write('REMARK 250 AUTHORS : TOBY & VON DREELE') self.Write('REMARK 250 REFRENCE : J. APPL. CRYST. 46, 544-549(2013)') self.Write('REMARK 250') self.Write('REMARK 250 DATA USED IN REFINEMENT') self.Write('REMARK 250 RESOLUTION RANGE HIGH (ANGSTROMS) : x.xx') self.Write('REMARK 250 RESOLUTION RANGE LOW (ANGSTROMS) : xx.xx') self.Write('REMARK 250 POWDER DIFFRACTION DATA.') self.Write('REMARK 250') self.Write('REMARK 250 FIT TO DATA USED IN REFINEMENT') self.Write('REMARK 250 NUMBER OF POWDER PATTERNS : x') self.Write('REMARK 250 PROFILE R VALUES (%) : x.xx') self.Write('REMARK 250 WEIGHTED PROFILE R VALUES (%) : x.xx') self.Write('REMARK 250 F**2 R VALUES (%) : xx.xx') self.Write('REMARK 250 NUMBERS OF POWDER PATTERN POINTS : xxxx') self.Write('REMARK 250 NUMBERS OF REFLECTIONS : xxxx') self.Write('REMARK 250 TOTAL NUMBER OF POWDER POINTS : xxxx') self.Write('REMARK 250') self.Write('REMARK 250 NUMBER OF NON-HYDROGEN ATOMS USED IN REFINEMENT.') self.Write('REMARK 250 PROTEIN ATOMS : xxxx') self.Write('REMARK 250 NUCLEIC ACID ATOMS : xxxx') self.Write('REMARK 250 HETEROGEN ATOMS : xxxx') self.Write('REMARK 250 SOLVENT ATOMS : xxxx') self.Write('REMARK 250') self.Write('REMARK 250 MODEL REFINEMENT.') self.Write('REMARK 250 NUMBER OF LEAST-SQUARES PARAMETERS : xxxx') self.Write('REMARK 250 NUMBER OF RESTRAINTS : xxxx') self.Write('REMARK 250') self.Write('REMARK 250 RMS DEVIATIONS FROM RESTRAINT TARGET VALUES. NUMBER.') self.Write('REMARK 250 BOND ANGLES (DEG) : x.xx xxx') # self.Write('REMARK 250 ANTI-BUMPING DISTANCE RESTRAINTS (A) :x.xxx xxx') # self.Write('REMARK 250 HYDROGEN BOND DISTANCE RESTRAINTS (A) :x.xxx xxx') self.Write('REMARK 250 INTERATOMIC DISTANCES (A) :x.xxx xxx') self.Write('REMARK 250 DISTANCES FROM RESTRAINT PLANES (A) :x.xxx xxx') self.Write('REMARK 250 TORSION PSEUDOPOTENTIAL RESTRAINTS (E) : x.xx xxx') self.Write('REMARK 250 TORSION ANGLE RESTRAINTS (E) : x.xx xxx') self.Write('REMARK 250') self.Write('REMARK 200') self.Write('DBREF') def PDBseqres(seqList): chains = seqList.keys() chains.sort() nSeq = 0 for chain in chains: nres = len(seqList[chain]) nrec = (nres-1)/13+1 iB = 0 for irec in range(nrec): iF = min(iB+13,nres) text = 'SEQRES {:3d}{:2s}{:5d} '+(iF-iB)*'{:4s}' self.Write(text.format(irec+1,chain,nres,*seqList[chain][iB:iF])) nSeq += 1 iB += 13 return nSeq # the export process starts here self.InitExport(event) # load all of the tree into a set of dicts self.loadTree() # create a dict with refined values and their uncertainties self.loadParmDict() if self.ExportSelect(): # set export parameters; ask for file name return filename = self.filename for phasenam in self.phasenam: phasedict = self.Phases[phasenam] # pointer to current phase info General = phasedict['General'] if General['Type'] != 'macromolecular': print 'phase '+str(phasenam)+' not macromolecular, skipping' continue i = self.Phases[phasenam]['pId'] if len(self.phasenam) > 1: # if more than one filename is included, add a phase # self.filename = os.path.splitext(filename)[1] + "_" + str(i) + self.extension fp = self.OpenFile() Atoms = phasedict['Atoms'] cx,ct,cs,cia = General['AtomPtrs'] seqList = {} AA3letter = ['ALA','ARG','ASN','ASP','CYS','GLN','GLU','GLY','HIS','ILE', 'LEU','LYS','MET','PHE','PRO','SER','THR','TRP','TYR','VAL','MSE'] seq = 0 for atom in Atoms: if atom[ct-3] in AA3letter and int(atom[ct-4]) != seq: if atom[ct-2] not in seqList: seqList[atom[ct-2]] = [] seqList[atom[ct-2]].append(atom[ct-3]) seq = int(atom[ct-4]) PDBheader() PDBremark250() nSeq = PDBseqres(seqList) # get cell parameters Cell = General['Cell'][1:7] line = "CRYST1 {:8.3f} {:8.3f} {:8.3f} {:6.2f} {:6.2f} {:6.2f} ".format(*Cell) line += General['SGData']['SpGrp'].ljust(13) line += '%2d'%(len(General['SGData']['SGOps'])*len(General['SGData']['SGCen'])) self.Write(line) self.Write('ORIGX1 1.000000 0.000000 0.000000 0.00000') self.Write('ORIGX2 0.000000 1.000000 0.000000 0.00000') self.Write('ORIGX3 0.000000 0.000000 1.000000 0.00000') A,B = G2lat.cell2AB(Cell) self.Write('SCALE1 {:9.6f} {:9.6f} {:9.6f} 0.00000'.format(*B[0])) self.Write('SCALE2 {:9.6f} {:9.6f} {:9.6f} 0.00000'.format(*B[1])) self.Write('SCALE3 {:9.6f} {:9.6f} {:9.6f} 0.00000'.format(*B[2])) iatom = 1 nHet = 0 nTer = 0 fmt = '{:6s}{:5d} {:4s}{:3s} {:1s}{:4s} '+3*'{:8.3f}'+2*'{:6.2f}'+'{:s}' for atom in Atoms: if atom[cia] == 'I': #need to deal with aniso thermals for proteins = "ANISOU" records Biso = atom[cia+1]*8.*np.pi**2 xyz = np.inner(A,np.array(atom[cx:cx+3])) if atom[ct-3] in AA3letter: self.Write(fmt.format('ATOM ',iatom,atom[ct-1],atom[ct-3].strip(), \ atom[ct-2].strip(),atom[ct-4].rjust(4),xyz[0],xyz[1],xyz[2],atom[cx+3], \ Biso,atom[ct].rjust(12))) if atom[ct-1] == 'OXT': iatom += 1 self.Write('{:6s}{:5d} {:4s}{:3s}'.format('TER ',iatom,atom[ct-1],atom[ct-3].strip())) nTer += 1 else: nHet += 1 self.Write(fmt.format('HETATM',iatom,atom[ct-1],atom[ct-3].strip(), \ atom[ct-2].strip(),atom[ct-4].rjust(4),xyz[0],xyz[1],xyz[2],atom[cx+3], \ Biso,atom[ct].rjust(12))) iatom += 1 vals = [3,0,nHet,0,0,0,6,len(Atoms),nTer,0,nSeq] fmt = 'MASTER'+11*'{:5d}' self.Write(fmt.format(*vals)) self.Write('END') self.CloseFile() print('Phase '+str(phasenam)+' written to PDB file '+str(self.fullpath))
def Readrmc6fPhase(self, filename, parent=None): '''Read a phase from a rmc6f file. ''' self.errors = 'Error opening file' fp = open(filename, 'Ur') Phase = {} Title = os.path.split(filename) G2G.SaveGPXdirectory(Title[0]) Title = os.path.splitext(Title[1])[0] Atoms = [] S = fp.readline() line = 1 SGData = None cell = None IA = 'I' Uiso = 0.01 Uij = [0. for i in range(6)] while S: self.errors = 'Error reading at line ' + str(line) Atom = [] if 'Cell' in S[:4]: cellRec = S.split(':')[1].split() abc = cellRec[:3] angles = cellRec[3:] cell = [ float(abc[0]), float(abc[1]), float(abc[2]), float(angles[0]), float(angles[1]), float(angles[2]) ] Volume = G2lat.calc_V(G2lat.cell2A(cell)) AA, AB = G2lat.cell2AB(cell) SGData = G2obj.P1SGData # P 1 elif 'Atoms' in S[:5]: S = fp.readline()[:-1] AtRec = S.split() for ix, s in enumerate(AtRec): if '.' in s: break #is points at x while S: AtRec = S.split() Atype = AtRec[1] Aname = Atype + AtRec[0] Afrac = 1.0 x, y, z = AtRec[ix:ix + 3] XYZ = np.array([float(x), float(y), float(z)]) SytSym, Mult = '1', 1 Atom = [ Aname, Atype, '', XYZ[0], XYZ[1], XYZ[2], Afrac, SytSym, Mult, IA, Uiso ] Atom += Uij Atom.append(ran.randint(0, sys.maxsize)) Atoms.append(Atom) S = fp.readline()[:-1] S = fp.readline() line += 1 fp.close() self.errors = 'Error after read complete' Phase = G2obj.SetNewPhase(Name='RMCProfile phase', SGData=SGData, cell=cell + [ Volume, ]) Phase['General']['Name'] = Title Phase['General']['Type'] = 'nuclear' Phase['General']['AtomPtrs'] = [3, 1, 7, 9] Phase['Atoms'] = Atoms return Phase