#!/usr/bin/env python
# -*- coding: utf-8 -*-
import math as m
import numpy as np
import re
from fractions import Fraction as frac
try:
import spglib as spg
except ImportError:
from pyspglib import spglib as spg
def readfile(filename):
''' read file to a list;
and del the blank lines'''
try:
f = open(filename)
except:
print('Error: cannot open file:'+ filename)
exit(0)
rst = []
try:
for line in f:
if len(line.strip()) != 0:
rst.append(line.strip())
finally:
f.close()
return rst
def appro_float(flo):
for i in range(len(flo)):
if flo[i]=="(":
flo=flo[:i]
break
return float(flo)
def symmetry(cif):
symm = [];__HALL='';__H_M=''
symmetry = []
trans = []
iline = 0
find_symm_info=False
for line in cif:
iline += 1
if '_symmetry_equiv_pos_as_xyz' in line or '_space_group_symop_operation_xyz' in line:
for item in cif[iline:]:
if item.strip()[0] != '_' and item.strip() != 'loop_':
if '\'' in item:
pattern=r'\'(.*?)\''
#print(item)
itemlist=re.findall(pattern,item)
item=itemlist[0]
if item[0] == "'" or item[0] == '"':
iitem = item[1:-1]
else:
iitem = item[:]
symm.append(iitem.strip().split(','))
find_symm_info=True
else:
break
break
elif 'name_Hall' in line:
try:
pattern=r'\'(.*?)\''
_HALL=re.findall(pattern,line)
__HALL=_HALL[0]
except:
try:
pattern=r'\"(.*?)\"'
_HALL=re.findall(pattern,line)
__HALL=_HALL[0]
except:
__HALL=' '.join(line.split()[1:])
#print __HALL
elif 'name_H-M' in line:
try:
pattern=r'\'(.*?)\''
_H_M=re.findall(pattern,line)
__H_M=_H_M[0]
except:
try:
pattern=r'\"(.*?)\"'
_H_M=re.findall(pattern,line)
__H_M=_H_M[0]
except:
__H_M=' '.join(line.split()[1:])
#print __H_M
# print(find_symm_info)
#print(__HALL)
print(symm)
print(__HALL)
print(__H_M)
if (find_symm_info==False):
if (__H_M=='' and __HALL==''):
print("P1 symmetry is assumed!")
symm=[['x',' y',' z']]
elif (__HALL!=''):
#print (SymOpsHall['I -4 2 3'])
__HALL=' '.join(__HALL.split())
#print(__HALL)
try:
symm=SymOpsHall[__HALL]
except:
raise OSError("WRONG HALL SYMBOL")
elif (__H_M!=''):
__H_M=''.join(__H_M.split())
try:
symm=HM2Hall[__H_M]
except:
raise OSError("WRONG H-M SYMBOL")
#print(symm,'symm')
for item in symm:
s2 = []
tran1 = []
for subtem in item:
subtem = subtem.strip()
try:
isprit = subtem.index('/')
stt = [istr for istr in subtem]
for i in range(0, 3): del(stt[isprit - 1])
if stt[-1] == '+' or stt[-1] == '-': del(stt[-1])
subt = ''.join(stt)
except:
subt = subtem[:]
s1 = [0, 0, 0]
if subt[0] == '-' or subt[0] == '+':
for i in range(0, len(subt) - 1, 2):
if subt[i:i+2] == '-x': s1[0] = -1
if subt[i:i+2] == '+x': s1[0] = 1
if subt[i:i+2] == '-y': s1[1] = -1
if subt[i:i+2] == '+y': s1[1] = 1
if subt[i:i+2] == '-z': s1[2] = -1
if subt[i:i+2] == '+z': s1[2] = 1
else:
if subt[0] == 'x': s1[0] = 1
if subt[0] == 'y': s1[1] = 1
if subt[0] == 'z': s1[2] = 1
for i in range(1, len(subt) - 1, 2):
if subt[i:i+2] == '-x': s1[0] = -1
if subt[i:i+1] == '+x': s1[0] = 1
if subt[i:i+2] == '-y': s1[1] = -1
if subt[i:i+2] == '+y': s1[1] = 1
if subt[i:i+2] == '-z': s1[2] = -1
if subt[i:i+2] == '+z': s1[2] = 1
t1 = 0.
for subsub in re.split('[+,-]', subtem):
try:
t1 = float(frac(subsub))
except:
continue
tran1.append(t1)
s2.append(s1)
symmetry.append(s2)
trans.append(tran1)
return (np.array(symmetry), np.array(trans))
def atominfo(cif):
loopinfo = []
atominfo = []
for i in range(0, len(cif)):
if cif[i].strip() == 'loop_':
istart = i
loopinfo = []
atominfo = []
for j in range(istart + 1, len(cif)):
if cif[j].strip() == 'loop_' or cif[j].strip().startswith("#"): break
if cif[j].strip()[0] == '_':
loopinfo.append(cif[j].strip())
else:
atominfo.append(cif[j].strip())
# debug
# print 'ttt'
# print loopinfo
# end debug
if '_atom_site_fract_x' in loopinfo: break
try:
il = loopinfo.index('_atom_site_label')
ix = loopinfo.index('_atom_site_fract_x')
iy = loopinfo.index('_atom_site_fract_y')
iz = loopinfo.index('_atom_site_fract_z')
except:
print('Unsupport CIF format!')
exit(0)
typesym = True
try:
it = loopinfo.index('_atom_site_type_symbol')
except:
typesym = False
fractional_occupation=False
try:
fractional_occupation=True
f_o = loopinfo.index('_atom_site_occupancy')
except:
fractional_occupation = False
atomtmp = [a.split() for a in atominfo]
label = []
ato = []
symbol = []
for item in atomtmp:
label.append(item[il])
ato.append([appro_float(ii) for ii in [item[ix],item[iy],item[iz]]])
for item in atomtmp:
#print(item[il])
recognized=False;two_width=False
for jk in element:
if item[il][:2].upper() == jk:
symbol.append(item[il][:2]);recognized=True;two_width=True;break
if (not two_width):
for jk in element:
if item[il][0].upper() == jk:
symbol.append(item[il][0]);recognized=True;break
if (not recognized): raise OSError("Unidentified atom type!")
#symbol.append(item[it])
if (fractional_occupation):
for item in atomtmp:
if appro_float(item[f_o])!=1.0:
raise OSError("Not suport for fractional occupation!")
equAtom = {}
for i in range(0, len(label)):
equAtom[label[i]] = [symbol[i], ato[i]]
#print(equAtom)
return equAtom,label
def lattice(cif):
for item in cif:
if "_cell_length_a" in item:
a = appro_float(item.split()[1])
if "_cell_length_b" in item:
b = appro_float(item.split()[1])
if "_cell_length_c" in item:
c = appro_float(item.split()[1])
if "_cell_angle_alpha" in item:
alpha = appro_float(item.split()[1])/180*m.pi
if "_cell_angle_beta" in item:
beta = appro_float(item.split()[1])/180*m.pi
if "_cell_angle_gamma" in item:
gamma = appro_float(item.split()[1])/180*m.pi
bc2 = b**2 + c**2 - 2*b*c*m.cos(a