Merge pull request #100 from IAlibay/rm-propkainput
Removal of PROPKA input
This commit is contained in:
@@ -12,8 +12,7 @@ protein-ligand complexes based in the 3D structure. The
|
|||||||
|
|
||||||
propka3 [-h] [-f FILENAMES] [-r REFERENCE] [-c CHAINS] [-i TITRATE_ONLY] [-t THERMOPHILES] [-a ALIGNMENT] [-m MUTATIONS]
|
propka3 [-h] [-f FILENAMES] [-r REFERENCE] [-c CHAINS] [-i TITRATE_ONLY] [-t THERMOPHILES] [-a ALIGNMENT] [-m MUTATIONS]
|
||||||
[-v VERSION_LABEL] [-p PARAMETERS] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-o PH] [-w WINDOW WINDOW WINDOW]
|
[-v VERSION_LABEL] [-p PARAMETERS] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-o PH] [-w WINDOW WINDOW WINDOW]
|
||||||
[-g GRID GRID GRID] [--mutator MUTATOR] [--mutator-option MUTATOR_OPTIONS] [-d] [-l] [-k] [-q] [--generate-propka-input]
|
[-g GRID GRID GRID] [--mutator MUTATOR] [--mutator-option MUTATOR_OPTIONS] [-d] [-l] [-k] [-q] [--protonate-all]
|
||||||
[--protonate-all]
|
|
||||||
input_pdb
|
input_pdb
|
||||||
|
|
||||||
|
|
||||||
@@ -120,10 +119,6 @@ protein-ligand complexes based in the 3D structure. The
|
|||||||
|
|
||||||
suppress non-warning messages (default: None)
|
suppress non-warning messages (default: None)
|
||||||
|
|
||||||
.. option:: --generate-propka-input
|
|
||||||
|
|
||||||
Generate a PROPKA input file (default: False)
|
|
||||||
|
|
||||||
.. option:: --protonate-all
|
.. option:: --protonate-all
|
||||||
|
|
||||||
Protonate all atoms (will not influence pKa calculation)
|
Protonate all atoms (will not influence pKa calculation)
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ from . import hybrid36
|
|||||||
|
|
||||||
|
|
||||||
# Format strings that get used in multiple places (or are very complex)
|
# Format strings that get used in multiple places (or are very complex)
|
||||||
PKA_FMT = "{:6.2f}"
|
|
||||||
INPUT_LINE_FMT = (
|
|
||||||
"{type:6s}{r.numb:>5d} {atom_label} {r.res_name}{r.chain_id:>2s}"
|
|
||||||
"{r.res_num:>4d}{r.x:>12.3f}{r.y:>8.3f}{r.z:>8.3f}{group:>6s}{pka:>6s} \n")
|
|
||||||
PDB_LINE_FMT1 = (
|
PDB_LINE_FMT1 = (
|
||||||
"{type:6s}{r.numb:>5d} {atom_label} {r.res_name}{r.chain_id:>2s}"
|
"{type:6s}{r.numb:>5d} {atom_label} {r.res_name}{r.chain_id:>2s}"
|
||||||
"{r.res_num:>4d}{r.x:>12.3f}{r.y:>8.3f}{r.z:>8.3f}{r.occ:>6s}"
|
"{r.res_num:>4d}{r.x:>12.3f}{r.y:>8.3f}{r.z:>8.3f}{r.occ:>6s}"
|
||||||
@@ -33,7 +29,13 @@ STR_FMT = (
|
|||||||
|
|
||||||
|
|
||||||
class Atom:
|
class Atom:
|
||||||
"""Atom class - contains all atom information found in the PDB file"""
|
"""Atom class - contains all atom information found in the PDB file
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
:meth:`make_input_line` and :meth:`get_input_parameters` have been
|
||||||
|
removed as reading/writing PROPKA input is no longer supported.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, line=None):
|
def __init__(self, line=None):
|
||||||
"""Initialize Atom object.
|
"""Initialize Atom object.
|
||||||
@@ -56,9 +58,6 @@ class Atom:
|
|||||||
self.z = None
|
self.z = None
|
||||||
self.group = None
|
self.group = None
|
||||||
self.group_type = None
|
self.group_type = None
|
||||||
self.group_label = None
|
|
||||||
self.group_model_pka = None
|
|
||||||
self.group_model_pka_set = None
|
|
||||||
self.number_of_bonded_elements = {}
|
self.number_of_bonded_elements = {}
|
||||||
self.cysteine_bridge = False
|
self.cysteine_bridge = False
|
||||||
self.bonded_atoms = []
|
self.bonded_atoms = []
|
||||||
@@ -255,31 +254,6 @@ class Atom:
|
|||||||
new_atom.icode = self.icode
|
new_atom.icode = self.icode
|
||||||
return new_atom
|
return new_atom
|
||||||
|
|
||||||
def make_input_line(self):
|
|
||||||
"""PDB line for this atom.
|
|
||||||
|
|
||||||
TODO - Could be @property method/attribute
|
|
||||||
TODO - figure out difference between make_pdb_line, make_input_line,
|
|
||||||
and make_pdb_line2
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
String with PDB-format line.
|
|
||||||
"""
|
|
||||||
group = '-'
|
|
||||||
model_pka = '-'
|
|
||||||
if self.group:
|
|
||||||
group = self.group.type
|
|
||||||
if self.terminal == 'C-':
|
|
||||||
group = 'C-' ## circumventing C-/COO parameter unification
|
|
||||||
|
|
||||||
if self.group.titratable:
|
|
||||||
model_pka = PKA_FMT.format(self.group.model_pka)
|
|
||||||
str_ = INPUT_LINE_FMT.format(
|
|
||||||
type=self.type.upper(), r=self,
|
|
||||||
atom_label=make_tidy_atom_label(self.name, self.element),
|
|
||||||
group=group, pka=model_pka)
|
|
||||||
return str_
|
|
||||||
|
|
||||||
def make_conect_line(self):
|
def make_conect_line(self):
|
||||||
"""PDB line for bonding within this molecule.
|
"""PDB line for bonding within this molecule.
|
||||||
|
|
||||||
@@ -298,45 +272,11 @@ class Atom:
|
|||||||
res += '\n'
|
res += '\n'
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_input_parameters(self):
|
|
||||||
"""Extract the input parameters stored in the occupancy and b-factor
|
|
||||||
fields in input files"""
|
|
||||||
# Set the group type
|
|
||||||
if self.occ != '-':
|
|
||||||
# make sure to set the terminal
|
|
||||||
if self.occ in ['N+', 'C-']:
|
|
||||||
self.terminal = self.occ
|
|
||||||
# save the ligand group charge
|
|
||||||
if self.occ == 'BLG':
|
|
||||||
self.charge = +1
|
|
||||||
elif self.occ == 'ALG':
|
|
||||||
self.charge = -1
|
|
||||||
# generic ions
|
|
||||||
if self.occ in ['1P', '2P', '1N', '2N']:
|
|
||||||
self.res_name = self.occ
|
|
||||||
self.occ = 'Ion'
|
|
||||||
# correct the group type
|
|
||||||
self.occ = self.occ.replace('N+', 'Nterm')
|
|
||||||
self.occ = self.occ.replace('C-', 'Cterm')
|
|
||||||
self.occ = self.occ.replace('ION', 'Ion')
|
|
||||||
self.occ = self.occ.replace('ALG', 'titratable_ligand')
|
|
||||||
self.occ = self.occ.replace('BLG', 'titratable_ligand')
|
|
||||||
self.occ = self.occ.replace('LG', 'non_titratable_ligand')
|
|
||||||
self.group_label = "{0:s}_group".format(self.occ)
|
|
||||||
# set the model pKa value
|
|
||||||
if self.beta != '-':
|
|
||||||
self.group_model_pka = float(self.beta)
|
|
||||||
self.group_model_pka_set = True
|
|
||||||
# set occ and beta to standard values
|
|
||||||
self.occ = '1.00'
|
|
||||||
self.beta = '0.00'
|
|
||||||
|
|
||||||
def make_pdb_line(self):
|
def make_pdb_line(self):
|
||||||
"""Create PDB line.
|
"""Create PDB line.
|
||||||
|
|
||||||
TODO - this could/should be a @property method/attribute
|
TODO - this could/should be a @property method/attribute
|
||||||
TODO - figure out difference between make_pdb_line, make_input_line,
|
TODO - figure out difference between make_pdb_line, and make_pdb_line2
|
||||||
and make_pdb_line2
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
String with PDB line.
|
String with PDB line.
|
||||||
@@ -367,8 +307,7 @@ class Atom:
|
|||||||
"""Create a PDB line.
|
"""Create a PDB line.
|
||||||
|
|
||||||
TODO - this could/should be a @property method/attribute
|
TODO - this could/should be a @property method/attribute
|
||||||
TODO - figure out difference between make_pdb_line, make_input_line,
|
TODO - figure out difference between make_pdb_line, and make_pdb_line2
|
||||||
and make_pdb_line2
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
String with PDB line.
|
String with PDB line.
|
||||||
|
|||||||
@@ -25,7 +25,13 @@ RESIDUE_MULTIPLIER = 1000
|
|||||||
|
|
||||||
|
|
||||||
class ConformationContainer:
|
class ConformationContainer:
|
||||||
"""Container for molecular conformations"""
|
"""Container for molecular conformations
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
Removed :meth:`additional_setup_when_reading_input_files` as reading
|
||||||
|
PROPKA inputs is no longer supported.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, name='', parameters=None, molecular_container=None):
|
def __init__(self, name='', parameters=None, molecular_container=None):
|
||||||
"""Initialize conformation container.
|
"""Initialize conformation container.
|
||||||
@@ -58,19 +64,6 @@ class ConformationContainer:
|
|||||||
if group:
|
if group:
|
||||||
self.setup_and_add_group(group)
|
self.setup_and_add_group(group)
|
||||||
|
|
||||||
def additional_setup_when_reading_input_file(self):
|
|
||||||
"""Generate interaction map and charge centers."""
|
|
||||||
# if a group is coupled and we are reading a .propka_input file, then
|
|
||||||
# some more configuration might be needed
|
|
||||||
map_ = make_interaction_map(
|
|
||||||
'Covalent coupling map for {0:s}'.format(str(self)),
|
|
||||||
self.get_covalently_coupled_groups(),
|
|
||||||
lambda g1, g2: g1 in g2.covalently_coupled_groups)
|
|
||||||
info(map_)
|
|
||||||
# check if we should set a common charge centre as well
|
|
||||||
if self.parameters.common_charge_centre:
|
|
||||||
self.set_common_charge_centres()
|
|
||||||
|
|
||||||
def set_common_charge_centres(self):
|
def set_common_charge_centres(self):
|
||||||
"""Assign charge centers to groups."""
|
"""Assign charge centers to groups."""
|
||||||
for system in self.get_coupled_systems(
|
for system in self.get_coupled_systems(
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Data structures for groups
|
|||||||
==========================
|
==========================
|
||||||
|
|
||||||
Routines and classes for storing groups important to PROPKA calculations.
|
Routines and classes for storing groups important to PROPKA calculations.
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
Removed :func:`initialize_atom_group` as reading PROPKA inputs is no longer
|
||||||
|
supported.
|
||||||
"""
|
"""
|
||||||
import math
|
import math
|
||||||
import propka.ligand
|
import propka.ligand
|
||||||
@@ -40,7 +45,14 @@ EXPECTED_ATOMS_BASE_INTERACTIONS = {
|
|||||||
|
|
||||||
|
|
||||||
class Group:
|
class Group:
|
||||||
"""Class for storing groups important to pKa calculations."""
|
"""Class for storing groups important to pKa calculations.
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
Removed :meth:`make_covalently_coupled_line` and
|
||||||
|
:meth:`make_non_covalently_coupled_line` as writing PROPKA inputs is no
|
||||||
|
longer supported.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, atom):
|
def __init__(self, atom):
|
||||||
"""Initialize with an atom.
|
"""Initialize with an atom.
|
||||||
@@ -178,48 +190,6 @@ class Group:
|
|||||||
self.determinants[type_].append(
|
self.determinants[type_].append(
|
||||||
Determinant(new_determinant.group, new_determinant.value))
|
Determinant(new_determinant.group, new_determinant.value))
|
||||||
|
|
||||||
def make_covalently_coupled_line(self):
|
|
||||||
"""Create line for covalent coupling.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
string
|
|
||||||
"""
|
|
||||||
# first check if there are any coupled groups at all
|
|
||||||
if len(self.covalently_coupled_groups) == 0:
|
|
||||||
return ''
|
|
||||||
line = 'CCOUPL{0:5d}'.format(self.atom.numb)
|
|
||||||
# extract and sort numbers of coupled groups
|
|
||||||
coupled = []
|
|
||||||
for group in self.covalently_coupled_groups:
|
|
||||||
coupled.append(group.atom.numb)
|
|
||||||
coupled.sort()
|
|
||||||
# write 'em out
|
|
||||||
for num in coupled:
|
|
||||||
line += '{0:5d}'.format(num)
|
|
||||||
line += '\n'
|
|
||||||
return line
|
|
||||||
|
|
||||||
def make_non_covalently_coupled_line(self):
|
|
||||||
"""Create line for non-covalent coupling.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
string
|
|
||||||
"""
|
|
||||||
# first check if there are any coupled groups at all
|
|
||||||
if len(self.non_covalently_coupled_groups) == 0:
|
|
||||||
return ''
|
|
||||||
line = 'NCOUPL{0:5d}'.format(self.atom.numb)
|
|
||||||
# extract and sort numbers of coupled groups
|
|
||||||
coupled = []
|
|
||||||
for group in self.non_covalently_coupled_groups:
|
|
||||||
coupled.append(group.atom.numb)
|
|
||||||
coupled.sort()
|
|
||||||
# write 'em out
|
|
||||||
for num in coupled:
|
|
||||||
line += '{0:5d}'.format(num)
|
|
||||||
line += '\n'
|
|
||||||
return line
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""Needed for creating sets of groups."""
|
"""Needed for creating sets of groups."""
|
||||||
if self.atom.type == 'atom':
|
if self.atom.type == 'atom':
|
||||||
@@ -1425,15 +1395,3 @@ def is_ion_group(parameters, atom):
|
|||||||
if atom.res_name.strip() in parameters.ions.keys():
|
if atom.res_name.strip() in parameters.ions.keys():
|
||||||
return IonGroup(atom)
|
return IonGroup(atom)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def initialize_atom_group(atom):
|
|
||||||
"""Initialize an atom group.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
atom: atom to initialize
|
|
||||||
"""
|
|
||||||
# try to initialise the group
|
|
||||||
group_attr = globals()[atom.group_label]
|
|
||||||
atom.group = group_attr(atom)
|
|
||||||
atom.group.model_pka = atom.group_model_pka
|
|
||||||
atom.group.model_pka_set = atom.group_model_pka_set
|
|
||||||
|
|||||||
112
propka/input.py
112
propka/input.py
@@ -3,13 +3,17 @@ Input handling
|
|||||||
==============
|
==============
|
||||||
|
|
||||||
Input routines.
|
Input routines.
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
Methods to read PROPKA input files (:func:`read_propka` and
|
||||||
|
:func:`get_atom_lines_from_input`) have been removed.
|
||||||
"""
|
"""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pkg_resources import resource_filename
|
from pkg_resources import resource_filename
|
||||||
from propka.lib import protein_precheck
|
from propka.lib import protein_precheck
|
||||||
from propka.atom import Atom
|
from propka.atom import Atom
|
||||||
from propka.conformation_container import ConformationContainer
|
from propka.conformation_container import ConformationContainer
|
||||||
from propka.group import initialize_atom_group
|
|
||||||
|
|
||||||
|
|
||||||
def open_file_for_reading(input_file):
|
def open_file_for_reading(input_file):
|
||||||
@@ -67,14 +71,17 @@ def read_molecule_file(filename: str, mol_container, stream=None):
|
|||||||
usually have an associated file name, an appropirate file name should
|
usually have an associated file name, an appropirate file name should
|
||||||
be passed to the ``filename`` argument. In this case, ``filename`` is
|
be passed to the ``filename`` argument. In this case, ``filename`` is
|
||||||
not opened for reading, but instead is used to help recognise the file
|
not opened for reading, but instead is used to help recognise the file
|
||||||
type (based on the extension being either `.pdb` or `.propka_input`)
|
type (based on the extension being `.pdb`) and also uses that given
|
||||||
and also uses that given ``filename`` to assign a name to the input
|
``filename`` to assign a name to the input
|
||||||
:class:`~propka.molecular_container.MolecularContainer` object.
|
:class:`~propka.molecular_container.MolecularContainer` object.
|
||||||
|
|
||||||
>>> read_molecule_file('test.pdb', mol_container,
|
>>> read_molecule_file('test.pdb', mol_container,
|
||||||
stream=string_io_object)
|
stream=string_io_object)
|
||||||
<propka.molecular_container.MolecularContainer at 0x7f6e0c8f2310>
|
<propka.molecular_container.MolecularContainer at 0x7f6e0c8f2310>
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
PROPKA input files (extension: `.propka_input`) are no longer read.
|
||||||
"""
|
"""
|
||||||
input_path = Path(filename)
|
input_path = Path(filename)
|
||||||
mol_container.name = input_path.stem
|
mol_container.name = input_path.stem
|
||||||
@@ -109,17 +116,6 @@ def read_molecule_file(filename: str, mol_container, stream=None):
|
|||||||
mol_container.conformations[name].sort_atoms()
|
mol_container.conformations[name].sort_atoms()
|
||||||
# find coupled groups
|
# find coupled groups
|
||||||
mol_container.find_covalently_coupled_groups()
|
mol_container.find_covalently_coupled_groups()
|
||||||
elif input_file_extension.lower() == '.propka_input':
|
|
||||||
# input is a propka_input file
|
|
||||||
conformations, conformation_names = read_propka(
|
|
||||||
input_file, mol_container.version.parameters, mol_container)
|
|
||||||
mol_container.conformations = conformations
|
|
||||||
mol_container.conformation_names = conformation_names
|
|
||||||
# Extract groups - this merely sets up the groups found in the
|
|
||||||
# input file
|
|
||||||
mol_container.extract_groups()
|
|
||||||
# do some additional set up
|
|
||||||
mol_container.additional_setup_when_reading_input_file()
|
|
||||||
else:
|
else:
|
||||||
str_ = "Unknown input file type {0!s} for file {1!s}".format(
|
str_ = "Unknown input file type {0!s} for file {1!s}".format(
|
||||||
input_file_extension, input_path)
|
input_file_extension, input_path)
|
||||||
@@ -220,94 +216,6 @@ def get_atom_lines_from_pdb(pdb_file, ignore_residues=[], keep_protons=False,
|
|||||||
terminal = None
|
terminal = None
|
||||||
|
|
||||||
|
|
||||||
def read_propka(input_file, parameters, molecule):
|
|
||||||
"""Read PROPKA input file for molecular container.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
input_file: input file
|
|
||||||
parameters: parameters for parsing/setup
|
|
||||||
molecule: molecular container
|
|
||||||
Returns:
|
|
||||||
list with [conformations, names of conformations]
|
|
||||||
"""
|
|
||||||
conformations = {}
|
|
||||||
# read in all atoms in the input file
|
|
||||||
lines = get_atom_lines_from_input(input_file)
|
|
||||||
for (name, atom) in lines:
|
|
||||||
if not name in conformations.keys():
|
|
||||||
conformations[name] = ConformationContainer(
|
|
||||||
name=name, parameters=parameters,
|
|
||||||
molecular_container=molecule)
|
|
||||||
conformations[name].add_atom(atom)
|
|
||||||
# make a sorted list of conformation names
|
|
||||||
names = sorted(conformations.keys(), key=conformation_sorter)
|
|
||||||
return [conformations, names]
|
|
||||||
|
|
||||||
|
|
||||||
def get_atom_lines_from_input(input_file, tags=['ATOM ', 'HETATM']):
|
|
||||||
"""Get atom lines from a PROPKA input file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
input_file: input file
|
|
||||||
tags: tags defining atom lines
|
|
||||||
Yields:
|
|
||||||
conformation container, list of atoms
|
|
||||||
"""
|
|
||||||
lines = open_file_for_reading(input_file).readlines()
|
|
||||||
conformation = ''
|
|
||||||
atoms = {}
|
|
||||||
numbers = []
|
|
||||||
for line in lines:
|
|
||||||
tag = line[0:6]
|
|
||||||
# set the conformation
|
|
||||||
if tag == 'MODEL ':
|
|
||||||
conformation = line[6:].strip()
|
|
||||||
# found an atom - save it
|
|
||||||
if tag in tags:
|
|
||||||
atom = Atom(line=line)
|
|
||||||
atom.get_input_parameters()
|
|
||||||
initialize_atom_group(atom)
|
|
||||||
atom.groups_extracted = 1
|
|
||||||
atom.is_protonated = True
|
|
||||||
atoms[atom.numb] = atom
|
|
||||||
numbers.append(atom.numb)
|
|
||||||
# found bonding information - apply it
|
|
||||||
if tag == 'CONECT' and len(line) > 14:
|
|
||||||
conect_numbers = [line[i:i+5] for i in range(6, len(line)-1, 5)]
|
|
||||||
center_atom = atoms[int(conect_numbers[0])]
|
|
||||||
for num in conect_numbers[1:]:
|
|
||||||
bond_atom = atoms[int(num)]
|
|
||||||
# remember to check for cysteine bridges
|
|
||||||
if center_atom.element == 'S' and bond_atom.element == 'S':
|
|
||||||
center_atom.cysteine_bridge = True
|
|
||||||
bond_atom.cysteine_bridge = True
|
|
||||||
# set up bonding
|
|
||||||
if not bond_atom in center_atom.bonded_atoms:
|
|
||||||
center_atom.bonded_atoms.append(bond_atom)
|
|
||||||
if not center_atom in bond_atom.bonded_atoms:
|
|
||||||
bond_atom.bonded_atoms.append(center_atom)
|
|
||||||
# found info on covalent coupling
|
|
||||||
if tag == 'CCOUPL' and len(line) > 14:
|
|
||||||
conect_numbers = [line[i:i+5] for i in range(6, len(line)-1, 5)]
|
|
||||||
center_atom = atoms[int(conect_numbers[0])]
|
|
||||||
for num in conect_numbers[1:]:
|
|
||||||
cov_atom = atoms[int(num)]
|
|
||||||
center_atom.group.couple_covalently(cov_atom.group)
|
|
||||||
# found info on non-covalent coupling
|
|
||||||
if tag == 'NCOUPL' and len(line) > 14:
|
|
||||||
conect_numbers = [line[i:i+5] for i in range(6, len(line)-1, 5)]
|
|
||||||
center_atom = atoms[int(conect_numbers[0])]
|
|
||||||
for num in conect_numbers[1:]:
|
|
||||||
cov_atom = atoms[int(num)]
|
|
||||||
center_atom.group.couple_non_covalently(cov_atom.group)
|
|
||||||
# this conformation is done - yield the atoms
|
|
||||||
if tag == 'ENDMDL':
|
|
||||||
for num in numbers:
|
|
||||||
yield (conformation, atoms[num])
|
|
||||||
# prepare for next conformation
|
|
||||||
atoms = {}
|
|
||||||
numbers = []
|
|
||||||
|
|
||||||
def read_pdb(pdb_file, parameters, molecule):
|
def read_pdb(pdb_file, parameters, molecule):
|
||||||
"""Parse a PDB file.
|
"""Parse a PDB file.
|
||||||
|
|
||||||
|
|||||||
@@ -195,9 +195,14 @@ def build_parser(parser=None):
|
|||||||
new parser will be created.
|
new parser will be created.
|
||||||
Returns:
|
Returns:
|
||||||
ArgumentParser object.
|
ArgumentParser object.
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
Argument `--generate-propka-input` has been removed as writing PROPKA
|
||||||
|
input files is no longer supported.
|
||||||
"""
|
"""
|
||||||
if parser is not None:
|
if parser is not None:
|
||||||
group = parser.add_argument_group(title="PROPKA invoation options")
|
group = parser.add_argument_group(title="PROPKA invocation options")
|
||||||
else:
|
else:
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description=("PROPKA predicts the pKa values of ionizable "
|
description=("PROPKA predicts the pKa values of ionizable "
|
||||||
@@ -285,9 +290,6 @@ def build_parser(parser=None):
|
|||||||
group.add_argument(
|
group.add_argument(
|
||||||
"-q", "--quiet", action="store_const", const="WARNING",
|
"-q", "--quiet", action="store_const", const="WARNING",
|
||||||
dest="log_level", help="suppress non-warning messages")
|
dest="log_level", help="suppress non-warning messages")
|
||||||
group.add_argument(
|
|
||||||
"--generate-propka-input", action="store_true",
|
|
||||||
help="Generate a PROPKA input file")
|
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--protonate-all", dest="protonate_all", action="store_true",
|
"--protonate-all", dest="protonate_all", action="store_true",
|
||||||
help="Protonate all atoms (will not influence pKa calculation)",
|
help="Protonate all atoms (will not influence pKa calculation)",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Molecular container for storing all contents of PDB files.
|
|||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import propka.version
|
import propka.version
|
||||||
from propka.output import write_propka, write_pka, print_header, print_result
|
from propka.output import write_pka, print_header, print_result
|
||||||
from propka.conformation_container import ConformationContainer
|
from propka.conformation_container import ConformationContainer
|
||||||
from propka.lib import info, warning, make_grid
|
from propka.lib import info, warning, make_grid
|
||||||
|
|
||||||
@@ -22,6 +22,12 @@ class MolecularContainer:
|
|||||||
|
|
||||||
TODO - this class name does not conform to PEP8 but has external use.
|
TODO - this class name does not conform to PEP8 but has external use.
|
||||||
We should deprecate and change eventually.
|
We should deprecate and change eventually.
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
Removed :meth:`write_propka` and
|
||||||
|
:meth:`additional_setup_when_reading_input_file` as reading and writing
|
||||||
|
PROPKA input files is no longer supported.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parameters, options=None):
|
def __init__(self, parameters, options=None):
|
||||||
@@ -72,11 +78,6 @@ class MolecularContainer:
|
|||||||
for name in self.conformation_names:
|
for name in self.conformation_names:
|
||||||
self.conformations[name].extract_groups()
|
self.conformations[name].extract_groups()
|
||||||
|
|
||||||
def additional_setup_when_reading_input_file(self):
|
|
||||||
"""Additional setup."""
|
|
||||||
for name in self.conformation_names:
|
|
||||||
self.conformations[name].additional_setup_when_reading_input_file()
|
|
||||||
|
|
||||||
def calculate_pka(self):
|
def calculate_pka(self):
|
||||||
"""Calculate pKa values."""
|
"""Calculate pKa values."""
|
||||||
# calculate for each conformation
|
# calculate for each conformation
|
||||||
@@ -123,16 +124,6 @@ class MolecularContainer:
|
|||||||
self.conformation_names[0]].chains
|
self.conformation_names[0]].chains
|
||||||
self.conformations['AVR'] = avr_conformation
|
self.conformations['AVR'] = avr_conformation
|
||||||
|
|
||||||
def write_propka(self, filename=None):
|
|
||||||
"""Write PROPKA input file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
filename: file to write to
|
|
||||||
"""
|
|
||||||
if filename is None:
|
|
||||||
filename = os.path.join('{0:s}.propka_input'.format(self.name))
|
|
||||||
write_propka(self, filename)
|
|
||||||
|
|
||||||
def write_pka(self, filename=None, reference="neutral",
|
def write_pka(self, filename=None, reference="neutral",
|
||||||
direction="folding", options=None):
|
direction="folding", options=None):
|
||||||
"""Write pKa information to a file.
|
"""Write pKa information to a file.
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ Output
|
|||||||
======
|
======
|
||||||
|
|
||||||
Output routines.
|
Output routines.
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged::3.4.0
|
||||||
|
Removed :func:`write_proka` as writing PROPKA input files is no longer
|
||||||
|
supported.
|
||||||
"""
|
"""
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from propka.lib import info
|
from propka.lib import info
|
||||||
@@ -589,30 +594,3 @@ def write_mol2_for_atoms(atoms, filename):
|
|||||||
out.write(bonds_section)
|
out.write(bonds_section)
|
||||||
out.write(substructure_section)
|
out.write(substructure_section)
|
||||||
out.close()
|
out.close()
|
||||||
|
|
||||||
def write_propka(molecular_container, filename):
|
|
||||||
"""Write PROPKA input file for molecular container.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
molecular_container: molecular container
|
|
||||||
filename: output file name
|
|
||||||
"""
|
|
||||||
out = open_file_for_writing(filename)
|
|
||||||
for conformation_name in molecular_container.conformation_names:
|
|
||||||
out.write('MODEL {0:s}\n'.format(conformation_name))
|
|
||||||
# write atoms
|
|
||||||
for atom in molecular_container.conformations[conformation_name].atoms:
|
|
||||||
out.write(atom.make_input_line())
|
|
||||||
# write bonds
|
|
||||||
for atom in molecular_container.conformations[conformation_name].atoms:
|
|
||||||
out.write(atom.make_conect_line())
|
|
||||||
# write covalently coupled groups
|
|
||||||
for group in (
|
|
||||||
molecular_container.conformations[conformation_name].groups):
|
|
||||||
out.write(group.make_covalently_coupled_line())
|
|
||||||
# write non-covalently coupled groups
|
|
||||||
for group in (
|
|
||||||
molecular_container.conformations[conformation_name].groups):
|
|
||||||
out.write(group.make_non_covalently_coupled_line())
|
|
||||||
out.write('ENDMDL\n')
|
|
||||||
out.close()
|
|
||||||
|
|||||||
@@ -21,7 +21,12 @@ _LOGGER = logging.getLogger("PROPKA")
|
|||||||
|
|
||||||
|
|
||||||
def main(optargs=None):
|
def main(optargs=None):
|
||||||
"""Read in structure files, calculate pKa values, and print pKa files."""
|
"""Read in structure files, calculate pKa values, and print pKa files.
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
Removed ability to write out PROPKA input files.
|
||||||
|
"""
|
||||||
# loading options, flags and arguments
|
# loading options, flags and arguments
|
||||||
optargs = optargs if optargs is not None else []
|
optargs = optargs if optargs is not None else []
|
||||||
options = loadOptions(*optargs)
|
options = loadOptions(*optargs)
|
||||||
@@ -32,8 +37,6 @@ def main(optargs=None):
|
|||||||
my_molecule = read_molecule_file(pdbfile, my_molecule)
|
my_molecule = read_molecule_file(pdbfile, my_molecule)
|
||||||
my_molecule.calculate_pka()
|
my_molecule.calculate_pka()
|
||||||
my_molecule.write_pka()
|
my_molecule.write_pka()
|
||||||
if options.generate_propka_input:
|
|
||||||
my_molecule.write_propka()
|
|
||||||
|
|
||||||
|
|
||||||
def single(filename: str, optargs: tuple = (), stream=None,
|
def single(filename: str, optargs: tuple = (), stream=None,
|
||||||
@@ -93,6 +96,9 @@ def single(filename: str, optargs: tuple = (), stream=None,
|
|||||||
|
|
||||||
:func:`propka.input.read_molecule_file`
|
:func:`propka.input.read_molecule_file`
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4.0
|
||||||
|
Removed ability to write out PROPKA input files.
|
||||||
"""
|
"""
|
||||||
# Deal with input optarg options
|
# Deal with input optarg options
|
||||||
optargs = tuple(optargs)
|
optargs = tuple(optargs)
|
||||||
@@ -113,8 +119,6 @@ def single(filename: str, optargs: tuple = (), stream=None,
|
|||||||
my_molecule.calculate_pka()
|
my_molecule.calculate_pka()
|
||||||
|
|
||||||
# write outputs
|
# write outputs
|
||||||
if options.generate_propka_input:
|
|
||||||
my_molecule.write_propka()
|
|
||||||
if write_pka:
|
if write_pka:
|
||||||
my_molecule.write_pka()
|
my_molecule.write_pka()
|
||||||
|
|
||||||
|
|||||||
@@ -78,8 +78,6 @@ def run_propka(options, pdb_path, tmp_path):
|
|||||||
molecule = read_molecule_file(str(pdb_path), molecule)
|
molecule = read_molecule_file(str(pdb_path), molecule)
|
||||||
molecule.calculate_pka()
|
molecule.calculate_pka()
|
||||||
molecule.write_pka()
|
molecule.write_pka()
|
||||||
if args.generate_propka_input:
|
|
||||||
molecule.write_propka()
|
|
||||||
finally:
|
finally:
|
||||||
os.chdir(cwd)
|
os.chdir(cwd)
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ def test_single_file(tmpdir, pdb, options):
|
|||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
pkrun.single(filename, options)
|
pkrun.single(filename, options)
|
||||||
compare_output(pdb, Path.cwd(), ref_path)
|
compare_output(pdb, Path.cwd(), ref_path)
|
||||||
|
assert os.path.isfile(f'{pdb}.pka')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pdb, options", [
|
@pytest.mark.parametrize("pdb, options", [
|
||||||
@@ -51,6 +52,7 @@ def test_single_filestream(tmpdir, pdb, options):
|
|||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
pkrun.single(filename, options, stream=filestream)
|
pkrun.single(filename, options, stream=filestream)
|
||||||
compare_output(pdb, Path.cwd(), ref_path)
|
compare_output(pdb, Path.cwd(), ref_path)
|
||||||
|
assert os.path.isfile(f'{pdb}.pka')
|
||||||
|
|
||||||
filestream.close()
|
filestream.close()
|
||||||
|
|
||||||
@@ -69,27 +71,10 @@ def test_single_nopka(tmpdir):
|
|||||||
assert not os.path.isfile(f"{pdb}.pka")
|
assert not os.path.isfile(f"{pdb}.pka")
|
||||||
|
|
||||||
|
|
||||||
def test_single_propka_input(tmpdir):
|
|
||||||
"""Basic test to check that the propka_input file is written when
|
|
||||||
`--generate-propka-input` is passed"""
|
|
||||||
pdb = "1FTJ-Chain-A"
|
|
||||||
options = ('--generate-propka-input',)
|
|
||||||
ref_path, pdb_path = get_paths(pdb)
|
|
||||||
filename = f"{pdb}.pdb"
|
|
||||||
|
|
||||||
with open(pdb_path, 'r') as writer:
|
|
||||||
filestream = StringIO(writer.read())
|
|
||||||
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
pkrun.single(filename, options, stream=filestream)
|
|
||||||
assert os.path.isfile(f"{pdb}.propka_input")
|
|
||||||
|
|
||||||
|
|
||||||
def test_single_extra_files_logwarn(tmpdir, caplog):
|
def test_single_extra_files_logwarn(tmpdir, caplog):
|
||||||
"""Tests that a logging warning is thrown if passing files via optargs"""
|
"""Tests that a logging warning is thrown if passing files via optargs"""
|
||||||
pdb = "1FTJ-Chain-A"
|
pdb = "1FTJ-Chain-A"
|
||||||
options = ('-f foo.pdb bar.pdb', '-f test.pdb test2.pdb',
|
options = ('-f foo.pdb bar.pdb', '-f test.pdb test2.pdb')
|
||||||
'--generate-propka-input')
|
|
||||||
ref_path, pdb_path = get_paths(pdb)
|
ref_path, pdb_path = get_paths(pdb)
|
||||||
filename = str(pdb_path)
|
filename = str(pdb_path)
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ def run_propka_stream(options, input_file, filename):
|
|||||||
molecule = read_molecule_file(filename, molecule, stream=input_file)
|
molecule = read_molecule_file(filename, molecule, stream=input_file)
|
||||||
molecule.calculate_pka()
|
molecule.calculate_pka()
|
||||||
molecule.write_pka()
|
molecule.write_pka()
|
||||||
if args.generate_propka_input:
|
|
||||||
molecule.write_propka()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pdb, options", [
|
@pytest.mark.parametrize("pdb, options", [
|
||||||
|
|||||||
Reference in New Issue
Block a user