import numpy as np
import re
import logging
import matplotlib.pyplot as plt
import sys
from ..utilsprocar import UtilsProcar
class ProcarParser:
"""Parses a PROCAR file and store it in memory. It only deals with
PROCAR files, that means no Fermi energy (UtilsProcar.FermiOutcar
can help), and the reciprocal vectors should be supplied (if used,
see UtilsProcar class).
Members:
__init__(self, loglevel): The setup the variables internally, `loglevel`
sets the verbosity level ie: `loglevel=logging.DEBUG` for debugging. Its
default is `logging.WARNING`
readFile(self, procar=None, permissive=False, recLattice=None):
The only method of the API it load the file completely.
Arguments:
`procar=None`: name of the PROCAR file, can be a gzipped file (the
extension is no required). The default covers a wide range
of obvious alternatives.
`permissive=False`: Set to `True` if the PROCAR file has problems reading
the Kpoints (stupid Fortran), but in that case the
Kpoints mesh will be discarded. Future updates could
allow it to handle other formating/corruption issues.
`recLattice`=None: Reciprical Vectors, you want to provide them since not
all the paths on the BZ are the same.
Don't use the other methods beggining with underscores "_"
Example:
To read a PROCAR or PROCAR.gz file:
>>> foo = ProcarParser()
>>> foo.readFile()
To include the reciprocal vectors, and file name MyFirstPROCAR
>>> outcarparser = UtilsProcar()
>>> recLat = outcarparser.RecLatOutcar(args.outcar)
>>> foo = ProcarParser()
>>> foo.readFile("MyFirstPROCAR", recLat=recLat)
"""
def __init__(self, loglevel=logging.WARNING):
# array with k-points, they have the following values
# -None: if not parsed (yet) or parsed with a `permissive` flag on
# -direct coordinates: if a recLattice was not supplied to the parser
# -cartesian coords: if a recLattice was supplied to the parser.
# In the later cases, self.kpoints.shape=(self.kpointsCount, 3)
self.kpoints = None
# Number of kpoints, as given by the KPOINTS header (PROCAR file)
self.kpointsCount = None
# bands headers present in PROCAR file.
# self.bands.shape=(self.kpointsCount,self.bandsCount)
self.bands = None
# Number of bands. For a spin polarized calculation the number of
# bands is double (spin ip + spin down). On this array there is no
# distinction between spin up and down
self.bandsCount = None
#Number of ions+1 the +1 is the 'tot' field, ie: the sum over all atoms
self.ionsCount = None
self.fileStr = None #the actual file, stored in memory
self.spd = None #the atom/orbital projected data
self.cspd = None #spd data with the phase
self.orbitalName = [
"s", "py", "pz", "px", "dxy", "dyz", "dz2", "dxz", "dx2", "tot"
]
self.orbitalCount = None #number of orbitals
# number of spin components (blocks of data), 1: non-magnetic non
# polarized, 2: spin polarized collinear, 4: non-collinear
# spin.
# NOTE: before calling to `self._readOrbital` the case '4'
# is marked as '1'
self.ispin = None
self.recLattice = None #reciprocal lattice vectors
self.utils = UtilsProcar()
self.log = logging.getLogger("ProcarParser")
self.log.setLevel(loglevel)
self.ch = logging.StreamHandler()
self.ch.setFormatter(
logging.Formatter("%(name)s::%(levelname)s:"
" %(message)s"))
self.ch.setLevel(logging.DEBUG)
self.log.addHandler(self.ch)
#At last, one message to the logger.
self.log.debug("Procar instanciated")
return
@property
def nspin(self):
"""
number of spin, default is 1.
"""
nspindict = {1: 1, 2: 2, 4: 2, None: 1}
return nspindict[self.ispin]
@property
def spd_orb(self):
# indices: ikpt, iband, ispin, iion, iorb
# remove indices and total from iorb.
return self.spd[:, :, :, 1:-1]
def _readKpoints(self, permissive=False):
"""Reads the k-point headers. A typical k-point line is:
k-point 1 : 0.00000000 0.00000000 0.00000000 weight = 0.00003704\n
fills self.kpoint[kpointsCount][3]
The weights are discarded (are they useful?)
"""
self.log.debug("readKpoints")
if not self.fileStr:
log.warning(
"You should invoke `procar.readFile()` instead. Returning")
return
# finding all the K-points headers
self.kpoints = re.findall(r"k-point\s+\d+\s*:\s+([-.\d\s]+)",
self.fileStr)
self.log.debug(str(len(self.kpoints)) + " K-point headers found")
self.log.debug("The first match found is: " + str(self.kpoints[0]))
# trying to build an array
self.kpoints = [x.split() for x in self.kpoints]
try:
self.kpoints = np.array(self.kpoints, dtype=float)
except ValueError:
self.log.error("Ill-formatted data:")
print('\n'.join([str(x) for x in self.kpoints]))
if permissive is True:
# Discarding the kpoints list, however I need to set
# self.ispin beforehand.
if len(self.kpoints) == self.kpointsCount:
self.ispin = 1
elif len(self.kpoints) == 2 * self.kpointsCount:
self.ispin = 2
else:
raise ValueError("Kpoints do not match with ispin=1 or 2.")
self.kpoints = None
self.log.warning(
"K-points list is useless, setting it to `None`")
return
else:
raise ValueError(
"Badly formated Kpoints headers, try `--permissive`")
# if successful, go on
# trying to identify an non-polarized or non-collinear case, a
# polarized case or a defective file
if len(self.kpoints) != self.kpointsCount:
#if they do not match, may means two things a spin polarized
#case or a bad file, lets check
self.log.debug("Number of kpoints do not match, looking for a "
"spin-polarized case")
# lets start testing if it is spin polarized, if so, there
# should be 2 identical blocks of kpoints.
up, down = np.vsplit(self.kpoints, 2)
if (up == down).all():
self.log.info("Spin-polarized calculation found")
self.ispin = 2
# just keeping one set of kpoints (the other will be
# discarded)
self.kpoints = up
else:
self.log.error("Number of K-points do not match! check them.")
raise RuntimeError("Bad Kpoints list.")
# if ISPIN != 2 setting ISPIN=1 (later for the non-collinear case 1->4)
# It is unknown until parsing the projected data
else:
self.ispin = 1
#checking again, for compatibility,
if len(self.kpoints) != self.kpointsCount:
raise RuntimeError(
"Kpoints number do not match with metadata (header of PROCAR)")
self.log.debug(str(self.kpoints))
self.log.info("The kpoints shape is " + str(self.kpoints.shape))
if self.recLattice is not None:
self.log.info("Changing to cartesians coordinates")
self.kpoints = np.dot(self.kpoints, self.recLattice)
self.log.debug("New kpoints: \n" + str(self.k
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
共38个文件
py:35个
cfg:1个
procar:1个
资源分类:Python库 所属语言:Python 资源全名:pyprocar-4.0.4.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
资源推荐
资源详情
资源评论
收起资源包目录
pyprocar-4.0.4.tar.gz (38个子文件)
pyprocar-4.0.4
PKG-INFO 582B
bin
procar 39KB
pyprocar
scriptFilter.py 2KB
procarplotcompare
procarplotcompare.py 10KB
__init__.py 49B
procarplot
__init__.py 36B
procarplot.py 5KB
scriptFermi3D.py 25KB
scriptCompareBands.py 10KB
procarfilefilter
__init__.py 84B
procarfilefilter.py 14KB
scriptUnfold.py 3KB
scriptVector.py 3KB
procarsymmetry
__init__.py 43B
procarsymmetry.py 8KB
procarunfold
unfolder.py 5KB
procar_unfolder.py 4KB
_bak.procarparser.py 20KB
__init__.py 44B
fatband.py 4KB
scriptBandsplot.py 7KB
fermisurface
__init__.py 39B
fermisurface.py 6KB
scriptKmesh2D.py 453B
__init__.py 2KB
procarparser
procarparser.py 29KB
__init__.py 76B
scriptKpath.py 2KB
scriptFermi2D.py 4KB
scriptRepair.py 313B
procarselect
procarselect.py 6KB
__init__.py 76B
scriptCat.py 549B
scriptAbinitMerge.py 337B
utilsprocar
utilsprocar.py 10KB
__init__.py 37B
setup.cfg 39B
setup.py 1KB
共 38 条
- 1
资源评论
挣扎的蓝藻
- 粉丝: 13w+
- 资源: 15万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功