Skip to content

Commit

Permalink
feat: run pdb2pqr in python (no CLI)
Browse files Browse the repository at this point in the history
  • Loading branch information
kiyoon committed Nov 30, 2024
1 parent be4e943 commit 1c4ff11
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 17 deletions.
1 change: 1 addition & 0 deletions pdb2pqr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from ._version import __version__
from .main import main as pdb2pqr_main
from .main import run_pdb2pqr

_LOGGER = logging.getLogger(__name__)
logging.captureWarnings(capture=True)
Expand Down
26 changes: 23 additions & 3 deletions pdb2pqr/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@
.. codeauthor:: Nathan Baker (et al.)
"""

from __future__ import annotations

import argparse
import logging
import sys
from collections import OrderedDict
from collections.abc import Sequence
from io import StringIO
from os import PathLike
from pathlib import Path

import propka.input as pk_in
Expand Down Expand Up @@ -224,7 +228,7 @@ def build_main_parser():
"calculation method."
),
)
pars = propka.lib.build_parser(pars)
pars: argparse.ArgumentParser = propka.lib.build_parser(pars)

# Override version flag set by PROPKA
pars.add_argument(
Expand Down Expand Up @@ -755,15 +759,14 @@ def non_trivial(args, biomolecule, ligand, definition, is_cif):
}


def main_driver(args):
def main_driver(args: argparse.Namespace):
"""Main driver for running program from the command line.
Validate inputs, launch PDB2PQR, handle output.
:param args: command-line arguments
:type args: argparse.Namespace
"""
io.setup_logger(args.output_pqr, args.log_level)
_LOGGER.debug(f"Invoked with arguments: {args}")
print_splash_screen(args)
_LOGGER.info("Checking and transforming input arguments.")
Expand Down Expand Up @@ -836,10 +839,27 @@ def main():
"""Hook for command-line usage."""
parser = build_main_parser()
args = parser.parse_args()
io.setup_logger(args.output_pqr, args.log_level)
if main_driver(args) == 1:
sys.exit(1)


def run_pdb2pqr(args: Sequence[str | PathLike]):
"""Run PDB2PQR with a list of arguments.
Logger is not set up so that it can be called multiple times.
:param args: list of command-line arguments
:type args: list
:return: results of PDB2PQR run
:rtype: tuple
"""
args_strlist = [str(arg) for arg in args]
parser = build_main_parser()
args_parsed = parser.parse_args(args_strlist)
return main_driver(args_parsed)


def dx_to_cube():
"""Convert DX file format to Cube file format.
Expand Down
2 changes: 1 addition & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def compare_pqr(pqr1_path, pqr2_path, compare_resnames=False):
_LOGGER.info(result)


def run_pdb2pqr(
def run_pdb2pqr_for_tests(
args,
input_pdb,
tmp_path,
Expand Down
14 changes: 7 additions & 7 deletions tests/core_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def test_short_pdb(input_pdb, tmp_path):
"""Non-regression tests on short list of PDB-format biomolecules."""
args = "--log-level=INFO --ff=AMBER --drop-water --apbs-input=apbs.in"
output_pqr = Path(input_pdb).stem + ".pqr"
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand All @@ -78,7 +78,7 @@ def test_basic_cif(input_pdb, tmp_path):
"""Non-regression tests on short list of CIF-format biomolecules."""
args = "--log-level=INFO --ff=AMBER --drop-water --apbs-input=apbs.in"
output_pqr = Path(input_pdb).stem + ".cif"
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand All @@ -92,7 +92,7 @@ def test_long_pdb(input_pdb, tmp_path):
"""Non-regression tests on short list of PDB-format biomolecules."""
args = "--log-level=INFO --ff=AMBER --drop-water --apbs-input=apbs.in"
output_pqr = Path(input_pdb).stem + ".pqr"
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand All @@ -106,7 +106,7 @@ def test_broken_backbone(input_pdb, tmp_path):
"""Test graceful failure of optimization with missing backbone atoms."""
args = "--log-level=INFO --ff=AMBER --drop-water"
output_pqr = Path(input_pdb).stem + ".pqr"
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand All @@ -122,7 +122,7 @@ def test_protonated_terminals(input_pdb, expected_pqr, tmp_path):
"""Tests for terminal residue protonation."""
args = "--log-level=INFO --ff=AMBER --ffout AMBER"
output_pqr = Path(input_pdb).stem + ".pqr"
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=common.DATA_DIR / input_pdb,
output_pqr=output_pqr,
Expand All @@ -146,7 +146,7 @@ def test_cyclic_peptide(input_pdb, expected_pqr, tmp_path):
"""Tests for cyclic peptide protonation."""
args = "--log-level=INFO --ff=AMBER --ffout AMBER"
output_pqr = Path(input_pdb).stem + ".pqr"
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=common.DATA_DIR / input_pdb,
output_pqr=output_pqr,
Expand All @@ -170,7 +170,7 @@ def test_ph_naming(naming_test, tmp_path):
f"--drop-water --whitespace --with-ph={naming_test['pH']} "
f"--titration-state-method=propka"
)
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=common.DATA_DIR / input_pdb,
output_pqr=output_pqr,
Expand Down
2 changes: 1 addition & 1 deletion tests/ligand_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def test_ligand_biomolecule(input_pdb, tmp_path):
args = f"--log-level=INFO --ff=AMBER --drop-water --ligand={ligand}"
output_pqr = Path(input_pdb).stem + ".pqr"
_LOGGER.debug(f"Running test in {tmp_path}")
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand Down
2 changes: 1 addition & 1 deletion tests/logging_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_log_output_in_pqr_location(
args = "--log-level=INFO --ff=AMBER"
input_path = common.DATA_DIR / input_file
output_pqr = output_file
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_path,
output_pqr=output_pqr,
Expand Down
2 changes: 1 addition & 1 deletion tests/propka_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_propka_apo(input_pdb, tmp_path):
"--titration-state-method=propka"
)
output_pqr = Path(input_pdb).stem + ".pqr"
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand Down
6 changes: 3 additions & 3 deletions tests/regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
)
def test_basic(args, input_pdb, output_pqr, expected_pqr, tmp_path):
"""Basic code to run 1AFS."""
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand Down Expand Up @@ -87,7 +87,7 @@ def test_basic(args, input_pdb, output_pqr, expected_pqr, tmp_path):
)
def test_forcefields(args, input_pdb, output_pqr, expected_pqr, tmp_path):
"""Basic code to run 1AFS with --whitespace for different forcefields."""
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand Down Expand Up @@ -153,7 +153,7 @@ def test_forcefields(args, input_pdb, output_pqr, expected_pqr, tmp_path):
)
def test_other_options(args, input_pdb, output_pqr, expected_pqr, tmp_path):
"""Basic code to run 1AFS with --whitespace."""
common.run_pdb2pqr(
common.run_pdb2pqr_for_tests(
args=args,
input_pdb=input_pdb,
output_pqr=output_pqr,
Expand Down

0 comments on commit 1c4ff11

Please sign in to comment.