Source code for ccu.adsorption.cli

"""CLI utilities for adsorption studies."""

import pathlib
import sys
from typing import Any

from ase import collections
from ase.build.molecule import extra
import click

from ccu.adsorption import adsorbatecomplex
from ccu.adsorption.adsorbates import ALL


@click.group(name=__package__.split(".")[-1])
def main():
    """Adsorption calculation tools."""


_all_adsorbates = list(ALL.keys()) + collections.g2.names + list(extra.keys())






@main.command(
    context_settings={"help_option_names": ["-h", "--help"]},
)
@click.argument(
    "adsorbate",
    type=click.Choice(_all_adsorbates, case_sensitive=False),
    required=True,
    metavar="ADSORBATE",
)
@click.argument(
    "structure",
    required=True,
    type=click.Path(exists=True, path_type=pathlib.Path),
)
@click.argument(
    "destination",
    default=pathlib.Path.cwd(),
    type=click.Path(file_okay=False, path_type=pathlib.Path),
)
@click.option(
    "-s",
    "--separation",
    help=(
        "specify the minimum distance between the surface and any adsorbate "
        "atom"
    ),
    default=1.8,
    type=float,
)
@click.option(
    "-c",
    "--special-centres",
    help=("include atom-centred orientations"),
    flag_value=True,
    is_flag=True,
)
@click.option(
    "-Y",
    "--symmetric",
    help="treat the adsorbate as symmetric",
    flag_value=True,
    is_flag=True,
)
@click.option(
    "-V",
    "--vertical",
    help=("include vertical adsorption configurations"),
    flag_value=True,
    is_flag=True,
)
@click.option(
    "-l",
    "--list",
    help="list all available adsorbates",
    flag_value=True,
    is_flag=True,
    is_eager=True,
    callback=print_adsorbates,
    expose_value=False,
)
def place_adsorbate(
    adsorbate,
    structure,
    destination,
    separation,
    special_centres,
    symmetric,
    vertical,
):
    """Create adsorbate complexes for a given structure and.

    Each complex is written to a ``.traj`` file with identifying metadata
    about the adsorbate identity, orientation, site, and structure.

    ADSORBATE is the name of the adsorbate to place on the surface.

    STRUCTURE is the path to the surface on which the adsorbate will be placed.

    DESTINATION is the directory in which to write the ``.traj`` files. The
    directory is created if it does not exist. Defaults to the current
    working directory.
    """
    complexes = adsorbatecomplex.generate_complexes(
        adsorbate,
        structure,
        destination,
        separation,
        special_centres,
        symmetric,
        vertical,
    )
    print(f"{len(complexes)} complexes created.")