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

Fix issue #236 #237

Merged
merged 7 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
22 changes: 5 additions & 17 deletions python/BioSimSpace/FreeEnergy/_relative.py
Original file line number Diff line number Diff line change
Expand Up @@ -2060,9 +2060,7 @@ def _initialise_runner(self, system):
extra_lines=self._extra_lines,
property_map=self._property_map,
)
if self._setup_only:
del first_process
else:
if not self._setup_only:
processes.append(first_process)

# Loop over the rest of the lambda values.
Expand Down Expand Up @@ -2139,30 +2137,20 @@ def _initialise_runner(self, system):
f.write(line)

mdp = new_dir + "/gromacs.mdp"
mdp_out = new_dir + "/gromacs.out.mdp"
gro = new_dir + "/gromacs.gro"
top = new_dir + "/gromacs.top"
tpr = new_dir + "/gromacs.tpr"

# Use grompp to generate the portable binary run input file.
command = "%s grompp -f %s -po %s -c %s -p %s -r %s -o %s" % (
_gmx_exe,
first_process._generate_binary_run_file(
mdp,
mdp_out,
gro,
top,
gro,
tpr,
)

# Run the command. If this worked for the first lambda value,
# then it should work for all others.
proc = _subprocess.run(
_Utils.command_split(command),
shell=False,
text=True,
stdout=_subprocess.PIPE,
stderr=_subprocess.PIPE,
first_process._exe,
ignore_warnings=self._ignore_warnings,
show_errors=self._show_errors,
)

# Create a copy of the process and update the working
Expand Down
165 changes: 142 additions & 23 deletions python/BioSimSpace/Process/_gromacs.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,40 +421,129 @@ def _generate_args(self):
if isinstance(self._protocol, (_Protocol.Metadynamics, _Protocol.Steering)):
self.setArg("-plumed", "plumed.dat")

def _generate_binary_run_file(self):
"""Use grommp to generate the binary run input file."""
@staticmethod
def _generate_binary_run_file(
mdp_file,
gro_file,
top_file,
ref_file,
tpr_file,
exe,
checkpoint_file=None,
ignore_warnings=False,
show_errors=True,
):
"""
Use grommp to generate the binary run input file.

Parameters
----------

mdp_file : str
The path to the input mdp file.

gro_file : str
The path to the input coordinate file.

top_file : str
The path to the input topology file.

ref_file : str
The path to the input reference coordinate file to be used for
position restraints.

tpr_file : str
The path to the output binary run file.

exe : str
The path to the GROMACS executable.

checkpoint_file : str
The path to a checkpoint file from a previous run. This can be used
to continue an existing simulation. Currently we only support the
use of checkpoint files for Equilibration protocols.

ignore_warnings : bool
Whether to ignore warnings when generating the binary run file
with 'gmx grompp'. By default, these warnings are elevated to
errors and will halt the program.

show_errors : bool
Whether to show warning/error messages when generating the binary
run file.
"""

if not isinstance(mdp_file, str):
raise ValueError("'mdp_file' must be of type 'str'.")
if not _os.path.isfile(mdp_file):
raise IOError(f"'mdp_file' doesn't exist: '{mdp_file}'")

if not isinstance(gro_file, str):
raise ValueError("'gro_file' must be of type 'str'.")
if not _os.path.isfile(gro_file):
raise IOError(f"'gro_file' doesn't exist: '{gro_file}'")

if not isinstance(top_file, str):
raise ValueError("'top_file' must be of type 'str'.")
if not _os.path.isfile(top_file):
raise IOError(f"'top_file' doesn't exist: '{top_file}'")

if not isinstance(ref_file, str):
raise ValueError("'ref_file' must be of type 'str'.")
if not _os.path.isfile(ref_file):
raise IOError(f"'ref_file' doesn't exist: '{ref_file}'")

if not isinstance(tpr_file, str):
raise ValueError("'tpr_file' must be of type 'str'.")

if not isinstance(exe, str):
raise ValueError("'exe' must be of type 'str'.")
if not _os.path.isfile(exe):
raise IOError(f"'exe' doesn't exist: '{exe}'")

if checkpoint_file is not None:
if not isinstance(checkpoint_file, str):
raise ValueError("'checkpoint_file' must be of type 'str'.")
if not _os.path.isfile(checkpoint_file):
raise IOError(f"'checkpoint_file' doesn't exist: '{checkpoint_file}'")

if not isinstance(ignore_warnings, bool):
raise ValueError("'ignore_warnings' must be of type 'bool'")

if not isinstance(show_errors, bool):
raise ValueError("'show_errors' must be of type 'bool'")

# Create the name of the output mdp file.
mdp_out = (
_os.path.dirname(self._config_file)
+ "/%s.out.mdp" % _os.path.basename(self._config_file).split(".")[0]
_os.path.dirname(mdp_file)
+ "/%s.out.mdp" % _os.path.basename(mdp_file).split(".")[0]
)

# Use grompp to generate the portable binary run input file.
if self._checkpoint_file is not None:
if checkpoint_file is not None:
command = "%s grompp -f %s -po %s -c %s -p %s -r %s -t %s -o %s" % (
self._exe,
self._config_file,
exe,
mdp_file,
mdp_out,
self._gro_file,
self._top_file,
self._gro_file,
self._checkpoint_file,
self._tpr_file,
gro_file,
top_file,
ref_file,
checkpoint_file,
tpr_file,
)
else:
command = "%s grompp -f %s -po %s -c %s -p %s -r %s -o %s" % (
self._exe,
self._config_file,
exe,
mdp_file,
mdp_out,
self._gro_file,
self._top_file,
self._gro_file,
self._tpr_file,
gro_file,
top_file,
ref_file,
tpr_file,
)

# Warnings don't trigger an error.
if self._ignore_warnings:
if ignore_warnings:
command += " --maxwarn 9999"

# Run the command.
Expand All @@ -469,7 +558,7 @@ def _generate_binary_run_file(self):
# Check that grompp ran successfully.
if proc.returncode != 0:
# Handle errors and warnings.
if self._show_errors:
if show_errors:
# Capture errors and warnings from the grompp output.
errors = []
warnings = []
Expand Down Expand Up @@ -531,14 +620,34 @@ def addToConfig(self, config):
super().addToConfig(config)

# Use grompp to generate the portable binary run input file.
self._generate_binary_run_file()
self._generate_binary_run_file(
self._config_file,
self._gro_file,
self._top_file,
self._gro_file,
self._tpr_file,
self._exe,
self._checkpoint_file,
self._ignore_warnings,
self._show_errors,
)

def resetConfig(self):
"""Reset the configuration parameters."""
self._generate_config()

# Use grompp to generate the portable binary run input file.
self._generate_binary_run_file()
self._generate_binary_run_file(
self._config_file,
self._gro_file,
self._top_file,
self._gro_file,
self._tpr_file,
self._exe,
self._checkpoint_file,
self._ignore_warnings,
self._show_errors,
)

def setConfig(self, config):
"""
Expand All @@ -556,7 +665,17 @@ def setConfig(self, config):
super().setConfig(config)

# Use grompp to generate the portable binary run input file.
self._generate_binary_run_file()
self._generate_binary_run_file(
self._config_file,
self._gro_file,
self._top_file,
self._gro_file,
self._tpr_file,
self._exe,
self._checkpoint_file,
self._ignore_warnings,
self._show_errors,
)

def start(self):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,7 @@ def _initialise_runner(self, system):
extra_lines=self._extra_lines,
)

if self._setup_only:
if self._setup_only and not self._engine == "GROMACS":
del first_process
else:
processes.append(first_process)
Expand Down Expand Up @@ -1462,30 +1462,20 @@ def _initialise_runner(self, system):
f.write(line)

mdp = new_dir + "/gromacs.mdp"
mdp_out = new_dir + "/gromacs.out.mdp"
gro = new_dir + "/gromacs.gro"
top = new_dir + "/gromacs.top"
tpr = new_dir + "/gromacs.tpr"

# Use grompp to generate the portable binary run input file.
command = "%s grompp -f %s -po %s -c %s -p %s -r %s -o %s" % (
self._exe,
first_process._generate_binary_run_file(
mdp,
mdp_out,
gro,
top,
gro,
tpr,
)

# Run the command. If this worked for the first lambda value,
# then it should work for all others.
proc = _subprocess.run(
_Utils.command_split(command),
shell=False,
text=True,
stdout=_subprocess.PIPE,
stderr=_subprocess.PIPE,
first_process._exe,
ignore_warnings=self._ignore_warnings,
show_errors=self._show_errors,
)

# Create a copy of the process and update the working
Expand Down
Loading
Loading