Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Band structure fails to load if vasprun is gzipped and KPOINTS isn't #1236

Closed
ajjackson opened this issue Aug 10, 2018 · 6 comments
Closed
Assignees

Comments

@ajjackson
Copy link
Contributor

System

  • Pymatgen version: 2018.7.23
  • Python version: 3.6
  • OS version: Linux Mint 17.3 64-bit

Summary

  • Using the BSVasprun class to import a band structure calculation
  • If vasprun.xml and KPOINTS files are present, it loads ok
  • If both vasprun.xml and KPOINTS files have been gzipped (i.e. vasprun.xml.gz), it loads ok
  • If only one file has been gzipped, an error is raised complaining about lack of KPOINTS file. This is quite disorientating if there is in fact a KPOINTS file...

Example code

gzip vasprun.xml
from pymatgen.io.vasp.outputs import BSVasprun
vr = BSVasprun('vasprun.xml.gz')
vr.get_band_structure(line_mode=True)

Error message

  File "/home/adam/.local/lib/python3.6/site-packages/pymatgen/io/vasp/outputs.py", line 749, in get_band_structure
    raise VaspParserError('KPOINTS needed to obtain band structure '
pymatgen.io.vasp.outputs.VaspParserError: KPOINTS needed to obtain band structure along symmetry lines.

Suggested solution

  • This behaviour is caused by the following line in pymatgen.io.vasp.outputs:
        if not kpoints_filename:
            kpoints_filename = self.filename.replace('vasprun.xml', 'KPOINTS')

Presumably the "replace" expression is intended to maintain the first part of the path (i.e. the parent directory). However, if self.filename was /some/path/to/vasprun.xml.gz then the replace operation will leave /some/path/to/KPOINTS.gz.

  • Suggested change
        if not kpoints_filename:
            vasprun_dir = os.path.abspath(os.path.join(self.filename,
                                                       os.path.pardir))
            for kpoints_filename in ('KPOINTS', 'KPOINTS.gz'):
                if os.path.exists(os.path.join(vasprun_dir, kpoints_filename)):
                    kpoints_filename = os.path.join(vasprun_dir,
                                                    kpoints_filename)
                    break
            else:
                kpoints_filename = ''
@computron
Copy link
Member

Not sure why this is assigned to me (pretty sure I had no part in the original code)?

But anyway, I am not sure what os.path.pardir refers to in the above example.

I would suggest to just use monty zpath (https://pythonhosted.org/monty/_modules/monty/os/path.html)

Maybe something like this:

from monty.os.path import zpath

if not kpoints_filename:
    kpoints_filename = zpath(os.path.join(os.path.dirname(self.filename), "KPOINTS"))

It's a bit convoluted but should work (?)

@computron
Copy link
Member

nevermind just understood the os.path.pardir as ".." - but anyway would probably suggest the code snippet above if it works

@mkhorton
Copy link
Member

@ajjackson would you be happy to submit a PR to fix using monty's zpath ? (monty is already a dependency of pymatgen, zpath handles a range of compressed formats so would be a more general solution)

@ajjackson
Copy link
Contributor Author

Can put that together, sure. This seems to be exactly what zpath is for.

@mkhorton
Copy link
Member

Many thanks :)

@shyamd
Copy link
Contributor

shyamd commented Dec 17, 2018

Fixed in in #1272

@shyamd shyamd closed this as completed Dec 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants