diff --git a/wfl/cli/cli_options.py b/wfl/cli/cli_options.py index fd0bc65b..1df7c414 100644 --- a/wfl/cli/cli_options.py +++ b/wfl/cli/cli_options.py @@ -1,4 +1,5 @@ import click +import json from wfl.configset import ConfigSet, OutputSpec from ase.io.extxyz import key_val_str_to_dict @@ -38,6 +39,16 @@ def param_fname(f): f = click.option("--param-fname", "-pf", type=click.Path(), help="Path to the potential parameter file")(f) return f +def _parse_kwargs(ctx, param, value): + if value is not None: + return json.loads(value) + else: + return {} + +def kwargs(f): + f = click.option("--kwargs", "-kw", callback=_parse_kwargs, help="JSON text with additional Calculator constructor kwargs")(f) + return f + def prop_prefix(f): f = click.option("--prop-prefix", "-pp", help='Prefix to be pre-pended to all evaluate properties. ' 'Defaults to "gap_"/"ace_"/"mace_" as appropriate')(f) diff --git a/wfl/cli/commands/eval.py b/wfl/cli/commands/eval.py index b4d2c4b3..8d04d778 100644 --- a/wfl/cli/commands/eval.py +++ b/wfl/cli/commands/eval.py @@ -16,9 +16,10 @@ def pyjulip_ace(param_fname): @opt.inputs @opt.outputs @opt.param_fname +@opt.kwargs @opt.prop_prefix @opt.num_inputs_per_python_subprocess -def gap(ctx, inputs, outputs, param_fname, prop_prefix, num_inputs_per_python_subprocess): +def gap(ctx, inputs, outputs, param_fname, kwargs, prop_prefix, num_inputs_per_python_subprocess): """evaluates GAP""" from quippy.potential import Potential @@ -26,7 +27,9 @@ def gap(ctx, inputs, outputs, param_fname, prop_prefix, num_inputs_per_python_su if prop_prefix is None: prop_prefix = "gap_" - calc = (Potential, [], {"param_filename": param_fname}) + kwargs_use = {"param_filename": param_fname} + kwargs_use.update(kwargs) + calc = (Potential, [], kwargs_use) generic.calculate( inputs=inputs, @@ -41,15 +44,16 @@ def gap(ctx, inputs, outputs, param_fname, prop_prefix, num_inputs_per_python_su @opt.inputs @opt.outputs @opt.param_fname +@opt.kwargs @opt.prop_prefix @opt.num_inputs_per_python_subprocess -def ace(ctx, inputs, outputs, param_fname, prop_prefix, num_inputs_per_python_subprocess): +def ace(ctx, inputs, outputs, param_fname, kwargs, prop_prefix, num_inputs_per_python_subprocess): """evaluates ACE""" if prop_prefix is None: prop_prefix = 'ace_' - calc = (pyjulip_ace, [param_fname], {}) + calc = (pyjulip_ace, [param_fname], kwargs) generic.calculate( inputs=inputs, @@ -64,9 +68,10 @@ def ace(ctx, inputs, outputs, param_fname, prop_prefix, num_inputs_per_python_su @opt.inputs @opt.outputs @opt.param_fname +@opt.kwargs @opt.prop_prefix @opt.num_inputs_per_python_subprocess -def mace(ctx, inputs, outputs, param_fname, prop_prefix, num_inputs_per_python_subprocess): +def mace(ctx, inputs, outputs, param_fname, kwargs, prop_prefix, num_inputs_per_python_subprocess): """evaluates MACE""" from mace.calculators import MACECalculator @@ -74,7 +79,9 @@ def mace(ctx, inputs, outputs, param_fname, prop_prefix, num_inputs_per_python_s if prop_prefix is None: prop_prefix = 'mace_' - calc = (MACECalculator, [], {"model_paths": param_fname, "device": "cpu"}) + kwargs_use = {"model_paths": param_fname, "device": "cpu"} + kwargs_use.update(kwargs) + calc = (MACECalculator, [], kwargs_use) generic.calculate( inputs=inputs, diff --git a/wfl/generate/optimize.py b/wfl/generate/optimize.py index 43694326..a3443bdb 100644 --- a/wfl/generate/optimize.py +++ b/wfl/generate/optimize.py @@ -93,7 +93,11 @@ def _run_autopara_wrappable(atoms, calculator, fmax=1.0e-3, smax=None, steps=100 if keep_symmetry: # noinspection PyUnresolvedReferences,PyUnresolvedReferences - from ase.spacegroup.symmetrize import FixSymmetry + try: + from ase.constraints import FixSymmetry + except ImportError: + # fall back to previous import location (pre MR 3288) + from ase.spacegroup.symmetrize import FixSymmetry all_trajs = []