Source code for GSASII.imports.G2phase_RRUFF

'''Reads structure files downloaded from the RRUFF database either as ASCII
text files or .rtf files that somehow are generated
'''
import sys
import numpy as np
import random as ran
from .. import GSASIIobj as G2obj
from .. import GSASIIspc as G2spc
from .. import GSASIIlattice as G2lat

[docs] class RRUFFReader(G2obj.ImportPhase): '''A fairly quickly-written importer to pull out the phase info from a RRUFF database (https://rruff.info) text file. ''' def __init__(self): super(self.__class__,self).__init__( # fancy way to say ImportPhase.__init__ extensionlist=('.txt'), strictExtension=True, formatName = 'RRUFF DIF file', longFormatName = 'RRUFF database DIF file download (*.txt)' )
[docs] def ContentsValidator(self, filename): "Test if the file has CELL PARAMETERS: and SPACE GROUP: entries" with open(filename,'r') as fp: txt = fp.read() status = True for s in ('CELL PARAMETERS:','SPACE GROUP:'): if not s in txt: print(s,'not found') if self.errors is None: self.errors = '' self.errors += f'no {s} record found; not valid. ' status = False if not ' ATOM ' in txt: print('ATOM line not found') if self.errors is None: self.errors = '' self.errors += 'no ATOM record found; no structure. ' status = False fp.close() return status
[docs] def Reader(self,filename,ParentFrame=None, **unused): 'Read a DIF file from RRUFF' #self.errors = 'Error opening file' Title = '' atomsmode = False fp = open(filename, 'r') SGData = None Atoms = [] cell = None for line in fp.readlines(): if len(line) == 0: continue line = line.strip() if atomsmode: # all DIF files appear to have atoms as element, X, Y, Z, OCCUPANCY, ISO(B) if r'\par' in line: # some files seem to have some formatting line = line.split('\\par')[0] try: Atype = line.split()[0] x,y,z,Afrac,B = [float(i) for i in line.split()[1:]] Uiso = B/(8*np.pi**2) 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] IA = 'I' i = 1 while f"{Atype}{i}" in [i[0] for i in Atoms]: i += 1 if i > 999: Aname = f"{Atype}?" break else: Aname = f"{Atype}{i}" if Atype.upper() in ['WA','OH','OW','OA','OB','OC','OD','OE','OL','OP','OO']: Atype = 'O' Atom = [Aname,Atype,'',x,y,z,Afrac,SytSym,Mult,IA,Uiso] Atom += 6*[0] Atom.append(ran.randint(0,sys.maxsize)) Atoms.append(Atom) except: atomsmode = False break if Title == '': if '\\rtf' in line: continue Title = line if r'\par' in line: # some files seem to have some formatting Title = line.split()[-1].split('\\')[0] if 'CELL PARAMETERS:' in line: L = line.split(':')[1] if r'\par' in line: # some files seem to have some formatting L = L.split('\\par')[0] cellRec = L.split() abc = cellRec[0:3] angles = cellRec[3:] cell=[float(abc[0]),float(abc[1]),float(abc[2]), float(angles[0]),float(angles[1]),float(angles[2])] Volume = float(G2lat.calc_V(G2lat.cell2A(cell))) elif 'SPACE GROUP:' in line: SGData = G2obj.P1SGData # P 1 S = line.split(':')[1].strip() if r'\par' in S: # some files seem to have some formatting S = S.split()[0] Sinit = S E,SGData = G2spc.SpcGroup(S) if E: SpGrpNorm = G2spc.StandardizeSpcName(S) if SpGrpNorm: E,SGData = G2spc.SpcGroup(SpGrpNorm) if E and '_' in S: S = S.replace('_','') if E: E,SGData = G2spc.SpcGroup(S[0]+' '+S[1:]) # some space group names that show up in RRUFF SGfixDict = {'B2/b': 'B 2/b 1 1', 'Bb21m':'B b 21 m', 'P21/b': 'P 21/b 1 1', 'P21212': 'P 21 21 2', 'P21ca': 'P 21 c a', 'P21cn': 'P 21 c n', 'P21nb': 'P21 n b', 'P21nm': 'P21 n m', 'P63cm': 'P63 c m', 'P63mc': 'P63 m c', 'Pn21a': 'P n 21 a', 'Pn21m': 'P n 21 m'} if E and S in SGfixDict: E,SGData = G2spc.SpcGroup(SGfixDict[S]) if E: self.warnings += f'ERROR in space group symbol {Sinit!r}' self.warnings += '\nThe space group has been set to "P 1". ' self.warnings += "Change this in phase's General tab." self.warnings += " Error msg="+G2spc.SGErrors(E) elif SGData['SpGrp'] in G2spc.spg2origins: self.warnings += f"WARNING space group {SGData['SpGrp']} has two Origins" elif 'ATOM ' in line: atomsmode = True if SGData is None: if self.errors is None: self.errors = '' self.errors += 'no Space Group record found; not valid. ' return False if cell is None: if self.errors is None: self.errors = '' self.errors += 'no CELL record found; not valid. ' return False if len(Atoms) == 0: if self.errors is None: self.errors = '' self.errors += 'no Atoms found; not valid. ' return False if cell[3] == cell[4] == cell[5] and cell[3] != 90: self.warnings += f'Note: {filename!r} has rhombohedral cell, changing space group' E,SGData = G2spc.SpcGroup(SGData['SpGrp'] + ' R') self.MPhase = None self.Phase = G2obj.SetNewPhase(Name=Title,SGData=SGData,cell=cell+[Volume,]) self.Phase['General']['Name'] = Title self.Phase['General']['Type'] = 'nuclear' self.Phase['General']['AtomPtrs'] = [3,1,7,9] self.Phase['Atoms'] = Atoms fp.close() return True