mirror of https://gitlab.com/QEF/q-e.git
246 lines
8.0 KiB
Python
Executable File
246 lines
8.0 KiB
Python
Executable File
#! /usr/bin/python
|
|
|
|
###### SUM STATES #######
|
|
# Python script for summing and ploting the data from the Density Of States
|
|
# files obtained from projwfc.x. It can sum also k-solved dos, and make a plot
|
|
# with mathplotlib (if not available, gnuplot, if not avaible, print to file)
|
|
# if there is not X11 forwarding, plots in terminal.
|
|
# It does something very similar to sumpdos.f90, but with
|
|
# some extra features (use "-h" option).
|
|
#
|
|
# it takes two different inputs, the first one is the pw.x output
|
|
# ("-o" option), which is used for parsing the Fermi energy for fitting
|
|
# the PDOS curve to the right energy. The other files are the pDOS files
|
|
# ("-s" option), that can be given with shell syntax, i.e.
|
|
# pdos_atm*Fe*wfc*d* for summing all the d orbitals of Fe.
|
|
# It can also handle k solved dos files.
|
|
#
|
|
# One of the most useful feature, compared to the sumpdos.x, is the
|
|
# fact that it also builds the picture directly, so it can be directly
|
|
# visualized and exported for inclusion in a document.
|
|
# It uses mathplotlib for plotting, but if no mathplotlib is found in
|
|
# the $PYTHONPATH, it tries to use gnuplot, if no gnuplot available,
|
|
# dumps the output data to a file.
|
|
# In the that no X11 forwarding is available (i.e. ssh to the cluster),
|
|
# it shows a rough graph in the terminal, so we get an idea of the shape
|
|
# of the results.
|
|
#
|
|
# Example of usage:
|
|
# cd ....../espresso-5.0/PP/examples/example02/results/
|
|
# ../../../src/sum_states.py -o ni.dos.out -s
|
|
# ni.pdos_atm#1\(Ni\)_wfc#2\(d\) -t "Example PP/02" -xr -6 2
|
|
#
|
|
#
|
|
# The procedure for obtaining the DOS files is explained
|
|
# i.e. in (espresso-dir)/PP/examples/example02/
|
|
#
|
|
# Author: Dr. Julen Larrucea
|
|
# University of Bremen,
|
|
# Bremen Centre for Computational Materials Science, HMI Group
|
|
# julenl [at] gmail.com or larrucea [at] hmi.uni-bremen.de
|
|
#
|
|
# This file is distributed under the terms of the GNU General Public
|
|
# License. See the file `License'
|
|
# in the root directory of the present distribution,
|
|
# or http://www.gnu.org/copyleft/gpl.txt .
|
|
#######################
|
|
|
|
import sys
|
|
import os
|
|
import fnmatch
|
|
import linecache
|
|
|
|
# Some default variables
|
|
version=0.2
|
|
pwout=""
|
|
selat="*"
|
|
graphtitle=""
|
|
min_x,max_x=-10,3
|
|
min_y,max_y="",""
|
|
output_file_name="sum_dos.out"
|
|
prt="no"
|
|
|
|
print " #### sum_states.py version "+str(version)+" #### "
|
|
|
|
|
|
# Check if X11, mathplotlib and gnuplot are available
|
|
try:
|
|
os.popen("gnuplot -V").read()
|
|
prog_gnuplot="yes" # gnuplot is installed
|
|
except:
|
|
prog_gnuplot="no"
|
|
|
|
|
|
|
|
# Parse command line options
|
|
if len(sys.argv)>1:
|
|
for i in sys.argv:
|
|
if i.startswith('-'):
|
|
option=i.split('-')[1]
|
|
if option=="o":
|
|
pwout= sys.argv[sys.argv.index('-o')+1]
|
|
if option=="s":
|
|
selat= sys.argv[sys.argv.index('-s')+1]
|
|
if option=="p":
|
|
prt="yes"
|
|
if len(sys.argv) > sys.argv.index('-p')+1: # if there is a name after "-p" take it as an output name
|
|
if sys.argv[sys.argv.index('-p')+1] != "-": # otherwise default name sum_dos.out
|
|
dos_out_name=sys.argv[sys.argv.index('-p')+1]
|
|
if option=="t":
|
|
graphtitle= sys.argv[sys.argv.index('-t')+1]
|
|
if option=="xr":
|
|
min_x,max_x= float(sys.argv[sys.argv.index('-xr')+1]),float(sys.argv[sys.argv.index('-xr')+2])
|
|
if option=="yr":
|
|
min_y,max_y= float(sys.argv[sys.argv.index('-yr')+1]),float(sys.argv[sys.argv.index('-yr')+2])
|
|
if option=="v":
|
|
print "sum_dos.py version: "+version
|
|
sys.exit()
|
|
if option=="h":
|
|
print '''
|
|
-o QE output file name (for grepping Fermi E)
|
|
-s Selection of atoms for summing the DOSes. "*" for all, *1*Fe*d* for first Fe atom " (def. "*")
|
|
-p Print output to a file and aditionaly provide an output name (def. no output and "sum_dos.out")
|
|
-t set title in the head of the graph
|
|
-xr set min and max x value for the axes in the graph
|
|
-yr set min and max y value for the axes in the graph
|
|
-h print this help
|
|
-v print version
|
|
Example: sum_states.py --s sys.pdos_atm#4\(Fe2\)_wfc#2\(d\) -t "Wustite LDA+U single Fe" -xr -9 4
|
|
'''
|
|
sys.exit()
|
|
|
|
|
|
# Check for mathplotlib/gnuplot and import mpl if possible
|
|
if len(os.popen('echo $DISPLAY').read()) > 1:
|
|
graphic_plot="yes"
|
|
try:
|
|
from pylab import *
|
|
mplplot="yes"
|
|
print "pylab imported"
|
|
except:
|
|
print "There is no mathplotlib installed. Using gnuplot."
|
|
mplplot="no"
|
|
prt="yes"
|
|
else:
|
|
print "No X11. Trying to plot on terminal"
|
|
graphic_plot="no"
|
|
if prog_gnuplot=="no":
|
|
prt="yes"
|
|
|
|
|
|
# if not specified, try to find the espresso output, in order to parse the Fermi energy
|
|
if pwout == "":
|
|
for filen in filter(os.path.isfile, os.listdir('.')):
|
|
if "Program PWSCF" in linecache.getline(filen, 2):
|
|
print "Using " + filen + " as pw.x output. You can specify another one with the -o option."
|
|
pwout=filen
|
|
|
|
# Parse Fermi energy from the pw.x output
|
|
if pwout!="":
|
|
try:
|
|
os.popen("grep -a 'the Fermi energy is' "+pwout ).read()
|
|
fermi=float(os.popen("grep -a 'the Fermi energy is' "+pwout ).read().split()[4])
|
|
print "Fermi energy = ", fermi, "a.u."
|
|
except:
|
|
print "WARNING: No Fermi energy found. Using 0 e.V. instead"
|
|
fermi=0
|
|
else:
|
|
print "WARNING: No pw.x output found. Using E Fermi = 0 e.V."
|
|
fermi=0
|
|
|
|
# List of all DOS files to add
|
|
dosfiles=[]
|
|
for dfile in os.listdir('.'):
|
|
if fnmatch.fnmatch(dfile, selat):
|
|
dosfiles.append(dfile)
|
|
if len(dosfiles)==0:
|
|
print "ERROR: Provide a (list of) valid DOS file(s)"
|
|
sys.exit()
|
|
|
|
print "dosfiles list: ",
|
|
for dosfile in dosfiles:
|
|
print dosfile,
|
|
print ""
|
|
|
|
# Check wetter we have k-solved DOS
|
|
if open(dosfiles[0],'r').readline().split()[1]=="E":
|
|
ksolved="no"
|
|
print "no ksolved"
|
|
elif open(dosfiles[0],'r').readline().split()[1]=="ik":
|
|
ksolved="yes"
|
|
print "ksolved"
|
|
|
|
# Sum over all k-points and files
|
|
mat=[] # matrix with total sum of ldos
|
|
for i in range(len(dosfiles)):
|
|
mati=[] # temporal matrix for each DOS file "i"
|
|
k=0
|
|
for line in open(dosfiles[i],'r'):
|
|
if len(line) > 10 and line.split()[0] != "#":
|
|
|
|
if ksolved=="no":
|
|
mati.append([float(line.split()[0]),float(line.split()[1]),float(line.split()[2])])
|
|
|
|
if ksolved=="yes":
|
|
ik = int(line.split()[0])
|
|
if ik > k: #if it is a different k block
|
|
k=int(line.split()[0])
|
|
oldmat=[] # temporal matrix for each k-point
|
|
if ik == 1:
|
|
mati.append([float(line.split()[1]),float(line.split()[2]),float(line.split()[3])]) # append: energy, ldosup, ldosdw
|
|
elif ik == k and k > 1:
|
|
oldmat.append([float(line.split()[1]),float(line.split()[2]),float(line.split()[3])])
|
|
elif len(line) < 5 and k > 1: #if blank line, sum k-frame to the total
|
|
for j in range(len(oldmat)):
|
|
mati[j]=[mati[j][0],mati[j][1]+oldmat[j][1],mati[j][2]+oldmat[j][2]]
|
|
|
|
if mat == []: # if it is the first dos file, copy total matrix (mat) = the first dos files's data
|
|
mat=mati[:]
|
|
else:
|
|
for j in range(len(mati)): # if it is not the first file, sum values
|
|
mat[j]=[mat[j][0],mat[j][1]+mati[j][1],mat[j][2]+mati[j][2]]
|
|
|
|
|
|
print "...ploting..."
|
|
|
|
|
|
if prt=="yes":
|
|
out=open(output_file_name,"w")
|
|
x,y1,y2=[],[],[]
|
|
for i in mat:
|
|
x.append(i[0]-fermi)
|
|
y1.append(i[1])
|
|
y2.append(-i[2])
|
|
if prt=="yes": # print to a file
|
|
print>>out, i[0]-fermi, i[1], i[2]
|
|
if prt=="yes":
|
|
out.close()
|
|
|
|
|
|
if graphic_plot=="yes":
|
|
# if there is matplotlib, generate a plot with it
|
|
if mplplot=="yes":
|
|
plot(x,y1,linewidth=1.0)
|
|
plot(x,y2,linewidth=1.0)
|
|
print min(y2),max(y1)
|
|
plt.title(graphtitle)
|
|
plt.xlabel('E (eV)')
|
|
plt.ylabel('States')
|
|
plt.grid(True)
|
|
plt.rcParams.update({'font.size': 22})
|
|
plt.fill(x,y1,color='0.8')
|
|
plt.fill(x,y2,color='0.9')
|
|
if min_x and max_x:
|
|
fromx,tox=min_x,max_x
|
|
plt.axis([fromx, tox, min(y2), max(y1)])
|
|
show()
|
|
elif mplplot=="no" and prog_gnuplot=="yes": # If no mathplotlib available, use gnuplot
|
|
os.system("echo \"plot '"+ output_file_name + "' using ($1-"+str(fermi)+"):2 w l, '' u ($1"+str(fermi)+"):3 w l\" | gnuplot -persist")
|
|
elif graphic_plot=="no": # If no X forwarding available, show graph in terminal
|
|
if prog_gnuplot=="yes":
|
|
os.system("echo \"set terminal dumb; plot '"+ output_file_name + "' using ($1-"+str(fermi)+"):2 w l, '' u ($1-"+str(fermi)+"):3 w l\" | gnuplot -persist")
|
|
|
|
|
|
|
|
|