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

.hdf5 files are now forcibly closed (if necessary) upon restarting ARMC procedures #60

Merged
merged 2 commits into from
Dec 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion FOX/classes/armc.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@

from .monte_carlo import MonteCarlo
from ..logger import Plams2Logger, get_logger
from ..io.hdf5_utils import create_hdf5, to_hdf5, create_xyz_hdf5, _get_filename_xyz
from ..io.hdf5_utils import (
create_hdf5, to_hdf5, create_xyz_hdf5, _get_filename_xyz, hdf5_clear_status
)
from ..io.file_container import NullContext
from ..functions.utils import get_template
from ..armc_functions.sanitization import init_armc_sanitization
Expand Down Expand Up @@ -520,6 +522,16 @@ def restart(self) -> None:
if not os.path.isfile(xyz):
create_xyz_hdf5(self.hdf5_file, self.molecule, iter_len=self.sub_iter_len)

# Check that both .hdf5 files can be opened; clear their status if not
closed = hdf5_clear_status(xyz)
if not closed:
self.logger.warning(f"Unable to open ...{os.sep}{os.path.basename(xyz)}, "
"file status was forcibly reset")
closed = hdf5_clear_status(self.hdf5_file)
if not closed:
self.logger.warning(f"Unable to open ...{os.sep}{os.path.basename(self.hdf5_file)}, "
"file status was forcibly reset")

# Finish the current set of sub-iterations
j += 1
for omega in range(j, self.sub_iter_len):
Expand Down
19 changes: 17 additions & 2 deletions FOX/io/hdf5_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

"""

import subprocess
from os import remove
from time import sleep
from typing import Dict, Iterable, Optional, Union, Hashable, List, Tuple
Expand Down Expand Up @@ -300,6 +301,17 @@ def _get_kwarg_dict(armc: 'FOX.ARMC') -> Settings:
"""################################### Updating .hdf5 files ####################################"""


@assert_error(H5PY_ERROR)
def hdf5_clear_status(filename: str) -> bool:
"""Run the :code:`h5clear filename` command if **filename** refuses to open."""
try:
with h5py.File(filename, 'r+', libver='latest'):
return True
except OSError:
subprocess.run(['h5clear', '-s', 'repr(filename)'])
return False


@assert_error(H5PY_ERROR)
def hdf5_availability(filename: str, timeout: float = 5.0,
max_attempts: Optional[int] = 10) -> None:
Expand Down Expand Up @@ -329,12 +341,12 @@ def hdf5_availability(filename: str, timeout: float = 5.0,
Raised if **max_attempts** is exceded.

"""
warning = "OSWarning: '{}' is currently unavailable; repeating attempt in {:.0f} seconds"
warning = "WARNING: '{}' is currently unavailable; repeating attempt in {:.0f} seconds"
i = max_attempts or np.inf

while i:
try:
with h5py.File(filename, 'r+', libver='latest') as _:
with h5py.File(filename, 'r+', libver='latest'):
return # the .hdf5 file can safely be opened
except OSError as ex: # the .hdf5 file cannot be safely opened yet
print((warning).format(filename, timeout))
Expand Down Expand Up @@ -405,6 +417,9 @@ def _xyz_to_hdf5(filename: str, omega: int,
All to-be exported :class:`MultiMolecule` instance(s) or float (*e.g.* ``np.nan``).

"""
# Check if the hdf5 file is already opened. If opened: wait for 5 sec and try again.
hdf5_availability(filename)

with h5py.File(filename, 'r+', libver='latest') as f:
if not isinstance(mol_list, abc.Iterable): # Check if mol_list is a scalar (np.nan)
i = 0
Expand Down