Skip to content

Commit

Permalink
2020-01-31 enable range and s p d specification abilities for occupat…
Browse files Browse the repository at this point in the history
…ion plot.(pyband only, as of now)
  • Loading branch information
Chengcheng-Xiao committed Jan 31, 2020
1 parent 14aed42 commit 1a2664d
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 38 deletions.
44 changes: 35 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The default output image name can be changed by adding `-o
YourImageName.suffix` to the above command line. Note that the image format is
automatically recognized by the script, which can be any format that is
supported by `matplotlib`. The size of the image can also be speified by `-s
width height` command line arguments.
width height` command line arguments.

The labels of the high-symmetry K-points, which are not shown in the figure, can
be designate by `-k` flag.
Expand All @@ -35,6 +35,14 @@ atoms` comes to help.

```$ pyband --occ '1 3 4'```

or

```$ pyband --occ '1-4'```

or combination

```$ pyband --occ '1-4, 5-6, 7'```

![band_with_atom_weight](examples/band_with_atoms_weight.png)

where `1 3 4` are the atom index starting from 1 to #atoms in the above image.
Expand All @@ -49,6 +57,15 @@ The spd-projected weight can also be specefied:

```$ pyband --occ '1 3 4' --spd '4 5 6 7 8' ```

or

```$ pyband --occ '1 3 4' --spd 'd' ```

or in combination

```$ pyband --occ '1 3 4' --spd 's p d 9-12' ```


![band_with_atom_weight_spd](examples/band_with_atoms_weight_spd.png)

where in the arguments of `--spd`:
Expand All @@ -62,10 +79,19 @@ where in the arguments of `--spd`:
More command line arguments can be found by `pyband -h`.

For Mac users, [iterm2](https://iterm2.com/) combined with [imgcat](https://iterm2.com/documentation-shell-integration.html) can be used to show inline image. Just modify the last line from:
```
call(['feh', '-xdF', opts.bandimage])
```
to
```
call(['~/.iterm2/imgcat', opts.bandimage])
```

## pydos

This script is used to plot partial density of states (pDOS) from VASP `PROCAR`
files.
files.

`pydos -p '1 3 4' -p '2 7 8' -p '5 6 9' -z 0.65 -x -1 2 -y 0 6`

Expand All @@ -85,12 +111,12 @@ This script can plot PDOS from multiple VASP `PROCARs` in multiple axes, example

npdos -nr 2 -f 4.8 4.0 \
-o g1.png \
-nxminor 4 \
-i pbe/scf/PROCAR -a 0 -p 0 -pv n -tlab 'PBE-PBE' -tlw 0.5 -tlc r \
-i scf-pbe_opt-hse/PROCAR -a 0 -p 0 -pv n -tlab 'HSE-PBE' -tlw 0.5 -tlc b \
-i scf-hse_opt-pbe/PROCAR -a 1 -p 0 -pv n -tlab 'PBE-HSE' -tlw 0.5 -tlc r \
-i hse/scf/PROCAR -a 1 -p 0 -pv n -tlab 'HSE-HSE' -tlw 0.5 -tlc b \
-x -4 6 -x -6 6 \
-nxminor 4 \
-i pbe/scf/PROCAR -a 0 -p 0 -pv n -tlab 'PBE-PBE' -tlw 0.5 -tlc r \
-i scf-pbe_opt-hse/PROCAR -a 0 -p 0 -pv n -tlab 'HSE-PBE' -tlw 0.5 -tlc b \
-i scf-hse_opt-pbe/PROCAR -a 1 -p 0 -pv n -tlab 'PBE-HSE' -tlw 0.5 -tlc r \
-i hse/scf/PROCAR -a 1 -p 0 -pv n -tlab 'HSE-HSE' -tlw 0.5 -tlc b \
-x -4 6 -x -6 6 \
-z 3.3129 -z 3.3726 -z 3.5583 -z 3.6332 \
-panelloc 0.01 0.95 \
-q
Expand Down Expand Up @@ -124,7 +150,7 @@ This script also make use of `ASE` to adsorb molecules onto the slab surface.
Examples usage:

```
molAdd.py -m H2O -i POSCAR -a 36 --height 2.0 -rotx 60 -v 15.0
molAdd.py -m H2O -i POSCAR -a 36 --height 2.0 -rotx 60 -v 15.0
```

where we add a H2O molecule above the atom with index 36 (which is the 37th
Expand Down
124 changes: 95 additions & 29 deletions pyband
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ from optparse import OptionParser
__version__ = "1.0"
############################################################

# CCX 2020-01-31 customize praser
def parseList(string):
m = re.match(r'(\d+)(?:-(\d+))?$', string)
# ^ (or use .split('-'). anyway you like.)
if not m:
raise ArgumentTypeError("'" + string + "' is not a range of number. Expected forms like '0-5' or '2'.")
start = m.group(1)
end = m.group(2) or start
return list(range(int(start,10), int(end,10)+1))


def WeightFromPro(infile='PROCAR', whichAtom=None, spd=None, lsorbit=False):
"""
Contribution of selected atoms to the each KS orbital
Expand All @@ -29,7 +40,7 @@ def WeightFromPro(infile='PROCAR', whichAtom=None, spd=None, lsorbit=False):
else:
Weights = np.asarray([line.split()[-1] for line in FileContents
if not re.search('[a-zA-Z]', line)], dtype=float)

nspin = Weights.shape[0] // (nkpts * nbands * nions)
nspin //= 4 if lsorbit else 1

Expand All @@ -38,7 +49,7 @@ def WeightFromPro(infile='PROCAR', whichAtom=None, spd=None, lsorbit=False):
Weights = Weights[:,:,:,0,:]
else:
Weights.resize(nspin, nkpts, nbands, nions)

if whichAtom is None:
return np.sum(Weights, axis=-1)
else:
Expand Down Expand Up @@ -75,11 +86,11 @@ def get_bandInfo(inFile = 'OUTCAR'):
# break

# basis vector of reciprocal lattice
# B = np.array([line.split()[3:] for line in outcar[ibasis:ibasis+3]],
# B = np.array([line.split()[3:] for line in outcar[ibasis:ibasis+3]],

# When the supercell is too large, spaces are missing between real space
# lattice constants. A bug found out by Wei Xie (weixie4@gmail.com).
B = np.array([line.split()[-3:] for line in outcar[ibasis:ibasis+3]],
B = np.array([line.split()[-3:] for line in outcar[ibasis:ibasis+3]],
dtype=float)
# k-points vectors and weights
tmp = np.array([line.split() for line in outcar[Lvkpts:Lvkpts+nkpts]],
Expand Down Expand Up @@ -108,7 +119,7 @@ def get_bandInfo(inFile = 'OUTCAR'):
Nk_in_seg = int(kp[1].split()[0])
Nseg = nkpts // Nk_in_seg
vkpt_diff = np.zeros_like(vkpts, dtype=float)

for ii in range(Nseg):
start = ii * Nk_in_seg
end = (ii + 1) * Nk_in_seg
Expand Down Expand Up @@ -268,21 +279,21 @@ def saveband_dat(kpath, bands):
for ii in range(nkpts):
line = '%10.4f ' % kpath[ii]
for jj in range(nbands):
line += '%8.4f' % bands[0,ii,jj]
line += '%8.4f' % bands[Ispin,ii,jj]
line += '\n'
out.write(line)

############################################################
def command_line_arg():
usage = "usage: %prog [options] arg1 arg2"
usage = "usage: %prog [options] arg1 arg2"
par = OptionParser(usage=usage, version= __version__)

par.add_option('-f', '--file',
action='store', type="string",
dest='filename', default='OUTCAR',
help='location of OUTCAR')

par.add_option('--procar',
par.add_option('--procar',
action='store', type="string", dest='procar',
default='PROCAR',
help='location of the PROCAR')
Expand Down Expand Up @@ -317,71 +328,71 @@ def command_line_arg():
default=1.0,
help='linewidth of the band plot')

par.add_option('--dpi',
par.add_option('--dpi',
action='store', type="int", dest='dpi',
default=360,
help='resolution of the output image')

par.add_option('--occ',
par.add_option('--occ',
action='append', type="string", dest='occ',
default=[],
help='orbital contribution of each KS state')

par.add_option('--occL',
par.add_option('--occL',
action='store_true', dest='occLC',
default=False,
help='use Linecollection or Scatter to show the orbital contribution')

par.add_option('--occLC_cmap',
par.add_option('--occLC_cmap',
action='store', type='string', dest='occLC_cmap',
default='jet',
help='colormap of the line collection')

par.add_option('--occLC_lw',
par.add_option('--occLC_lw',
action='store', type='float', dest='occLC_lw',
default=2.0,
help='linewidth of the line collection')

par.add_option('--occLC_cbar_pos',
par.add_option('--occLC_cbar_pos',
action='store', type='string', dest='occLC_cbar_pos',
default='top',
help='position of the colorbar')

par.add_option('--occLC_cbar_size',
par.add_option('--occLC_cbar_size',
action='store', type='string', dest='occLC_cbar_size',
default='3%',
help='size of the colorbar, relative to the axis')

par.add_option('--occLC_cbar_pad',
par.add_option('--occLC_cbar_pad',
action='store', type='float', dest='occLC_cbar_pad',
default=0.02,
help='pad between colorbar and axis')

par.add_option('--occM',
par.add_option('--occM',
action='append', type="string", dest='occMarker',
default=[],
help='the marker used in the plot')

par.add_option('--occMs',
par.add_option('--occMs',
action='append', type="int", dest='occMarkerSize',
default=[],
help='the size of the marker')

par.add_option('--occMc',
par.add_option('--occMc',
action='append', type="string", dest='occMarkerColor',
default=[],
help='the color of the marker')

par.add_option('--spd',
action='store', type="string", dest='spdProjections',
par.add_option('--spd',
action='append', type="string", dest='spdProjections',
default=None,
help='Spd-projected wavefunction character of each KS orbital.')

par.add_option('--lsorbit',
action='store_true', dest='lsorbit',
help='Spin orbit coupling on, special treament of PROCAR')

par.add_option('-q', '--quiet',
par.add_option('-q', '--quiet',
action='store_true', dest='quiet',
help='not show the resulting image')

Expand Down Expand Up @@ -409,18 +420,73 @@ if __name__ == '__main__':
opts.occMarkerSize = occMs

whts = []
occTmp = []
for occ in opts.occ:
alist = np.array(occ.split(), dtype=int)
nlist = [x for x in alist if not x == -1]
cmark, = np.where(alist == -1)
for ii in cmark:
nlist += range(alist[ii + 1], alist[ii + 2] + 1)
occAtom = set(nlist)
# CCX 2020-01-31 prase atoms with -
if len(occ.split()) != 1:
for occ_bak in occ.split():
if '-' in occ_bak:
occTmp += parseList(occ_bak)
else:
occTmp += [int(i) for i in occ_bak.split()]
else:
occ_bak = occ
if '-' in occ_bak:
occTmp += parseList(occ_bak)
else:
occTmp += [int(i) for i in occ_bak.split()]
occAtom = set(occTmp)

#alist = np.array(occ.split(), dtype=int)
#nlist = [x for x in alist if not x == -1]
#cmark, = np.where(alist == -1)
#for ii in cmark:
# nlist += range(alist[ii + 1], alist[ii + 2] + 1)
#occAtom = set(nlist)


# occAtom = [int(x) for x in opts.occ.split()]
# whts = WeightFromPro(opts.procar, whichAtom = occAtom)
if opts.spdProjections and (Nocc == 1):
angularM = [int(x) for x in opts.spdProjections.split()]
# CCX 2020-01-31 prase spd
angTmp = []
for angall in opts.spdProjections:
if len(angall.split()) != 1:
for ang in angall.split():
# for range
if '-' in ang:
angTmp += parseList(ang)
# for s p d preset
elif ang == 's':
angTmp += [0]
elif ang == 'p':
angTmp += [1,2,3]
elif ang == 'd':
angTmp += [4,5,6,7,8]
elif ang == 'f':
angTmp += [9,10,11,12,13,14,15]
else:
angTmp += [int(i) for i in ang.split()]
else:
ang = angall
# for range
if '-' in ang:
angTmp += parseList(ang)
# for s p d preset
elif ang == 's':
angTmp += [0]
elif ang == 'p':
angTmp += [1,2,3]
elif ang == 'd':
angTmp += [4,5,6,7,8]
elif ang == 'f':
angTmp += [9,10,11,12,13,14,15]
else:
angTmp += [int(i) for i in ang.split()]


angularM = list(set(angTmp))
#angularM = [int(x) for x in opts.spdProjections.split()]
# print angularM
whts.append(WeightFromPro(opts.procar, whichAtom=occAtom,
spd=angularM, lsorbit=opts.lsorbit))
Expand Down

0 comments on commit 1a2664d

Please sign in to comment.