Skip to content

Commit

Permalink
Merge pull request #50 from calpolyccg/fix-ci
Browse files Browse the repository at this point in the history
Fix CI pipeline errors and separately test osx-arm64 and osx-x86-64
  • Loading branch information
ALescoulie authored Jun 22, 2024
2 parents eb423d8 + 73e10a1 commit c491f2b
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 139 deletions.
24 changes: 12 additions & 12 deletions .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macOS-latest, ubuntu-latest]
python-version: ["3.8", "3.9"]
os: [macOS-latest, ubuntu-latest, macOS-13]
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

# Cache our conda packages.
# More info: https://github.com/conda-incubator/setup-miniconda#caching-packages
- name: Cache conda environment
uses: actions/cache@v2
uses: actions/cache@v3
env:
# Increase this value to reset cache if environment.yml has not changed
CACHE_NUMBER: 0
Expand All @@ -41,15 +41,15 @@ jobs:

# More info on options: https://github.com/conda-incubator/setup-miniconda
- name: Set up Anaconda environment
uses: conda-incubator/setup-miniconda@v2
uses: conda-incubator/setup-miniconda@v3
with:
python-version: ${{ matrix.python-version }}
environment-file: environment.yml
channels: psi4,conda-forge,defaults
channels: conda-forge,defaults
activate-environment: mdsapt
auto-update-conda: false
auto-activate-base: false
use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly!
#use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly!

# TODO: make pyright happier someday in the future
# - name: Type-check
Expand Down Expand Up @@ -83,8 +83,8 @@ jobs:
strategy:
fail-fast: true
matrix:
os: [macOS-latest, ubuntu-latest]
python-version: [3.7, 3.8, 3.9]
os: [macOS-13, ubuntu-latest]
python-version: [3.9, 3.10, 3.11, 3.12]
include:
- os: macOS-latest
output-folder: osx-64
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
activate-environment: mdsapt-build
auto-update-conda: false
auto-activate-base: false
use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly!
#use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly!

- name: Build MDSAPT conda package
# conda requires this special shell
Expand All @@ -139,8 +139,8 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macOS-latest, ubuntu-latest]
python-version: [3.7, 3.8, 3.9]
os: [macOS-latest, macOS-13, ubuntu-latest]
python-version: [3.9, 3.10, 3.11, 3.12]

steps:
- uses: actions/checkout@v2
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ MD-SAPT
SAPT Calculations for MDAnalysis

[//]: # (Badges)
[![GitHub Actions Build Status](https://github.com/alescoulie/MDSAPT/workflows/CI/badge.svg)](https://github.com/alescolie/MDSAPT/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/alescoulie/MDSAPT/branch/master/graph/badge.svg)](https://codecov.io/gh/alescoulie/MDSAPT/branch/master)
[![GitHub Actions Build Status](https://github.com/calpolyccg/MDSAPT/workflows/CI/badge.svg)](https://github.com/alescolie/MDSAPT/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/calpolyccg/MDSAPT/branch/master/graph/badge.svg)](https://codecov.io/gh/alescoulie/MDSAPT/branch/master)
[![Documentation Status](https://readthedocs.org/projects/mdsapt/badge/?version=latest)](https://mdsapt.readthedocs.io/en/latest/?badge=latest)
[![Launch binder demo](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/calpolyccg/MDSAPT_demo/master?labpath=MD-SAPT_demo.ipynb)

Expand Down
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@

devEnv = pkgs.mkShell {
propagatedBuildInputs = [ poetryEnv];
buildInputs = with pkgs; [pkgs.qchem.psi4 pkgs.qchem.openmm pkgs.qchem.pdbfixer ];
buildInputs = with pkgs; [pkgs.qchem.psi4 pkgs.qchem.openmm pkgs.qchem.pdbfixer pkgs.act ];
};

# DON'T FORGET TO PUT YOUR PACKAGE NAME HERE, REMOVING `throw`
Expand Down
2 changes: 1 addition & 1 deletion mdsapt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# pylint: skip-file
"""An MDA-kit for calcuating quantum interactions in psi4."""
from . import _version
import logging

from . import log
Expand Down Expand Up @@ -34,5 +35,4 @@ def log_banner() -> None:
logger = create_logger()
log_banner()

from . import _version
__version__ = _version.get_versions()['version']
6 changes: 4 additions & 2 deletions mdsapt/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# This file helps to compute a version number in source trees obtained from
# git-archive tarball (such as those provided by githubs download-from-tag
# feature). Distribution tarballs (built by setup.py sdist) and build
Expand All @@ -19,6 +18,9 @@
from typing import Any, Callable, Dict, List, Optional, Tuple
import functools

# pylint: disable=consider-using-f-string
# pylint: disable=invalid-name


def get_keywords() -> Dict[str, str]:
"""Get the keywords needed to look up the version information."""
Expand Down Expand Up @@ -162,7 +164,7 @@ def git_get_keywords(versionfile_abs: str) -> Dict[str, str]:
# _version.py.
keywords: Dict[str, str] = {}
try:
with open(versionfile_abs, "r") as fobj:
with open(versionfile_abs, "r") as fobj: # pylint: disable=unspecified-encoding
for line in fobj:
if line.strip().startswith("git_refnames ="):
mo = re.search(r'=\s*"(.*)"', line)
Expand Down
14 changes: 9 additions & 5 deletions mdsapt/cli.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# pylint: disable=missing-module-docstring
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.

Expand All @@ -16,11 +16,13 @@

@click.group()
def cli():
# pylint: disable=line-too-long
"""
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.
"""
# pylint: disable=line-too-long


@cli.command()
Expand All @@ -43,17 +45,19 @@ def generate(filename: str, template: str, force: bool):
"""
Generate a template input file at filename.
"""
# pylint: disable=fixme
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:
with open(template_path, 'r', encoding='utf-8') as template:
template_data = template.read()
with open(filename, 'w') as new_file:
with open(filename, 'w', encoding='utf-8') as new_file:
new_file.write(template_data)

logger.info(f'Generated template input file {filename}')
logger.info('Generated template input file %s', filename)
# pylint: enable=fixme


@cli.command()
Expand All @@ -75,7 +79,7 @@ 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
import mdsapt # pylint: disable=import-outside-toplevel

ensure_safe_to_overwrite(out_file, force)

Expand Down
58 changes: 47 additions & 11 deletions mdsapt/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,17 @@ class Psi4Config(BaseModel):
Attributes:
method:
The SAPT method to use.
NOTE: You can use any valid Psi4 method, but it might fail if you don't use a SAPT method.
NOTE: You can use any valid Psi4 method, but it might fail
if you don't use a SAPT method.
basis:
The basis to use.
NOTE: We do not verify if this is a valid basis set or not.
save_output:
Whether to save the raw output of Psi4. May be useful for debugging.
settings:
Other Psi4 settings you would like to provide. These will be passed into
`psi4.set_options <https://psicode.org/psi4manual/master/api/psi4.driver.set_options.html>`_.
`psi4.set_options
<https://psicode.org/psi4manual/master/api/psi4.driver.set_options.html>`_.
"""

method: str
Expand Down Expand Up @@ -97,10 +99,12 @@ class TopologySelection(BaseModel):
Attributes:
path: Where the topology file is located.
topology_format: If specified, overrides the format to import with.
charge_overrides: An optional dictionary, where keys are atom numbers and values are their charges.
charge_overrides: An optional dictionary, where keys are atom numbers and
values are their charges.
.. seealso::
`List of topology formats that MDAnalysis supports <https://docs.mdanalysis.org/1.1.1/documentation_pages/topology/init.html>`_
`List of topology formats that MDAnalysis supports
<https://docs.mdanalysis.org/1.1.1/documentation_pages/topology/init.html>`_
"""

path: Path
Expand Down Expand Up @@ -164,16 +168,25 @@ class TrajectoryAnalysisConfig(BaseModel):
type: Literal['trajectory']
topology: TopologySelection
trajectories: List[FilePath]
pairs: List[Tuple[Annotated[int, Field(strict=True, ge=0)], Annotated[int, Field(strict=True, ge=0)]
]]
pairs: List[
Tuple[
Annotated[
int,
Field(strict=True, ge=0)],
Annotated[int, Field(strict=True, ge=0)]
]
]
frames: RangeFrameSelection
output: str

def create_universe(self, **universe_kwargs) -> mda.Universe:
"""
Loads a universe from the given topology and trajectory
"""
return self.topology.create_universe([str(p) for p in self.trajectories], **universe_kwargs)
return self.topology.create_universe(
[str(p) for p in self.trajectories],
**universe_kwargs
)

def get_selections(self) -> Set[int]:
"""
Expand Down Expand Up @@ -209,6 +222,10 @@ def get_invalid_residue_selections(residues: Iterable[int], unv: mda.Universe) -


def get_individual_topologies(sel: TopologyGroupSelection) -> List[TopologySelection]:
"""
Gets a list of :class:`mdsapt.config.TopolgoySelections` from a
:class:`mdsapt.config.TopologyGroupSelection`
"""
if isinstance(sel, list):
return sel

Expand Down Expand Up @@ -257,12 +274,27 @@ class DockingAnalysisConfig(BaseModel):

@model_validator(mode='after')
def ensure_presence_of_args(self) -> 'DockingAnalysisConfig':
provided_args = (self.combined_topologies is not None, self.protein is not None, self.ligands is not None)
"""
Checks that arguments are correct
"""
provided_args = (
self.combined_topologies is not None,
self.protein is not None,
self.ligands is not None
)

if provided_args not in [(True, False, False), (False, True, True)]:
raise ValueError('Must provide `protein` and `ligands` keys, or only `combined_topologies`')
raise ValueError(
'Must provide `protein` and `ligands` keys, or only `combined_topologies`'
)

return self

def build_ensemble(self) -> Ensemble:
"""
Creates an Ensemble containing the set of topologies used to analyze docking.
"""
return self._build_ensemble(combined_topologies=self.combined_topologies,
protein=self.protein,
ligands=self.ligands)
Expand All @@ -275,7 +307,9 @@ def _build_ensemble(
protein: Optional[TopologySelection],
ligands: Optional[TopologyGroupSelection],
) -> Ensemble:
"""Fails if the wrong types of arguments are provided."""
"""
Fails if the wrong types of arguments are provided.
"""
if combined_topologies is not None and (protein, ligands) == (None, None):
return Ensemble.build_from_files(
[top.path for top in get_individual_topologies(combined_topologies)]
Expand All @@ -289,7 +323,9 @@ def _build_ensemble(
ens = ens.merge(protein_mol)
return ens

raise ValueError('Must provide `protein` and `ligands` keys, or only `combined_topologies`')
raise ValueError(
'Must provide `protein` and `ligands` keys, or only `combined_topologies`'
)

def get_selections(self) -> Set[int]:
"""
Expand Down
5 changes: 4 additions & 1 deletion mdsapt/repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ def get_spin_multiplicity(molecule: Chem.Mol) -> int:


def is_amino(unv: mda.Universe, resid: int) -> bool:
"""
Checks resnames aganst list of anmino acids, returns boolean if its in the list.
"""
std_resids: Set[str] = {
'ALA',
'ARG',
Expand All @@ -80,7 +83,7 @@ def is_amino(unv: mda.Universe, resid: int) -> bool:
'VAL'
}

resname_atr = unv._topology.resnames
resname_atr = unv._topology.resnames # pylint: disable=protected-access
return resname_atr.values[resid - 1] in std_resids


Expand Down
6 changes: 5 additions & 1 deletion mdsapt/sapt.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ class DockingSAPT:
'SAPT DISP ENERGY'
]

_res_dict: Dict[str, List[float]]
_key_names: Dict[str, str]
results: pd.DataFrame

def __init__(self, config: Config) -> None:
"""
Sets up ligand topology systems.
Expand Down Expand Up @@ -247,7 +251,7 @@ def _single_system(self) -> None:

coords = xyz_dict[pair[0]] + '\n--\n' + xyz_dict[pair[1]] + '\nunits angstrom'

logger.info(f'Starting SAPT for {pair}')
logger.info(f'Starting SAPT for {pair}') # pylint: disable=logging-fstring-interpolation

if self._cfg.psi4.save_output:
outfile = f'sapt_{self._key_names[self._key]}_{self._pair_names[pair]}.out'
Expand Down
1 change: 0 additions & 1 deletion mdsapt/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from tempfile import mktemp
from typing import Dict, Any

import pydantic
import pytest

from pydantic import ValidationError
Expand Down
6 changes: 3 additions & 3 deletions mdsapt/tests/test_sapt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
"""
import os

import MDAnalysis
from MDAnalysis.topology.guessers import guess_types

from ..config import Config, load_from_yaml_file
from ..config import load_from_yaml_file
from ..sapt import TrajectorySAPT, DockingSAPT

traj_settings = load_from_yaml_file(
os.path.join(os.getcwd(), 'mdsapt', 'tests', 'testing_resources', 'test_input.yaml'))

dock_settings = load_from_yaml_file(
os.path.join(os.getcwd(), 'mdsapt', 'tests', 'testing_resources', 'docking_in.yaml'))
os.path.join(os.getcwd(), 'mdsapt', 'tests', 'testing_resources', 'docking_in.yaml'))

unv = traj_settings.analysis.create_universe()
elements = guess_types(unv.atoms.names)
unv.add_TopologyAttr('elements', elements)


class TestSAPT:
"""
Test object for SAPT analysis
Expand Down
Loading

0 comments on commit c491f2b

Please sign in to comment.