Skip to content
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
6 changes: 5 additions & 1 deletion src/somd2/config/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,11 @@ def as_dict(self, sire_compatible=False):
if value is None and sire_compatible:
d[attr_l] = False

# Don't include lambda_schedule_name or perturbed_system_file in the dictionary,
# since these are just helper attributes.
d.pop("_lambda_schedule_name", None)
d.pop("_perturbed_system_file", None)

# Handle the lambda schedule separately so that we can use simplified
# keyword options.

Expand Down Expand Up @@ -716,7 +721,6 @@ def as_dict(self, sire_compatible=False):
and self._perturbed_system_file is not None
):
d["perturbed_system"] = str(self._perturbed_system_file)
d.pop("perturbed_system_file", None)

return d

Expand Down
77 changes: 43 additions & 34 deletions src/somd2/runner/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1397,7 +1397,6 @@ def _compare_configs(config1, config2):
"frame_frequency",
"save_velocities",
"perturbed_system",
"perturbed_system_file",
"platform",
"max_threads",
"max_gpus",
Expand Down Expand Up @@ -1434,51 +1433,61 @@ def _compare_configs(config1, config2):
# Standard schedules are stored as strings, so we can compare these directly.
if v1 == v2:
continue
else:
try:
v1 = _Config._from_hex(v1)
except Exception as e:
try:
v1 = _Config._from_hex(v1)
except Exception as e:
raise ValueError(
f"Unable to deserialise lambda schedule from config1: {str(e)}"
)
try:
v2 = _Config._from_hex(v2)
except Exception as e:
raise ValueError(
f"Unable to deserialise lambda schedule from config2: {str(e)}"
)
if v1 != v2:
raise ValueError(
f"{key} has changed since the last run. This is not "
"allowed when using the restart option."
)
continue

# Restraints are stored as a list of hexadecimal strings of serialised objects.
# We need to deserialise them before comparison.
elif key == "restraints":
if v1 and v2:
if len(v1) != len(v2):
raise ValueError(
f"Unable to deserialise lambda schedule from config1: {str(e)}"
f"Number of restraints has changed since the last run "
f"({len(v1)} vs {len(v2)}). This is not allowed when "
"using the restart option."
)
# Deserialise all restraints from both configs.
try:
v2 = _Config._from_hex(v2)
deserialized_v1 = [_Config._from_hex(r) for r in v1]
except Exception as e:
raise ValueError(
f"Unable to deserialise lambda schedule from config2: {str(e)}"
f"Unable to deserialise restraint from config1: {str(e)}"
)
if v1 != v2:
try:
deserialized_v2 = [_Config._from_hex(r) for r in v2]
except Exception as e:
raise ValueError(
f"{key} has changed since the last run. This is not "
"allowed when using the restart option."
f"Unable to deserialise restraint from config2: {str(e)}"
)
else:
continue

# Restraints are stored as a list of hexadecimal strings of serialised objects.
# We need to deserialise them before comparison.
elif key == "restraints":
if v1 and v2:
for r1, r2 in zip(v1, v2):
try:
r1 = _Config._from_hex(r1)
except Exception as e:
raise ValueError(
f"Unable to deserialise restraint from config1: {str(e)}"
)
try:
r2 = _Config._from_hex(r2)
except Exception as e:
raise ValueError(
f"Unable to deserialise restraint from config2: {str(e)}"
)
if r1 != r2:
# Match each restraint in v1 against v2, regardless of order.
unmatched = list(deserialized_v2)
for r1 in deserialized_v1:
for i, r2 in enumerate(unmatched):
if r1 == r2:
unmatched.pop(i)
break
else:
raise ValueError(
f"{key} has changed since the last run. This is not "
"allowed when using the restart option."
)
else:
continue
continue

# Convert GeneralUnits to strings for comparison.
if isinstance(v1, _GeneralUnit):
Expand Down
Loading