# coding: utf-8
# Distributed under the terms of the MIT License.
""" This script mimics the dispersion.pl script bundled
with CASTEP. For the given bands file, a bandstructure
is created. If a <seed>.adaptive.dat file exists
then a combined BS/DOS plot will be created.
"""
from os.path import isfile
import argparse
import glob
from matador import __version__, script_epilog
[docs]def main():
""" Parse args and run the script. """
parser = argparse.ArgumentParser(
prog='dispersion',
epilog=script_epilog,
description='simple plotting script for bandstructures/DOS based on matador',
add_help=True)
parser.add_argument('--version', action='version', version='matador version ' + __version__ + '.')
parser.add_argument('--pdf', action='store_true',
help='save pdf rather than showing plot in X')
parser.add_argument('--png', action='store_true',
help='save png rather than showing plot in X')
parser.add_argument('--svg', action='store_true',
help='save svg rather than showing plot in X')
parser.add_argument('--labels', type=str, nargs='*',
help='list of legend labels, comma separated')
parser.add_argument('--dos_only', action='store_true', help='only plot DOS')
parser.add_argument('--bs_only', action='store_true', help='only plot dispersion')
parser.add_argument('--preserve_kspace_distance', action='store_true',
help='when linearising kpoint path, ensure distance in reciprocal space is conserved')
parser.add_argument('--cmap', type=str,
help='matplotlib colourmap name to use')
parser.add_argument('--spin_only', type=str,
help='either "up" or "down" to only plot one channel')
parser.add_argument('-interp', '--pdis_interpolation_factor', type=float,
help='multiple by which to interpolate pDIS bands (DEFAULT: 2)')
parser.add_argument('-scale', '--pdis_point_scale', type=float,
help='point scale in pDIS plots (DEFAULT: 25)')
parser.add_argument('-p', '--projectors_to_plot', type=str,
help=("a list of projectors to plot, in the format element:orbital, "
"e.g. -p K:s,P:p. If the orbital is omitted, all orbitals will be used for that element."))
parser.add_argument('--unstacked_pdos', action='store_true',
help='plot PDOS as overlap rather than stack')
parser.add_argument('--no_pdis', action='store_true',
help='do not try to plot PDIS, even if its available')
parser.add_argument('--band_reorder', action='store_true',
help='try to reorder bands based on local gradients')
parser.add_argument('--pdos_hide_sum', action='store_true',
help='plot PDOS without sum pDOS')
parser.add_argument('--projector_colours', type=str, nargs="+",
help='override all projector colour options with a list of matplotlib-interpretable colours, '
'e.g. --projector_colours red blue #ff00ff')
parser.add_argument('--colours', type=str, nargs="+",
help='override all colour options with a list of matplotlib-interpretable colours, '
'e.g. --colours red blue #ff00ff')
parser.add_argument('-g', '--gap', action='store_true',
help='plot position and size of band gap')
parser.add_argument('-ph', '--phonons', action='store_true', default=False,
help='plot phonon calculation, rather than electronic')
parser.add_argument('-ir', '--infrared', action='store_true', default=False,
help='plot infrared spectrum from file')
parser.add_argument('-ir_ss', '--infrared_step_size', type=float, nargs='?', default=1.0,
help='step size in cm^{-1} on x-axis for IR plots; must be > 0, default is 1')
parser.add_argument('-gw', '--gaussian_width', type=float,
help=('smearing width for DOS from .bands_dos (default: 0.1 eV) or '
'.phonon_dos files (default: 10 1/cm)'))
parser.add_argument('--highlight_bands', nargs='+', type=int,
help='specify band numbres to highlight in plot')
parser.add_argument('-v', '--verbosity', type=int, default=0,
help='control verbosity of output')
parser.add_argument('-figsize', '--figsize', nargs='+', type=int,
help='figure size in inches to pass to matplotlib')
parser.add_argument('-pw', '--plot_window', nargs='+', type=float,
help='energy window [x, y] or [-x, x] to plot either side of E_F (eV)\
(DEFAULT: 5 eV)')
parser.add_argument('seed', type=str, nargs='+',
help='seedname or related filename (e.g. bands or dos file)')
kwargs = vars(parser.parse_args())
if 'gap' in kwargs:
gap = kwargs['gap']
del kwargs['gap']
seeds = kwargs.get('seed')
exts_to_strip = ['bands', 'linear.dat', 'adaptive.dat', 'pdis.dat',
'bands_dos', 'pdos.dat', 'phonon', 'phonon_dos']
for ind, seed in enumerate(seeds):
for ext in exts_to_strip:
seeds[ind] = seeds[ind].replace('.' + ext, '')
verbosity = kwargs.get('verbosity')
phonons = kwargs.get('phonons')
ir = kwargs.get('infrared')
if kwargs.get('labels'):
labels = ' '.join(kwargs.get('labels')).split(',')
else:
labels = None
if kwargs['no_pdis']:
plot_pdis = False
else:
plot_pdis = True
del kwargs['no_pdis']
cmap = kwargs.get('cmap')
band_reorder = kwargs.get('band_reorder', False)
from matador.plotting import plot_spectral, plot_ir_spectrum
del kwargs['seed']
del kwargs['verbosity']
del kwargs['labels']
del kwargs['cmap']
del kwargs['band_reorder']
bandstructure = False
dos = False
for seed in seeds:
if not phonons and not ir:
bs_seed = seed + '.bands'
bandstructure = isfile(bs_seed)
dos_seeds = glob.glob(seed + '*.dat')
if isfile(seed + '.bands_dos'):
dos_seeds.append(seed + '.bands_dos')
dos = any([isfile(dos_seed) for dos_seed in dos_seeds])
elif phonons and not ir:
phonon_seed = seed + '.phonon'
bandstructure = isfile(phonon_seed)
dos_seed = seed + '.phonon_dos'
dos = isfile(dos_seed)
elif ir:
if len(seeds) > 1:
exit('Multiple seeds not supported for IR plot.')
ir_seed = seed + '.phonon'
if bandstructure:
cell_seed = seed + '.cell'
cell = isfile(cell_seed)
else:
cell = False
if kwargs.get('dos_only') and dos:
bandstructure = False
if kwargs.get('bs_only') and bandstructure:
dos = False
if not any([bandstructure, dos, ir]):
raise SystemExit("Unable to find files for seedname {}".format(seed))
if not ir:
return plot_spectral(
seeds,
plot_bandstructure=bandstructure,
plot_dos=dos,
plot_pdis=plot_pdis,
cell=cell,
gap=gap,
verbosity=verbosity,
labels=labels,
cmap=cmap,
band_reorder=band_reorder,
**kwargs
)
if ir:
return plot_ir_spectrum(
ir_seed,
bin_width=kwargs['infrared_step_size'],
**kwargs
)
exit("Issue plotting {}: did you specify -ph/-ir appropriately?"
.format(seeds))
if __name__ == '__main__':
main()