Source code for janus_core.cli.singlepoint

# ruff: noqa: I002, FA100
"""Set up singlepoint commandline interface."""

# Issues with future annotations and typer
# c.f. https://github.com/maxb2/typer-config/issues/295
# from __future__ import annotations

from pathlib import Path
from typing import Annotated, Optional

from typer import Context, Option, Typer
from typer_config import use_config

from janus_core.cli.types import (
    Architecture,
    CalcKwargs,
    Device,
    LogPath,
    ModelPath,
    ReadKwargsAll,
    StructPath,
    Summary,
    WriteKwargs,
)
from janus_core.cli.utils import yaml_converter_callback

app = Typer()


[docs] @app.command() @use_config(yaml_converter_callback) def singlepoint( # numpydoc ignore=PR02 ctx: Context, struct: StructPath, arch: Architecture = "mace_mp", device: Device = "cpu", model_path: ModelPath = None, properties: Annotated[ Optional[list[str]], Option( help=( "Properties to calculate. If not specified, 'energy', 'forces' " "and 'stress' will be returned." ), ), ] = None, out: Annotated[ Optional[Path], Option( help=( "Path to save structure with calculated results. Default is inferred " "from name of structure file." ), ), ] = None, read_kwargs: ReadKwargsAll = None, calc_kwargs: CalcKwargs = None, write_kwargs: WriteKwargs = None, log: LogPath = None, tracker: Annotated[ bool, Option(help="Whether to save carbon emissions of calculation") ] = True, summary: Summary = None, ) -> None: """ Perform single point calculations and save to file. Parameters ---------- ctx : Context Typer (Click) Context. Automatically set. struct : Path Path of structure to simulate. arch : Optional[str] MLIP architecture to use for single point calculations. Default is "mace_mp". device : Optional[str] Device to run model on. Default is "cpu". model_path : Optional[str] Path to MLIP model. Default is `None`. properties : Optional[list[str]] Physical properties to calculate. Default is ("energy", "forces", "stress"). out : Optional[Path] Path to save structure with calculated results. Default is inferred from name of the structure file. read_kwargs : Optional[dict[str, Any]] Keyword arguments to pass to ase.io.read. By default, read_kwargs["index"] is ":". calc_kwargs : Optional[dict[str, Any]] Keyword arguments to pass to the selected calculator. Default is {}. write_kwargs : Optional[dict[str, Any]] Keyword arguments to pass to ase.io.write when saving results. Default is {}. log : Optional[Path] Path to write logs to. Default is inferred from the name of the structure file. tracker : bool Whether to save carbon emissions of calculation in log file and summary. Default is True. summary : Optional[Path] Path to save summary of inputs, start/end time, and carbon emissions. Default is inferred from the name of the structure file. config : Optional[Path] Path to yaml configuration file to define the above options. Default is None. """ from janus_core.calculations.single_point import SinglePoint from janus_core.cli.utils import ( carbon_summary, check_config, end_summary, parse_typer_dicts, save_struct_calc, start_summary, ) # Check options from configuration file are all valid check_config(ctx) [read_kwargs, calc_kwargs, write_kwargs] = parse_typer_dicts( [read_kwargs, calc_kwargs, write_kwargs] ) # Check filename for results not duplicated if "filename" in write_kwargs: raise ValueError("'filename' must be passed through the --out option") if out: write_kwargs["filename"] = out log_kwargs = {"filemode": "w"} if log: log_kwargs["filename"] = log singlepoint_kwargs = { "struct_path": struct, "properties": properties, "write_kwargs": write_kwargs, "write_results": True, "arch": arch, "device": device, "model_path": model_path, "read_kwargs": read_kwargs, "calc_kwargs": calc_kwargs, "attach_logger": True, "log_kwargs": log_kwargs, "track_carbon": tracker, } # Initialise singlepoint structure and calculator s_point = SinglePoint(**singlepoint_kwargs) # Store inputs for yaml summary summary = s_point._build_filename( "singlepoint-summary.yml", filename=summary ).absolute() log = s_point.log_kwargs["filename"] # Store inputs for yaml summary inputs = singlepoint_kwargs.copy() # Add structure, MLIP information, and log to inputs save_struct_calc( inputs=inputs, struct=s_point.struct, struct_path=struct, arch=arch, device=device, model_path=model_path, read_kwargs=read_kwargs, calc_kwargs=calc_kwargs, log=log, ) # Save summary information before singlepoint calculation begins start_summary(command="singlepoint", summary=summary, inputs=inputs) # Run singlepoint calculation s_point.run() # Save carbon summary if tracker: carbon_summary(summary=summary, log=log) # Save time after simulation has finished end_summary(summary)