Skip to content

Commit

Permalink
Merge pull request #38 from calpolyccg/cli
Browse files Browse the repository at this point in the history
Create CLI
  • Loading branch information
ALescoulie authored Oct 15, 2022
2 parents ae47305 + 3e90d13 commit 9b4ab45
Show file tree
Hide file tree
Showing 16 changed files with 250 additions and 139 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# generated files
psi.*.clean
out.csv
/timer.dat
/resid_fixed.pdb
/resid.pdb
Expand Down Expand Up @@ -111,3 +113,7 @@ ENV/
# profraw files from LLVM? Unclear exactly what triggers this
# There are reports this comes from LLVM profiling, but also Xcode 9.
*profraw

# MDSAPT-generated files
timer.dat
input.yaml
1 change: 0 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,3 @@ For the poster we presented at ACS Spring 2022, `click here <./_static/mdsapt_po
optimizer
reader
viewer
scripts
27 changes: 23 additions & 4 deletions docs/install.rst
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
Installation
============

MD-SAPT can be installed by cloning the GitHub repository.
MD-SAPT can be installed from the psi4 Conda repo like so:

.. code-block:: bash
conda install -c psi4/label/dev -c conda-forge mdsapt
Alternatively, it can be installed by cloning the GitHub repository.

.. code-block:: bash
git clone https://github.com/calpolyccg/MDSAPT.git
pip install ./MDSAPT
MD-SAPT can also be installed from conda.
To ensure it's been installed correctly, run `mdsapt` or `python3 -m mdsapt`.

.. code-block:: bash
.. code-block::
Warning: importing 'simtk.openmm' is deprecated. Import 'openmm' instead.
2022-03-30 09:32:50,071 mdsapt INFO MDSAPT 1.2.0 starting
2022-03-30 09:32:50,071 mdsapt INFO Copyright (c) 2021 Alia Lescoulie, Astrid Yu, and Ashley Ringer McDonald
2022-03-30 09:32:50,071 mdsapt INFO Released under GPLv3 License
Usage: python -m mdsapt [OPTIONS] COMMAND [ARGS]...
MDSAPT - Molecular Dynamics Symmetry-Adapted Perturbation Theory
This command-line interface lets you easily do common MDSAPT-related tasks.
conda install -c psi4 MDSAPT
Options:
--help Show this message and exit.
Commands:
generate Generate a template input file at filename.
run Run a SAPT calculation using the configuration in in_file.
93 changes: 78 additions & 15 deletions docs/quick.rst
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
Quickstart Guide
================

MD-SAPT simplifies for the calculation of SAPT interaction energies from MD
trajectories. Running it just requires MD simulation files.
MD-SAPT simplifies the calculation of SAPT interaction energies between selected residue pairs in MD trajectories. Running it just requires MD simulation files.

Basic work flow
===============
Prerequisites
_____________

MD-SAPT can be run as a script or in a notebook. It gives the SAPT energy
between the specified residue pairs.
Ensure that you have the following things set up:

Setup Process
_____________
- You have existing MD trajectory and topology files in any form that `MDAnalysis <https://mdanalysis.readthedocs.io/en/latest/`_ supports
- You have already installed MDSAPT, following the :installation guide:`install`

.. note:
If your `PATH` environment variable is not set up to point to installed Python modules, then invoking `mdsapt` directly, as shown in this guide, may not work. In that case, try running `python3 -m mdsapt` instead.
The following steps describe how to set up the input yaml file
Generating an input file
________________________

1. Use the `mdsapt_get_runinput.py` script to generate a blank input file
The following steps describe how to set up the input YAML file.

1. Run `mdsapt generate [filename]` to generate a blank Trajectory SAPT input file at the given filename. Don't worry, it will not overwrite any files unless you explicitly provide the `-f` flag.

2. Specify the MD file locations in the input file

Expand All @@ -25,21 +29,80 @@ The following steps describe how to set up the input yaml file

5. Specify trajectory, optimization, and SAPT settings

Here is an example of a filled-out YAML file:

.. code-block:: yaml
topology_path: 'testtop.psf'
trajectory_paths:
- 'testtraj.dcd'
selection_resid_num:
- 11
- 199
int_pairs:
# Place pair of selections defined above in a list of lists
- [11, 199]
trajectory_settings:
start: 0
stop: 98
step: 1
system_settings:
ncpus: '12'
memory: '12GB'
time: '24:00:00'
opt_settings:
pH: 7
sapt_settings:
method: 'sapt0'
basis: 'jun-cc-pvdz'
settings:
reference: 'rhf'
save_psi4_output: true
Running SAPT
____________

With the input done MD-SAPT is ready to be run. The settings are read using :class:`mdsapt.reader.InputReader` which is then passed into :class:`mdsapt.reader.Optimizer` which handles preparing residues. Finally :class:`mdsapt.reader.TrajectorySAPT` is used to run SAPT over the MD data. The results are stored in a :class:`Pandas.DataFrame`.
Using the `mdsapt` CLI
^^^^^^^^^^^^^^^^^^^^^^

This mode is suited for:

- running on an HPC cluster
- running a simple input file

With the input done MD-SAPT is ready to be run. Simply execute

.. code-block:: bash
mdsapt run [filename] [output]
and it will run SAPT on your trajectory using the parameters specified in your input file.

Using the `mdsapt` Python library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This mode is suited for:

- using MD-SAPT in a notebook
- using MD-SAPT in your own library or applications

The classes involved are as follows:

- The settings are read using :class:`mdsapt.reader.InputReader`
- The `InputReader` is then passed into :class:`mdsapt.reader.Optimizer` which handles preparing residues.
- Finally, :class:`mdsapt.reader.TrajectorySAPT` is used to run SAPT over the MD data.
- The results are stored in a :class:`Pandas.DataFrame` which can be accessed under the `TrajectorySAPT.results` property.

Here is some code demonstrating it:

.. code-block:: Python
import mdsapt
Settings = mdsapt.InputReader('runinput.yaml')
Settings = mdsapt.InputReader('runinput.yaml')
Opt = mdsapt.Optimizer(Settings)
SAPT_run = mdsapt.TrajectorySAPT(Settings, Opt)
SAPT_run.run(Settings.start, Settings.stop, Settings.step)
SAPT_run.results.to_csv('results.csv')
See also `the Binder demo <https://mybinder.org/v2/gh/calpolyccg/MDSAPT_demo/master?labpath=MD-SAPT_demo.ipynb>`_ for a bigger example.

SAPT_run.results.to_csv('results.csv')
23 changes: 0 additions & 23 deletions docs/scripts.rst

This file was deleted.

1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies:
- psi4>=1.6.1,<1.7

- mdanalysis>=2.2.0,<2.3
- click
- numpy
- openmm
- pandas
Expand Down
2 changes: 2 additions & 0 deletions mdsapt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from .config import Config, load_from_yaml_file
from .sapt import TrajectorySAPT, DockingSAPT

from .cli import cli

# Handle versioneer
from ._version import get_versions
versions = get_versions()
Expand Down
12 changes: 12 additions & 0 deletions mdsapt/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env python3
"""
Main entrypoint for the CLI.
"""

# Note that we import directly from the CLI instead of the full package. This is an optimization
# since some CLI tasks do not need the entire package.
from .cli import cli


if __name__ == '__main__':
cli()
109 changes: 109 additions & 0 deletions mdsapt/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import logging
import os
import sys

import click
from mdsapt.config import RangeFrameSelection

# Note that we do not import MDSAPT. This is a speed optimization; it is imported later.


logger = logging.getLogger(__name__)

_dir_path = os.path.dirname(os.path.realpath(__file__))
"""Location of the mdsapt package to be used in resolving templates."""


@click.group()
def cli():
"""
MDSAPT - Molecular Dynamics Symmetry-Adapted Perturbation Theory, by Alia Lescoulie, Astrid Yu, and Ashley Ringer McDonald.
This command-line interface lets you easily do common MDSAPT-related tasks.
"""


@cli.command()
@click.argument(
'filename',
default='input.yaml',
)
@click.option(
'-t', '--template', 'template',
help="Template to generate from. By default, trajectory.",
type=click.Choice(['trajectory', 'docking'], case_sensitive=False),
default='trajectory',
)
@click.option(
'-f', '--force',
help="If provided, overwrites existing files.",
is_flag=True,
)
def generate(filename: str, template: str, force: bool):
"""
Generate a template input file at filename.
"""
ensure_safe_to_overwrite(filename, force)

# TODO: make a wizard for these templates
template_path = os.path.join(_dir_path, 'data', f'{template}_template.yaml')

with open(template_path, 'r') as template:
template_data = template.read()
with open(filename, 'w') as new_file:
new_file.write(template_data)

logger.info(f'Generated template input file {filename}')


@cli.command()
@click.argument(
'in_file',
default='input.yaml',
)
@click.argument(
'out_file',
default='out.csv',
)
@click.option(
'-f', '--force',
help="If provided, overwrites existing files.",
is_flag=True,
)
def run(in_file: str, out_file: str, force: bool):
"""
Run a SAPT calculation using the configuration in in_file. Outputs will be written to
out_file.
"""
import mdsapt

ensure_safe_to_overwrite(out_file, force)

config = mdsapt.load_from_yaml_file(in_file)
if isinstance(config.analysis, mdsapt.config.TrajectoryAnalysisConfig):
sapt = mdsapt.TrajectorySAPT(config)
frames = config.analysis.frames
sapt.run(frames.start, frames.stop, frames.step)
elif isinstance(config.analysis, mdsapt.config.DockingAnalysisConfig):
sapt = mdsapt.DockingSAPT(config)
sapt.run()

logger.info('saving results to CSV')
sapt.results.to_csv(out_file)


def ensure_safe_to_overwrite(path: str, force: bool):
"""
Helper function to ensure that it's safe to overwrite the given file, and
halts the program if not.
"""
if not os.path.exists(path):
return

if force:
logger.warning("will overwrite existing CSV %s", path)
return

logger.error("Halting, file already exists: %s", path)
logger.error("If you want to overwrite that file, add the -f flag")
sys.exit(-1)
Loading

0 comments on commit 9b4ab45

Please sign in to comment.