Repository: materialsproject/pymatgen

Issue #3586: `Vasprun` parser raises a `FileNotFoundError` when searching for POTCARs with pymatgen 2024.1.26
Created: 2024-01-26T18:22:58Z
Python version
3.11
Pymatgen version
2024.1.26
Operating system version
Ubuntu
Current behavior
Do the following in a completed folder containing a VASP run.
from pymatgen.io.vasp.outputs import Vasprun

Vasprun('vasprun.xml')
File /scratch/network/asrosen/software/miniconda/envs/quacc/lib/python3.10/site-packages/pymatgen/i
o/vasp/outputs.py:296, in Vasprun.__init__(self, filename, ionic_step_skip, ionic_step_offset, pars
e_dos, parse_eigen, parse_projected_eigen, parse_potcar_file, occu_tol, separate_spins, exception_o
n_bad_xml)
    293         self.nionic_steps = len(self.ionic_steps)
    295     if parse_potcar_file:
--> 296         self.update_potcar_spec(parse_potcar_file)
    297         self.update_charge_from_potcar(parse_potcar_file)
    299 if self.incar.get("ALGO") not in ["CHI", "BSE"] and not self.converged and self.parameters.
get("IBRION") != 0:
File /scratch/network/asrosen/software/miniconda/envs/quacc/lib/python3.10/site-packages/pymatgen/i
o/vasp/outputs.py:1054, in Vasprun.update_potcar_spec(self, path)
   1046 def update_potcar_spec(self, path):
   1047     """
   1048     Args:
   1049         path: Path to search for POTCARs
   (...)
   1052         Potcar spec from path.
   1053     """
-> 1054     if potcar := self.get_potcars(path):
   1055         self.potcar_spec = [
   1056             {"titel": sym, "hash": ps.md5_header_hash, "summary_stats": ps._summary_stats}
   1057             for sym in self.potcar_symbols
   1058             for ps in potcar
   1059             if ps.symbol == sym.split()[1]
   1060         ]
File /scratch/network/asrosen/software/miniconda/envs/quacc/lib/python3.10/site-packages/pymatgen/i
o/vasp/outputs.py:1010, in Vasprun.get_potcars(self, path)
   1007 else:
   1008     search_path = os.path.split(self.filename)[0] if path is True else str(path)
   1009     potcar_paths = [
-> 1010         f"{search_path}/{fn}" for fn in os.listdir(search_path) if fn.startswith("POTCAR") 
and ".spec" not in fn
   1011     ]
   1013 for potcar_path in potcar_paths:
   1014     try:
FileNotFoundError: [Errno 2] No such file or directory: ''
Here are the files in my directory (can share over Slack since POTCAR is proprietary).
AECCAR0       CHGCAR          IBZKPT        OSZICAR      POTCAR       vasp.out
AECCAR1       CONTCAR         INCAR         OUTCAR       POTCAR.orig  vaspout.h5
AECCAR2       custodian.json  INCAR.orig    PCDAT        PROCAR       vasprun.xml
ase-sort.dat  DOSCAR          KPOINTS       POSCAR       REPORT       WAVECAR
CHG           EIGENVAL        KPOINTS.orig  POSCAR.orig  std_err.txt  XDATCAR

Likely introduced in #3491.
Expected Behavior
The Vasprun should correctly identify the POTCAR file in the present working directory.

Duplicate issue #3604: Vasprun get_potcars fails if no explicit directories in file path
Created: 2024-02-05T21:34:50Z
Python version
3.9.18
Pymatgen version
2024.1.27
Operating system version
MacOS 13.6.4
Current behavior
When loading a Vasprun using a 'vasprun.xml' file in the present working directory (i.e. Vasprun('vasprun.xml')), it throws a FileNotFoundError when it attempts to get_potcar. The traceback is below.
Specifically, in get_potcar, it uses os.path.split to get the directory of the filename. But in this case, that is an empty string. The code then fails in the next line, when it attempts to evaluate os.listdir('').
If I instead call Vasprun('./vasprun.xml') or Vasprun('vasprun.xml', parse_potcar_file=False) the code runs without error.
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[2], line 1
----> 1 Vasprun('vasprun.xml')

File ~/anaconda3/envs/ifermi/lib/python3.9/site-packages/pymatgen/io/vasp/outputs.py:296, in Vasprun.__init__(self, filename, ionic_step_skip, ionic_step_offset, parse_dos, parse_eigen, parse_projected_eigen, parse_potcar_file, occu_tol, separate_spins, exception_on_bad_xml)
    293         self.nionic_steps = len(self.ionic_steps)
    295     if parse_potcar_file:
--> 296         self.update_potcar_spec(parse_potcar_file)
    297         self.update_charge_from_potcar(parse_potcar_file)
    299 if self.incar.get("ALGO") not in ["CHI", "BSE"] and not self.converged and self.parameters.get("IBRION") != 0:

File ~/anaconda3/envs/ifermi/lib/python3.9/site-packages/pymatgen/io/vasp/outputs.py:1054, in Vasprun.update_potcar_spec(self, path)
   1046 def update_potcar_spec(self, path):
   1047     """
   1048     Args:
   1049         path: Path to search for POTCARs
   (...)
   1052         Potcar spec from path.
   1053     """
-> 1054     if potcar := self.get_potcars(path):
   1055         self.potcar_spec = [
   1056             {"titel": sym, "hash": ps.md5_header_hash, "summary_stats": ps._summary_stats}
   1057             for sym in self.potcar_symbols
   1058             for ps in potcar
   1059             if ps.symbol == sym.split()[1]
   1060         ]

File ~/anaconda3/envs/ifermi/lib/python3.9/site-packages/pymatgen/io/vasp/outputs.py:1010, in Vasprun.get_potcars(self, path)
   1007 else:
   1008     search_path = os.path.split(self.filename)[0] if path is True else str(path)
   1009     potcar_paths = [
-> 1010         f"{search_path}/{fn}" for fn in os.listdir(search_path) if fn.startswith("POTCAR") and ".spec" not in fn
   1011     ]
   1013 for potcar_path in potcar_paths:
   1014     try:

FileNotFoundError: [Errno 2] No such file or directory: ''
Expected Behavior
Vasprun.get_potcar should be able to handle the case where self.filename is a relative path with no directories.
This could be done by adding a line if search_path == '': search_path = None. This will then work as expected, because os.listdir(None) acts as if the argument were the present working directory.
Minimal example
In a directory containing a vasprun.xml file...
from pymatgen.io.vasp.outputs import Vasprun
Vasprun('vasprun.xml')
Relevant files to reproduce this bug
No response

Closing comment (2024-02-06T16:35:24Z): Thanks @bfield1, this is a duplicate of #3586, and should be fixed in #3587. Can you pip install from git and see if this issue is resolved (pip install git+https://github.com/materialsproject/pymatgen.git)?