Output performed with loggers. Adds options --no-print. (#12)

Output performed with loggers.  Adds --quiet and --verbose options.
This commit is contained in:
Toni G
2016-04-29 08:21:35 +02:00
committed by Matvey Adzhigirey
parent ca6224433a
commit 5fbbdd4868
23 changed files with 4987 additions and 217 deletions

18
Tests/pdb/1HPX-warn.pdb Normal file
View File

@@ -0,0 +1,18 @@
ATOM 1 N PRO A 1 12.435 14.677 30.369 1.00 35.93 N
ATOM 2 CA PRO A 1 11.739 15.379 29.269 1.00 34.94 C
ATOM 2 CA PRO A 1 11.739 15.379 29.269 1.00 34.94 C
ATOM 3 C PRO A 1 10.309 14.853 29.143 1.00 32.24 C
ATOM 4 O PRO A 1 10.035 13.743 29.578 1.00 32.11 O
ATOM 5 CB PRO A 1 12.566 15.121 27.988 1.00 34.34 C
ATOM 6 CG PRO A 1 13.973 14.970 28.518 1.00 35.36 C
ATOM 7 CD PRO A 1 13.768 14.261 29.859 1.00 35.14 C
ATOM 8 N GLN A 2 9.436 15.666 28.552 1.00 29.85 N
ATOM 9 CA GLN A 2 8.117 15.184 28.193 1.00 29.27 C
ATOM 10 C GLN A 2 7.939 15.392 26.711 1.00 28.61 C
ATOM 11 O GLN A 2 8.147 16.506 26.246 1.00 31.02 O
ATOM 12 CB GLN A 2 7.108 15.981 28.932 1.00 28.24 C
ATOM 13 CG GLN A 2 5.789 15.599 28.365 1.00 32.41 C
ATOM 14 CD GLN A 2 4.735 16.247 29.153 1.00 37.59 C
ATOM 15 OE1 GLN A 2 4.403 15.796 30.243 1.00 39.05 O
ATOM 16 NE2 GLN A 2 4.210 17.303 28.540 1.00 39.28 N
END

2327
Tests/pdb/3SGB-subset.pdb Normal file

File diff suppressed because it is too large Load Diff

2327
Tests/pdb/3SGB.pdb Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
7.95

View File

@@ -0,0 +1,2 @@
3.51
12.80

57
Tests/results/3SGB.dat Normal file
View File

@@ -0,0 +1,57 @@
3.21
4.29
3.47
3.85
4.22
4.59
3.55
2.61
4.48
5.27
4.26
5.11
4.60
3.63
3.24
8.04
6.15
7.14
99.99
99.99
99.99
99.99
99.99
99.99
99.99
99.99
99.99
99.99
10.27
10.00
10.33
10.82
13.96
13.90
10.28
10.96
12.23
12.62
10.25
10.52
12.31
9.50
10.92
10.35
10.44
10.67
11.74
12.84
11.95
12.36
11.05
12.89
12.19
12.17
12.16
7.38
7.56

View File

@@ -17,6 +17,7 @@ if __name__ == "__main__":
('4DFR', []), ('4DFR', []),
('3SGB', []), ('3SGB', []),
('3SGB-subset', ['--titrate_only', 'E:17,E:18,E:19,E:29,E:44,E:45,E:46,E:118,E:119,E:120,E:139']), ('3SGB-subset', ['--titrate_only', 'E:17,E:18,E:19,E:29,E:44,E:45,E:46,E:118,E:119,E:120,E:139']),
('1HPX-warn', ['--quiet']),
] ]
for pdb, args in pdbs: for pdb, args in pdbs:

View File

@@ -5,6 +5,7 @@ from __future__ import print_function
import pickle,sys,os,math,propka.calculations import pickle,sys,os,math,propka.calculations
import pkg_resources import pkg_resources
from propka.lib import info, warning
class bondmaker: class bondmaker:
def __init__(self): def __init__(self):
@@ -111,14 +112,14 @@ class bondmaker:
""" Finds bonds proteins based on the way atoms """ Finds bonds proteins based on the way atoms
normally bond in proteins""" normally bond in proteins"""
print('++++ Side chains ++++') info('++++ Side chains ++++')
# side chains # side chains
for chain in protein.chains: for chain in protein.chains:
for residue in chain.residues: for residue in chain.residues:
if residue.resName.replace(' ','') not in ['N+','C-']: if residue.resName.replace(' ','') not in ['N+','C-']:
self.find_bonds_for_side_chain(residue.atoms) self.find_bonds_for_side_chain(residue.atoms)
print('++++ Backbones ++++') info('++++ Backbones ++++')
# backbone # backbone
last_residues = [] last_residues = []
for chain in protein.chains: for chain in protein.chains:
@@ -128,12 +129,12 @@ class bondmaker:
self.connect_backbone(chain.residues[i-1], chain.residues[i]) self.connect_backbone(chain.residues[i-1], chain.residues[i])
last_residues.append(chain.residues[i]) last_residues.append(chain.residues[i])
print('++++ terminal oxygen ++++') info('++++ terminal oxygen ++++')
# terminal OXT # terminal OXT
for last_residue in last_residues: for last_residue in last_residues:
self.find_bonds_for_terminal_oxygen(last_residue) self.find_bonds_for_terminal_oxygen(last_residue)
print('++++ cysteines ++++') info('++++ cysteines ++++')
# Cysteines # Cysteines
for chain in protein.chains: for chain in protein.chains:
for i in range(0,len(chain.residues)): for i in range(0,len(chain.residues)):
@@ -349,9 +350,9 @@ class bondmaker:
ylen = ymax-ymin ylen = ymax-ymin
zlen = zmax-zmin zlen = zmax-zmin
#print('x range: [%6.2f;%6.2f] %6.2f'%(xmin,xmax,xlen)) #info('x range: [%6.2f;%6.2f] %6.2f'%(xmin,xmax,xlen))
#print('y range: [%6.2f;%6.2f] %6.2f'%(ymin,ymax,ylen)) #info('y range: [%6.2f;%6.2f] %6.2f'%(ymin,ymax,ylen))
#print('z range: [%6.2f;%6.2f] %6.2f'%(zmin,zmax,zlen)) #info('z range: [%6.2f;%6.2f] %6.2f'%(zmin,zmax,zlen))
# how many boxes do we need in each dimension? # how many boxes do we need in each dimension?
# NOTE: math.ceil() returns an int in python3 and a float in # NOTE: math.ceil() returns an int in python3 and a float in
@@ -361,9 +362,9 @@ class bondmaker:
self.no_box_y = max(1, int(math.ceil(ylen/box_size))) self.no_box_y = max(1, int(math.ceil(ylen/box_size)))
self.no_box_z = max(1, int(math.ceil(zlen/box_size))) self.no_box_z = max(1, int(math.ceil(zlen/box_size)))
#print('No. box x: %6.2f'%self.no_box_x) #info('No. box x: %6.2f'%self.no_box_x)
#print('No. box y: %6.2f'%self.no_box_y) #info('No. box y: %6.2f'%self.no_box_y)
#print('No. box z: %6.2f'%self.no_box_z) #info('No. box z: %6.2f'%self.no_box_z)
# initialize boxes # initialize boxes
self.boxes = {} self.boxes = {}
@@ -400,7 +401,7 @@ class bondmaker:
# No box exists for this coordinate # No box exists for this coordinate
pass pass
#print(atom,'->',key,':',len(self.boxes[key])) #info(atom,'->',key,':',len(self.boxes[key]))
return return
@@ -415,7 +416,7 @@ class bondmaker:
if atom1 == atom2: if atom1 == atom2:
return return
#print('making bond for',atom1,atom2) #info('making bond for',atom1,atom2)
if not atom1 in atom2.bonded_atoms: if not atom1 in atom2.bonded_atoms:
atom2.bonded_atoms.append(atom1) atom2.bonded_atoms.append(atom1)
@@ -465,12 +466,12 @@ if __name__ == '__main__':
import protein, pdb, sys,os import protein, pdb, sys,os
arguments = sys.argv arguments = sys.argv
if len(arguments) != 2: if len(arguments) != 2:
print('Usage: bonds.py <pdb_file>') info('Usage: bonds.py <pdb_file>')
sys.exit(0) sys.exit(0)
filename = arguments[1] filename = arguments[1]
if not os.path.isfile(filename): if not os.path.isfile(filename):
print('Error: Could not find \"%s\"'%filename) info('Error: Could not find \"%s\"' % filename)
sys.exit(1) sys.exit(1)
pdblist = pdb.readPDB(filename) pdblist = pdb.readPDB(filename)

View File

@@ -3,6 +3,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import math, propka.protonate, propka.bonds,copy, sys import math, propka.protonate, propka.bonds,copy, sys
from propka.lib import info, warning
# #
@@ -60,7 +61,7 @@ def setup_bonding_and_protonation_30_style(parameters, molecular_container):
def protonate_30_style(molecular_container): def protonate_30_style(molecular_container):
for name in molecular_container.conformation_names: for name in molecular_container.conformation_names:
print('Now protonating',name) info('Now protonating', name)
# split atom into residues # split atom into residues
curres = -1000000 curres = -1000000
residue = [] residue = []
@@ -96,7 +97,7 @@ def addArgHydrogen(residue):
""" """
Adds Arg hydrogen atoms to residues according to the 'old way'. Adds Arg hydrogen atoms to residues according to the 'old way'.
""" """
#print('Adding arg H',residue) #info('Adding arg H',residue)
for atom in residue: for atom in residue:
if atom.name == "CD": if atom.name == "CD":
CD = atom CD = atom
@@ -159,7 +160,7 @@ def addTrpHydrogen(residue):
CE = atom CE = atom
if CD == None or NE == None or CE == None: if CD == None or NE == None or CE == None:
str = "Did not find all atoms in %s%4d - in %s" % (self.resName, self.resNumb, "addTrpHydrogen()") str = "Did not find all atoms in %s%4d - in %s" % (self.resName, self.resNumb, "addTrpHydrogen()")
print(str) info(str)
sys.exit(0) sys.exit(0)
HE = protonateSP2([CD, NE, CE]) HE = protonateSP2([CD, NE, CE])
@@ -184,7 +185,7 @@ def addAmdHydrogen(residue):
if C == None or O == None or N == None: if C == None or O == None or N == None:
str = "Did not find N, C and/or O in %s%4d - in %s" % (atom.resName, atom.resNumb, "addAmdHydrogen()") str = "Did not find N, C and/or O in %s%4d - in %s" % (atom.resName, atom.resNumb, "addAmdHydrogen()")
print(str) info(str)
sys.exit(0) sys.exit(0)
H1 = protonateDirection([N, O, C]) H1 = protonateDirection([N, O, C])
@@ -387,7 +388,7 @@ def radial_volume_desolvation(parameters, group):
#print('%s %5.2f %5.2f %4d'%(group, group.buried, group.Emass, group.Nmass)) #info('%s %5.2f %5.2f %4d'%(group, group.buried, group.Emass, group.Nmass))
return return
@@ -573,7 +574,7 @@ def hydrogen_bond_interaction(group1, group2, version):
[closest_atom1, distance, closest_atom2] = propka.calculations.get_smallest_distance(atoms1, atoms2) [closest_atom1, distance, closest_atom2] = propka.calculations.get_smallest_distance(atoms1, atoms2)
if None in [closest_atom1, closest_atom2]: if None in [closest_atom1, closest_atom2]:
print('Warning: Side chain interaction failed for %s and %s'%(group1.label, group2.label)) warning('Side chain interaction failed for %s and %s' % (group1.label, group2.label))
return None return None
# get the parameters # get the parameters
@@ -627,17 +628,17 @@ def hydrogen_bond_interaction(group1, group2, version):
#exception = False # circumventing exception #exception = False # circumventing exception
if exception == True: if exception == True:
""" do nothing, value should have been assigned """ """ do nothing, value should have been assigned """
#print(" exception for %s %s %6.2lf" % (group1.label, group2.label, value)) #info(" exception for %s %s %6.2lf" % (group1.label, group2.label, value))
else: else:
value = version.calculateSideChainEnergy(distance, dpka_max, cutoff, weight, f_angle) value = version.calculateSideChainEnergy(distance, dpka_max, cutoff, weight, f_angle)
# print('distance',distance) # info('distance',distance)
# print('dpka_max',dpka_max) # info('dpka_max',dpka_max)
# print('cutoff',cutoff) # info('cutoff',cutoff)
# print('f_angle',f_angle) # info('f_angle',f_angle)
# print('weight',weight) # info('weight',weight)
# print('value',value) # info('value',value)
# print('===============================================') # info('===============================================')
return value return value
@@ -786,7 +787,7 @@ def checkCooArgException(group_coo, group_arg, version):
#cutoff = parameters.sidechain_cutoffs.get_value(group_coo.type,group_arg.type) #cutoff = parameters.sidechain_cutoffs.get_value(group_coo.type,group_arg.type)
# needs to be this way since you want to find shortest distance first # needs to be this way since you want to find shortest distance first
#print("--- exception for %s %s ---" % (group_coo.label, group_arg.label)) #info("--- exception for %s %s ---" % (group_coo.label, group_arg.label))
atoms_coo = [] atoms_coo = []
atoms_coo.extend(group_coo.get_interaction_atoms(group_arg)) atoms_coo.extend(group_coo.get_interaction_atoms(group_arg))
atoms_arg = [] atoms_arg = []
@@ -804,7 +805,7 @@ def checkCooArgException(group_coo, group_arg, version):
distance, f_angle, nada = AngleFactorX(closest_coo_atom, closest_arg_atom, atom3) distance, f_angle, nada = AngleFactorX(closest_coo_atom, closest_arg_atom, atom3)
value = HydrogenBondEnergy(distance, dpka_max, cutoff, f_angle) value = HydrogenBondEnergy(distance, dpka_max, cutoff, f_angle)
#print(iter, closest_coo_atom, closest_arg_atom,distance,value) #info(iter, closest_coo_atom, closest_arg_atom,distance,value)
value_tot += value value_tot += value
# remove closest atoms before we attemp to find the runner-up pair # remove closest atoms before we attemp to find the runner-up pair
atoms_coo.remove(closest_coo_atom) atoms_coo.remove(closest_coo_atom)

View File

@@ -6,6 +6,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import propka.group, propka.determinants, propka.determinant, propka.ligand, propka.output, propka.coupled_groups, functools import propka.group, propka.determinants, propka.determinant, propka.ligand, propka.output, propka.coupled_groups, functools
from propka.lib import info, warning
class Conformation_container: class Conformation_container:
def __init__(self, name='', parameters=None, molecular_container=None): def __init__(self, name='', parameters=None, molecular_container=None):
@@ -50,7 +51,7 @@ class Conformation_container:
map = propka.output.make_interaction_map('Covalent coupling map for %s'%self, map = propka.output.make_interaction_map('Covalent coupling map for %s'%self,
self.get_covalently_coupled_groups(), self.get_covalently_coupled_groups(),
lambda g1,g2: g1 in g2.covalently_coupled_groups) lambda g1,g2: g1 in g2.covalently_coupled_groups)
print(map) info(map)
# check if we should set a common charge centre as well # check if we should set a common charge centre as well
if self.parameters.common_charge_centre: if self.parameters.common_charge_centre:
@@ -96,7 +97,7 @@ class Conformation_container:
#self.get_titratable_groups(), #self.get_titratable_groups(),
self.get_covalently_coupled_groups(), self.get_covalently_coupled_groups(),
lambda g1,g2: g1 in g2.covalently_coupled_groups) lambda g1,g2: g1 in g2.covalently_coupled_groups)
print(map) info(map)
return return
@@ -168,7 +169,7 @@ class Conformation_container:
# #
def calculate_pka(self, version, options): def calculate_pka(self, version, options):
print('\nCalculating pKas for',self) info('\nCalculating pKas for', self)
# calculate desolvation # calculate desolvation
for group in self.get_titratable_groups()+self.get_ions(): for group in self.get_titratable_groups()+self.get_ions():
@@ -193,7 +194,7 @@ class Conformation_container:
penalised_labels = self.coupling_effects() penalised_labels = self.coupling_effects()
if self.parameters.remove_penalised_group and len(penalised_labels)>0: if self.parameters.remove_penalised_group and len(penalised_labels)>0:
print('Removing penalised groups!!!') info('Removing penalised groups!!!')
for g in self.get_titratable_groups(): for g in self.get_titratable_groups():
g.remove_determinants(penalised_labels) g.remove_determinants(penalised_labels)
@@ -297,7 +298,7 @@ class Conformation_container:
def calculate_folding_energy(self, pH=None, reference=None): def calculate_folding_energy(self, pH=None, reference=None):
ddg = 0.0 ddg = 0.0
for group in self.groups: for group in self.groups:
#print('Folding energy for %s at pH %f: %f'%(group,pH,group.calculate_folding_energy(self.parameters, pH=pH, reference=reference))) #info('Folding energy for %s at pH %f: %f'%(group,pH,group.calculate_folding_energy(self.parameters, pH=pH, reference=reference)))
ddg += group.calculate_folding_energy(self.parameters, pH=pH, reference=reference) ddg += group.calculate_folding_energy(self.parameters, pH=pH, reference=reference)
return ddg return ddg
@@ -379,7 +380,7 @@ class Conformation_container:
def add_atom(self, atom): def add_atom(self, atom):
#print(self,'adding',atom) #info(self,'adding',atom)
self.atoms.append(atom) self.atoms.append(atom)
if not atom.conformation_container: if not atom.conformation_container:
atom.conformation_container = self atom.conformation_container = self
@@ -446,5 +447,5 @@ class Conformation_container:
key += atom.resNumb*1000 key += atom.resNumb*1000
if len(atom.name) > len(atom.element): if len(atom.name) > len(atom.element):
key += ord(atom.name[len(atom.element)]) key += ord(atom.name[len(atom.element)])
#print(atom,ord(atom.name[len(atom.element)]), '|%s||%s|'%(atom.name,atom.element)) #info(atom,ord(atom.name[len(atom.element)]), '|%s||%s|'%(atom.name,atom.element))
return key return key

View File

@@ -3,6 +3,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import math, propka.output, propka.group, propka.lib, itertools import math, propka.output, propka.group, propka.lib, itertools
from propka.lib import info, warning
class non_covalently_couple_groups: class non_covalently_couple_groups:
@@ -129,22 +130,22 @@ class non_covalently_couple_groups:
self.parameters = conformation.parameters self.parameters = conformation.parameters
if verbose: if verbose:
print('') info('')
print(' Warning: When using the -d option, pKa values based on \'swapped\' interactions') info(' Warning: When using the -d option, pKa values based on \'swapped\' interactions')
print(' will be writting to the output .pka file') info(' will be writting to the output .pka file')
print('') info('')
print('-'*103) info('-' * 103)
print(' Detecting non-covalently coupled residues') info(' Detecting non-covalently coupled residues')
print('-'*103) info('-' * 103)
print(' Maximum pKa difference: %4.2f pKa units'%self.parameters.max_intrinsic_pKa_diff) info(' Maximum pKa difference: %4.2f pKa units' % self.parameters.max_intrinsic_pKa_diff)
print(' Minimum interaction energy: %4.2f pKa units'%self.parameters.min_interaction_energy) info(' Minimum interaction energy: %4.2f pKa units' % self.parameters.min_interaction_energy)
print(' Maximum free energy diff.: %4.2f pKa units'%self.parameters.max_free_energy_diff) info(' Maximum free energy diff.: %4.2f pKa units' % self.parameters.max_free_energy_diff)
print(' Minimum swap pKa shift: %4.2f pKa units'%self.parameters.min_swap_pka_shift) info(' Minimum swap pKa shift: %4.2f pKa units' % self.parameters.min_swap_pka_shift)
print(' pH: %6s ' %str(self.parameters.pH)) info(' pH: %6s ' % str(self.parameters.pH))
print(' Reference: %s' %self.parameters.reference) info(' Reference: %s' % self.parameters.reference)
print(' Min pKa: %4.2f'%self.parameters.min_pka) info(' Min pKa: %4.2f' % self.parameters.min_pka)
print(' Max pKa: %4.2f'%self.parameters.max_pka) info(' Max pKa: %4.2f' % self.parameters.max_pka)
print('') info('')
# find coupled residues # find coupled residues
titratable_groups = conformation.get_titratable_groups() titratable_groups = conformation.get_titratable_groups()
@@ -169,7 +170,7 @@ class non_covalently_couple_groups:
map = propka.output.make_interaction_map('Non-covalent coupling map for %s'%conformation, map = propka.output.make_interaction_map('Non-covalent coupling map for %s'%conformation,
conformation.get_non_covalently_coupled_groups(), conformation.get_non_covalently_coupled_groups(),
lambda g1,g2: g1 in g2.non_covalently_coupled_groups) lambda g1,g2: g1 in g2.non_covalently_coupled_groups)
print(map) info(map)
for system in conformation.get_coupled_systems(conformation.get_non_covalently_coupled_groups(),propka.group.Group.get_non_covalently_coupled_groups): for system in conformation.get_coupled_systems(conformation.get_non_covalently_coupled_groups(),propka.group.Group.get_non_covalently_coupled_groups):
self.print_system(conformation, list(system)) self.print_system(conformation, list(system))
@@ -177,7 +178,7 @@ class non_covalently_couple_groups:
def print_system(self, conformation, system): def print_system(self, conformation, system):
print('System containing %d groups:'%len(system)) info('System containing %d groups:' % len(system))
# make list of interactions withi this system # make list of interactions withi this system
interactions = list(itertools.combinations(system,2)) interactions = list(itertools.combinations(system,2))
@@ -187,7 +188,7 @@ class non_covalently_couple_groups:
for interaction in interactions: for interaction in interactions:
data = self.is_coupled_protonation_state_probability(interaction[0], interaction[1],conformation.calculate_folding_energy, return_on_fail=False) data = self.is_coupled_protonation_state_probability(interaction[0], interaction[1],conformation.calculate_folding_energy, return_on_fail=False)
coup_info += self.make_data_to_string(data,interaction[0],interaction[1])+'\n\n' coup_info += self.make_data_to_string(data,interaction[0],interaction[1])+'\n\n'
print(coup_info) info(coup_info)
# make list of possible combinations of swap to try out # make list of possible combinations of swap to try out
combinations = propka.lib.generate_combinations(interactions) combinations = propka.lib.generate_combinations(interactions)
@@ -211,7 +212,7 @@ class non_covalently_couple_groups:
#for interaction in combination: #for interaction in combination:
# self.swap_interactions([interaction[0]], [interaction[1]]) # self.swap_interactions([interaction[0]], [interaction[1]])
print(swap_info) info(swap_info)
return return
# #
@@ -236,7 +237,7 @@ class non_covalently_couple_groups:
all_labels = [g.label for g in system] all_labels = [g.label for g in system]
s = ' '+'-'*113+'\n' s = ' '+'-'*113+'\n'
for group in system: for group in system:
s += self.tagged_print(' %-8s|'%tag,group.getDeterminantString(), all_labels) s += self.tagged_format(' %-8s|' % tag, group.getDeterminantString(), all_labels)
return s+'\n' return s+'\n'
@@ -287,7 +288,7 @@ class non_covalently_couple_groups:
# Output methods # Output methods
# #
def tagged_print(self, tag, s, labels): def tagged_format(self, tag, s, labels):
s = "%s %s"%(tag,s) s = "%s %s"%(tag,s)
s = s.replace('\n','\n%s '%tag) s = s.replace('\n','\n%s '%tag)
for label in labels: for label in labels:

View File

@@ -6,6 +6,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import propka.ligand, propka.determinant, propka.ligand_pka_values, math, propka.protonate import propka.ligand, propka.determinant, propka.ligand_pka_values, math, propka.protonate
from propka.lib import info, warning
my_protonator = propka.protonate.Protonate(verbose=False) my_protonator = propka.protonate.Protonate(verbose=False)
@@ -80,7 +81,7 @@ expected_atoms_base_interactions = {
class Group: class Group:
def __init__(self, atom): def __init__(self, atom):
#print('Made new %s group from %s'%(type,atom)) #info('Made new %s group from %s'%(type,atom))
self.atom = atom self.atom = atom
self.type = '' self.type = ''
atom.group = self atom.group = self
@@ -349,7 +350,7 @@ class Group:
if self.residue_type in self.parameters.ions.keys(): if self.residue_type in self.parameters.ions.keys():
self.charge = self.parameters.ions[self.residue_type] self.charge = self.parameters.ions[self.residue_type]
#print('ION setup',self,self.residue_type, self.charge) #info('ION setup',self,self.residue_type, self.charge)
# find the center and the interaction atoms # find the center and the interaction atoms
self.setup_atoms() self.setup_atoms()
@@ -396,18 +397,18 @@ class Group:
ok = False ok = False
if not ok: if not ok:
print('Warning: Missing atoms or failed protonation for %s (%s) -- please check the structure'%(self.label, self.type)) warning('Missing atoms or failed protonation for %s (%s) -- please check the structure' % (self.label, self.type))
print(' %s'%self) warning('%s' % self)
Na = sum([expected_atoms_acid_interactions[self.type][e] for e in expected_atoms_acid_interactions[self.type].keys()]) Na = sum([expected_atoms_acid_interactions[self.type][e] for e in expected_atoms_acid_interactions[self.type].keys()])
Nb = sum([expected_atoms_base_interactions[self.type][e] for e in expected_atoms_base_interactions[self.type].keys()]) Nb = sum([expected_atoms_base_interactions[self.type][e] for e in expected_atoms_base_interactions[self.type].keys()])
print(' Expected %d interaction atoms for acids, found:'%Na) warning('Expected %d interaction atoms for acids, found:' % Na)
for i in range(len(self.interaction_atoms_for_acids)): for i in range(len(self.interaction_atoms_for_acids)):
print(' %s'%self.interaction_atoms_for_acids[i]) warning(' %s' % self.interaction_atoms_for_acids[i])
print(' Expected %d interaction atoms for bases, found:'%Nb) warning('Expected %d interaction atoms for bases, found:' % Nb)
for i in range(len(self.interaction_atoms_for_bases)): for i in range(len(self.interaction_atoms_for_bases)):
print(' %s'%self.interaction_atoms_for_bases[i]) warning(' %s' % self.interaction_atoms_for_bases[i])
#return #return
@@ -648,7 +649,7 @@ class HIS_group(Group):
# Find the atoms in the histidine ring # Find the atoms in the histidine ring
ring_atoms = propka.ligand.is_ring_member(self.atom) ring_atoms = propka.ligand.is_ring_member(self.atom)
if len(ring_atoms) != 5: if len(ring_atoms) != 5:
print('Warning: His group does not seem to contain a ring',self) warning('His group does not seem to contain a ring', self)
# protonate ring # protonate ring
for r in ring_atoms: for r in ring_atoms:
@@ -832,7 +833,7 @@ class NAR_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'NAR' self.type = 'NAR'
self.residue_type = 'NAR' self.residue_type = 'NAR'
print('Found NAR group:',atom) info('Found NAR group:', atom)
return return
@@ -855,7 +856,7 @@ class NAM_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'NAM' self.type = 'NAM'
self.residue_type = 'NAM' self.residue_type = 'NAM'
print('Found NAM group:',atom) info('Found NAM group:', atom)
return return
@@ -876,7 +877,7 @@ class F_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'F' self.type = 'F'
self.residue_type = 'F' self.residue_type = 'F'
print('Found F group:',atom) info('Found F group:', atom)
return return
class Cl_group(Group): class Cl_group(Group):
@@ -884,7 +885,7 @@ class Cl_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'Cl' self.type = 'Cl'
self.residue_type = 'Cl' self.residue_type = 'Cl'
print('Found Cl group:',atom) info('Found Cl group:', atom)
return return
class OH_group(Group): class OH_group(Group):
@@ -892,7 +893,7 @@ class OH_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'OH' self.type = 'OH'
self.residue_type = 'OH' self.residue_type = 'OH'
print('Found OH group:',atom) info('Found OH group:', atom)
return return
@@ -911,7 +912,7 @@ class OP_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'OP' self.type = 'OP'
self.residue_type = 'OP' self.residue_type = 'OP'
print('Found OP group:',atom) info('Found OP group:', atom)
return return
@@ -932,7 +933,7 @@ class O3_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'O3' self.type = 'O3'
self.residue_type = 'O3' self.residue_type = 'O3'
print('Found O3 group:',atom) info('Found O3 group:', atom)
return return
@@ -941,7 +942,7 @@ class O2_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'O2' self.type = 'O2'
self.residue_type = 'O2' self.residue_type = 'O2'
print('Found O2 group:',atom) info('Found O2 group:', atom)
return return
class SH_group(Group): class SH_group(Group):
@@ -949,7 +950,7 @@ class SH_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'SH' self.type = 'SH'
self.residue_type = 'SH' self.residue_type = 'SH'
print('Found SH group:',atom) info('Found SH group:', atom)
return return
@@ -959,7 +960,7 @@ class CG_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'CG' self.type = 'CG'
self.residue_type = 'CG' self.residue_type = 'CG'
print('Found CG group:',atom) info('Found CG group:', atom)
return return
def setup_atoms(self): def setup_atoms(self):
@@ -983,7 +984,7 @@ class C2N_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'C2N' self.type = 'C2N'
self.residue_type = 'C2N' self.residue_type = 'C2N'
print('Found C2N group:',atom) info('Found C2N group:', atom)
return return
def setup_atoms(self): def setup_atoms(self):
@@ -1007,7 +1008,7 @@ class OCO_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'OCO' self.type = 'OCO'
self.residue_type = 'OCO' self.residue_type = 'OCO'
print('Found OCO group:',atom) info('Found OCO group:', atom)
return return
def setup_atoms(self): def setup_atoms(self):
@@ -1026,7 +1027,7 @@ class N30_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'N30' self.type = 'N30'
self.residue_type = 'N30' self.residue_type = 'N30'
print('Found N30 group:',atom) info('Found N30 group:', atom)
return return
def setup_atoms(self): def setup_atoms(self):
@@ -1043,7 +1044,7 @@ class N31_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'N31' self.type = 'N31'
self.residue_type = 'N31' self.residue_type = 'N31'
print('Found N31 group:',atom) info('Found N31 group:', atom)
return return
def setup_atoms(self): def setup_atoms(self):
@@ -1060,7 +1061,7 @@ class N32_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'N32' self.type = 'N32'
self.residue_type = 'N32' self.residue_type = 'N32'
print('Found N32 group:',atom) info('Found N32 group:', atom)
return return
def setup_atoms(self): def setup_atoms(self):
@@ -1077,7 +1078,7 @@ class N33_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'N33' self.type = 'N33'
self.residue_type = 'N33' self.residue_type = 'N33'
print('Found N33 group:',atom) info('Found N33 group:', atom)
return return
def setup_atoms(self): def setup_atoms(self):
@@ -1094,7 +1095,7 @@ class NP1_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'NP1' self.type = 'NP1'
self.residue_type = 'NP1' self.residue_type = 'NP1'
print('Found NP1 group:',atom) info('Found NP1 group:', atom)
return return
@@ -1112,7 +1113,7 @@ class N1_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'N1' self.type = 'N1'
self.residue_type = 'N1' self.residue_type = 'N1'
print('Found N1 group:',atom) info('Found N1 group:', atom)
return return
@@ -1122,7 +1123,7 @@ class Ion_group(Group):
Group.__init__(self,atom) Group.__init__(self,atom)
self.type = 'ION' self.type = 'ION'
self.residue_type = atom.resName.strip() self.residue_type = atom.resName.strip()
print('Found ion group:',atom) info('Found ion group:', atom)
return return
@@ -1131,7 +1132,7 @@ class non_titratable_ligand_group(Group):
Group.__init__(self, atom) Group.__init__(self, atom)
self.type = 'LG' self.type = 'LG'
self.residue_type = 'LG' self.residue_type = 'LG'
# print('Non-titratable ligand group',atom) # info('Non-titratable ligand group',atom)
return return
class titratable_ligand_group(Group): class titratable_ligand_group(Group):
@@ -1153,7 +1154,7 @@ class titratable_ligand_group(Group):
# this is not true if we are reading an input file # this is not true if we are reading an input file
if atom.marvin_pka: if atom.marvin_pka:
self.model_pka = atom.marvin_pka self.model_pka = atom.marvin_pka
print('Titratable ligand group ',atom, self.model_pka, self.charge) info('Titratable ligand group ', atom, self.model_pka, self.charge)
self.model_pka_set = True self.model_pka_set = True
return return

View File

@@ -7,6 +7,7 @@ import math, time
import propka.lib as lib import propka.lib as lib
from propka.determinant import Determinant from propka.determinant import Determinant
import propka.calculations import propka.calculations
from propka.lib import info, warning, debug
# Some library functions for the interative pKa determinants # Some library functions for the interative pKa determinants
@@ -186,8 +187,8 @@ def addDeterminants(iterative_interactions, version, options=None):
done_group.append(group) done_group.append(group)
# Initialize iterative scheme # Initialize iterative scheme
if options.verbose == True: debug("\n --- pKa iterations (%d groups, %d interactions) ---" %
print("\n --- pKa iterations (%d groups, %d interactions) ---" % ( len(iteratives), len(iterative_interactions) )) (len(iteratives), len(iterative_interactions)))
converged = False converged = False
iteration = 0 iteration = 0
# set non-iterative pka values as first step # set non-iterative pka values as first step
@@ -246,30 +247,30 @@ def addDeterminants(iterative_interactions, version, options=None):
itres.pKa_iter.append(itres.pKa_new) itres.pKa_iter.append(itres.pKa_new)
if iteration == 10: if iteration == 10:
print("did not converge in %d iterations" % (iteration)) info("did not converge in %d iterations" % (iteration))
break break
# --- Iterations finished --- # --- Iterations finished ---
# printing pKa iterations # printing pKa iterations
if options.verbose == True: # formerly was conditioned on if options.verbosity >= 2 - now unnecessary
str = "%12s" % (" ") str = "%12s" % (" ")
for index in range(0, iteration+1 ): for index in range(0, iteration+1 ):
str += "%8d" % (index) str += "%8d" % (index)
print(str) debug(str)
for itres in iteratives: for itres in iteratives:
str = "%s " % (itres.label) str = "%s " % (itres.label)
for pKa in itres.pKa_iter: for pKa in itres.pKa_iter:
str += "%8.2lf" % (pKa) str += "%8.2lf" % (pKa)
if itres.converged == False: if itres.converged == False:
str += " *" str += " *"
print(str) debug(str)
# creating real determinants and adding them to group object # creating real determinants and adding them to group object
for itres in iteratives: for itres in iteratives:
for type in ['sidechain','backbone','coulomb']: for type in ['sidechain','backbone','coulomb']:
for interaction in itres.determinants[type]: for interaction in itres.determinants[type]:
#print('done',itres.group.label,interaction[0],interaction[1]) #info('done',itres.group.label,interaction[0],interaction[1])
value = interaction[1] value = interaction[1]
if value > 0.005 or value < -0.005: if value > 0.005 or value < -0.005:
g = interaction[0] g = interaction[0]

View File

@@ -1,9 +1,14 @@
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
import string, sys, copy, math, os import sys
import pkg_resources import pkg_resources
import logging
logger = logging.getLogger("propka")
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(logging.Formatter("%(message)s"))
logger.addHandler(stdout_handler)
# #
# file I/O # file I/O
@@ -132,7 +137,7 @@ def parse_res_string(res_str):
def loadOptions(*args): def loadOptions(*args):
""" """
load the arguments parser with options Load the arguments parser with options. Note that verbosity is set as soon as this function is invoked.
""" """
from optparse import OptionParser from optparse import OptionParser
@@ -162,15 +167,11 @@ def loadOptions(*args):
parser.add_option("-v", "--version", dest="version_label", default="Jan15", parser.add_option("-v", "--version", dest="version_label", default="Jan15",
help="specifying the sub-version of propka [Jan15/Dec19]") help="specifying the sub-version of propka [Jan15/Dec19]")
parser.add_option("-p", "--parameters",dest="parameters", default=pkg_resources.resource_filename(__name__, "propka.cfg"), parser.add_option("-p", "--parameters",dest="parameters", default=pkg_resources.resource_filename(__name__, "propka.cfg"),
help="set the parameter file [%default]") help="set the parameter file [%default]")
parser.add_option("-z", "--verbose", dest="verbose", action="store_true", default=True, parser.add_option("-z", "--verbose", dest="verbosity", action="store_const", const=2,
help="sleep during calculations") help="output debugging information")
parser.add_option("-q", "--quiet", dest="verbose", action="store_false", parser.add_option("-q", "--quiet", dest="verbosity", action="store_const", const=0, default=1,
help="sleep during calculations") help="inhibit printing to stdout")
parser.add_option("-s", "--silent", dest="verbose", action="store_false",
help="not activated yet")
parser.add_option("--verbosity", dest="verbosity", action="store_const",
help="level of printout - not activated yet")
parser.add_option("-o", "--pH", dest="pH", type="float", default=7.0, parser.add_option("-o", "--pH", dest="pH", type="float", default=7.0,
help="setting pH-value used in e.g. stability calculations [7.0]") help="setting pH-value used in e.g. stability calculations [7.0]")
parser.add_option("-w", "--window", dest="window", nargs=3, type="float", default=(0.0, 14.0, 1.0), parser.add_option("-w", "--window", dest="window", nargs=3, type="float", default=(0.0, 14.0, 1.0),
@@ -204,9 +205,10 @@ def loadOptions(*args):
for filename in options.filenames: for filename in options.filenames:
args.append(filename) args.append(filename)
# checking at early stage that there is at least one pdbfile to work with # checking at early stage that there is at least one pdbfile to work with. The error message is misleading
# if one is using the python interface via Molecular_container.
if len(args) == 0: if len(args) == 0:
print("Warning: no pdbfile provided") info("No pdbfile provided")
#sys.exit(9) #sys.exit(9)
# Convert titrate_only string to a list of (chain, resnum) items: # Convert titrate_only string to a list of (chain, resnum) items:
@@ -216,11 +218,22 @@ def loadOptions(*args):
try: try:
chain, resnum, inscode = parse_res_string(res_str) chain, resnum, inscode = parse_res_string(res_str)
except ValueError: except ValueError:
print('Invalid residue string: "%s"' % res_str) logger.critical('Invalid residue string: "%s"' % res_str)
sys.exit(1) sys.exit(1)
res_list.append((chain, resnum, inscode)) res_list.append((chain, resnum, inscode))
options.titrate_only = res_list options.titrate_only = res_list
# Set the no-print variable
if options.verbosity == 0:
logger.setLevel(logging.CRITICAL)
elif options.verbosity == 1:
logger.setLevel(logging.INFO)
elif options.verbosity == 2:
logger.setLevel(logging.DEBUG)
else:
logger.warning("Invalid verbosity level, using default")
# done! # done!
return options, args return options, args
@@ -272,3 +285,19 @@ def writeFile(filename, lines):
f.close() f.close()
def _args_to_str(arg_list):
return " ".join(map(str, arg_list))
def info(*args):
"""Log a message. Level defaults to INFO unless overridden."""
logger.info(_args_to_str(args))
def debug(*args):
"""Log a message on the DEBUG level."""
logger.debug(_args_to_str(args))
def warning(*args):
"""Log a WARN message"""
logger.warning(_args_to_str(args))

View File

@@ -7,6 +7,7 @@ import sys
import propka.calculations import propka.calculations
from propka.vector_algebra import * from propka.vector_algebra import *
from propka.lib import info, warning
all_sybyl_types = [ all_sybyl_types = [
@@ -150,7 +151,7 @@ max_C_triple_bond_squared = max_C_triple_bond*max_C_triple_bond
def assign_sybyl_type(atom): def assign_sybyl_type(atom):
# check if we already have assigned a name to this atom # check if we already have assigned a name to this atom
if atom.sybyl_assigned: if atom.sybyl_assigned:
#print(atom.name,'already assigned') #info(atom.name,'already assigned')
return return
# find some properties of the atom # find some properties of the atom
@@ -331,7 +332,7 @@ def assign_sybyl_type(atom):
element = atom.element.capitalize() element = atom.element.capitalize()
set_type(atom,element) set_type(atom,element)
# print('Using element as type for %s'%atom.element) # info('Using element as type for %s'%atom.element)
return return
@@ -362,7 +363,7 @@ def identify_ring(this_atom, original_atom, number, past_atoms):
def set_type(atom,type): def set_type(atom,type):
#print(atom, '->',type) #info(atom, '->',type)
atom.sybyl_type = type atom.sybyl_type = type
atom.sybyl_assigned=True atom.sybyl_assigned=True
return return
@@ -387,7 +388,7 @@ def are_atoms_planar(atoms):
margin = 0.20 margin = 0.20
for b in atoms[3:]: for b in atoms[3:]:
v = vector(atom1=atoms[0], atom2=b).rescale(1.0) v = vector(atom1=atoms[0], atom2=b).rescale(1.0)
#print(atoms[0],abs(v*n) ) #info(atoms[0],abs(v*n) )
if abs(v*n)>margin: if abs(v*n)>margin:
return False return False

View File

@@ -2,6 +2,7 @@
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
from propka.lib import info, warning
import propka.molecular_container, propka.calculations, propka.calculations, propka.parameters, propka.pdb, propka.lib, os, subprocess, sys import propka.molecular_container, propka.calculations, propka.calculations, propka.parameters, propka.pdb, propka.lib, os, subprocess, sys
@@ -12,9 +13,9 @@ class ligand_pka_values:
# attempt to find Marvin executables in the path # attempt to find Marvin executables in the path
self.molconvert = self.find_in_path('molconvert') self.molconvert = self.find_in_path('molconvert')
self.cxcalc = self.find_in_path('cxcalc') self.cxcalc = self.find_in_path('cxcalc')
print('Found Marvin executables:') info('Found Marvin executables:')
print(self.cxcalc) info(self.cxcalc)
print(self.molconvert) info(self.molconvert)
return return
@@ -26,7 +27,7 @@ class ligand_pka_values:
map(lambda dir: os.path.join(dir, program),path))] map(lambda dir: os.path.join(dir, program),path))]
if len(l) == 0: if len(l) == 0:
print('Error: Could not find %s. Please make sure that it is found in the path.'%program) info('Error: Could not find %s. Please make sure that it is found in the path.' % program)
sys.exit(-1) sys.exit(-1)
return l[0] return l[0]
@@ -67,7 +68,7 @@ class ligand_pka_values:
propka.pdb.write_mol2_for_atoms(atoms, filename) propka.pdb.write_mol2_for_atoms(atoms, filename)
# check that we actually have a file to work with # check that we actually have a file to work with
if not os.path.isfile(filename): if not os.path.isfile(filename):
print('Warning: Didn\'t find a user-modified file \'%s\' - generating one'%filename) warning('Didn\'t find a user-modified file \'%s\' - generating one' % filename)
propka.pdb.write_mol2_for_atoms(atoms, filename) propka.pdb.write_mol2_for_atoms(atoms, filename)
@@ -79,12 +80,12 @@ class ligand_pka_values:
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
if len(errors)>0: if len(errors)>0:
print('********************************************************************************************************') info('********************************************************************************************************')
print('* Warning: Marvin execution failed: *') info('* Warning: Marvin execution failed: *')
print('* %-100s *'%errors) info('* %-100s *' % errors)
print('* *') info('* *')
print('* Please edit the ligand mol2 file and re-run PropKa with the -l option: %29s *'%filename) info('* Please edit the ligand mol2 file and re-run PropKa with the -l option: %29s *' % filename)
print('********************************************************************************************************') info('********************************************************************************************************')
sys.exit(-1) sys.exit(-1)
# extract calculated pkas # extract calculated pkas
@@ -94,15 +95,15 @@ class ligand_pka_values:
for i in range(len(indices)): for i in range(len(indices)):
atoms[indices[i]].marvin_pka = pkas[i] atoms[indices[i]].marvin_pka = pkas[i]
atoms[indices[i]].charge = {'a':-1,'b':+1}[types[i]] atoms[indices[i]].charge = {'a':-1,'b':+1}[types[i]]
print('%s model pKa: %.2f'%(atoms[indices[i]],pkas[i])) info('%s model pKa: %.2f' % (atoms[indices[i]], pkas[i]))
return return
def extract_pkas(self, output): def extract_pkas(self, output):
# split output # split output
[tags, values,empty_line] = output.decode().split('\n') [tags, values,empty_line] = output.decode().split('\n')
#print(tags) #info(tags)
#print(values) #info(values)
tags = tags.split('\t') tags = tags.split('\t')
values = values.split('\t') values = values.split('\t')

View File

@@ -9,6 +9,7 @@ from __future__ import print_function
import os, sys import os, sys
import propka.pdb, propka.version, propka.output, propka.conformation_container, propka.group, propka.lib import propka.pdb, propka.version, propka.output, propka.conformation_container, propka.group, propka.lib
from propka.lib import info, warning
class Molecular_container: class Molecular_container:
def __init__(self, input_file, options=None): def __init__(self, input_file, options=None):
@@ -39,7 +40,7 @@ class Molecular_container:
# read in atoms and top up containers to make sure that all atoms are present in all conformations # read in atoms and top up containers to make sure that all atoms are present in all conformations
[self.conformations, self.conformation_names] = propka.pdb.read_pdb(input_file, self.version.parameters,self) [self.conformations, self.conformation_names] = propka.pdb.read_pdb(input_file, self.version.parameters,self)
if len(self.conformations)==0: if len(self.conformations)==0:
print('Error: The pdb file does not seems to contain any molecular conformations') info('Error: The pdb file does not seems to contain any molecular conformations')
sys.exit(-1) sys.exit(-1)
self.top_up_conformations() self.top_up_conformations()
@@ -76,7 +77,7 @@ class Molecular_container:
self.additional_setup_when_reading_input_file() self.additional_setup_when_reading_input_file()
else: else:
print('Unrecognized input file:%s'%input_file) info('Unrecognized input file:%s' % input_file)
sys.exit(-1) sys.exit(-1)
@@ -90,14 +91,14 @@ class Molecular_container:
return return
def find_covalently_coupled_groups(self): def find_covalently_coupled_groups(self):
print('-'*103) info('-' * 103)
for name in self.conformation_names: for name in self.conformation_names:
self.conformations[name].find_covalently_coupled_groups() self.conformations[name].find_covalently_coupled_groups()
return return
def find_non_covalently_coupled_groups(self): def find_non_covalently_coupled_groups(self):
print('-'*103) info('-' * 103)
for name in self.conformation_names: for name in self.conformation_names:
self.conformations[name].find_non_covalently_coupled_groups(verbose=self.options.display_coupled_residues) self.conformations[name].find_non_covalently_coupled_groups(verbose=self.options.display_coupled_residues)
@@ -149,7 +150,7 @@ class Molecular_container:
if group_to_add: if group_to_add:
avr_group += group_to_add avr_group += group_to_add
else: else:
print('Warning: Group %s could not be found in conformation %s.'%(group.atom.residue_label, name)) warning('Group %s could not be found in conformation %s.' % (group.atom.residue_label, name))
# ... and store the average value # ... and store the average value
avr_group = avr_group / len(self.conformation_names) avr_group = avr_group / len(self.conformation_names)
avr_conformation.groups.append(avr_group) avr_conformation.groups.append(avr_group)
@@ -192,7 +193,7 @@ class Molecular_container:
profile = [] profile = []
for ph in propka.lib.make_grid(*grid): for ph in propka.lib.make_grid(*grid):
ddg = self.conformations[conformation].calculate_folding_energy( pH=ph, reference=reference) ddg = self.conformations[conformation].calculate_folding_energy( pH=ph, reference=reference)
#print(ph,ddg) #info(ph,ddg)
profile.append([ph, ddg]) profile.append([ph, ddg])
# find optimum # find optimum
@@ -225,7 +226,7 @@ class Molecular_container:
return charge_profile return charge_profile
def getPI(self, conformation='AVR', grid=[0., 14., 1], iteration=0): def getPI(self, conformation='AVR', grid=[0., 14., 1], iteration=0):
#print('staring',grid, iteration) #info('staring',grid, iteration)
# search # search
charge_profile = self.getChargeProfile(conformation=conformation, grid=grid) charge_profile = self.getChargeProfile(conformation=conformation, grid=grid)
pi = [] pi = []

View File

@@ -5,6 +5,7 @@ from __future__ import print_function
import sys import sys
import propka.lib import propka.lib
from propka.lib import info, warning
def printHeader(): def printHeader():
@@ -15,7 +16,7 @@ def printHeader():
str += "%s\n" % ( getReferencesHeader() ) str += "%s\n" % ( getReferencesHeader() )
str += "%s\n" % ( getWarningHeader() ) str += "%s\n" % ( getWarningHeader() )
print(str) info(str)
def writePDB(protein, file=None, filename=None, include_hydrogens=False, options=None): def writePDB(protein, file=None, filename=None, include_hydrogens=False, options=None):
@@ -28,7 +29,7 @@ def writePDB(protein, file=None, filename=None, include_hydrogens=False, options
if filename == None: if filename == None:
filename = "%s.pdb" % (protein.name) filename = "%s.pdb" % (protein.name)
file = open(filename, 'w') file = open(filename, 'w')
print("writing pdbfile %s" % (filename)) info("writing pdbfile %s" % (filename))
close_file = True close_file = True
else: else:
# don't close the file, it was opened in a different place # don't close the file, it was opened in a different place
@@ -60,7 +61,7 @@ def writePKA(protein, parameters, filename=None, conformation ='1A',reference="n
filename = "%s.pka" % (protein.name) filename = "%s.pka" % (protein.name)
file = open(filename, 'w') file = open(filename, 'w')
if verbose == True: if verbose == True:
print("Writing %s" % (filename)) info("Writing %s" % (filename))
# writing propka header # writing propka header
str = "%s\n" % ( getPropkaHeader() ) str = "%s\n" % ( getPropkaHeader() )
@@ -98,7 +99,7 @@ def printTmProfile(protein, reference="neutral", window=[0., 14., 1.], Tm=[0.,0.
for (pH, Tm) in profile: for (pH, Tm) in profile:
if pH >= window[0] and pH <= window[1] and (pH%window[2] < 0.01 or pH%window[2] > 0.99*window[2]): if pH >= window[0] and pH <= window[1] and (pH%window[2] < 0.01 or pH%window[2] > 0.99*window[2]):
str += "%6.2lf%10.2lf\n" % (pH, Tm) str += "%6.2lf%10.2lf\n" % (pH, Tm)
print(str) info(str)
def printResult(protein, conformation, parameters): def printResult(protein, conformation, parameters):
@@ -114,10 +115,10 @@ def printPKASection(protein, conformation, parameters):
""" """
# geting the determinants section # geting the determinants section
str = getDeterminantSection(protein, conformation, parameters) str = getDeterminantSection(protein, conformation, parameters)
print(str) info(str)
str = getSummarySection(protein,conformation,parameters) str = getSummarySection(protein,conformation,parameters)
print(str) info(str)
def getDeterminantSection(protein, conformation, parameters): def getDeterminantSection(protein, conformation, parameters):

View File

@@ -5,6 +5,7 @@ from __future__ import print_function
import math import math
import propka.lib as lib import propka.lib as lib
import sys, os import sys, os
from propka.lib import info, warning
import pkg_resources import pkg_resources
@@ -99,7 +100,7 @@ class Parameters:
self.parse_to_string_dictionary(words) self.parse_to_string_dictionary(words)
#print(words) #info(words)
return return
@@ -138,7 +139,7 @@ class Parameters:
return return
def parse_string(self, words): def parse_string(self, words):
#print('self.%s = \'%s\''%tuple(words)) #info('self.%s = \'%s\''%tuple(words))
exec('self.%s = \'%s\''%tuple(words)) exec('self.%s = \'%s\''%tuple(words))
return return
@@ -158,12 +159,12 @@ class Parameters:
return return
def print_interaction_parameters(self): def print_interaction_parameters(self):
print('--------------- Model pKa values ----------------------') info('--------------- Model pKa values ----------------------')
for k in self.model_pkas.keys(): for k in self.model_pkas.keys():
print('%3s %8.2f'%(k,self.model_pkas[k])) info('%3s %8.2f' % (k, self.model_pkas[k]))
print('') info('')
print('--------------- Interactions --------------------------') info('--------------- Interactions --------------------------')
agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
@@ -213,21 +214,21 @@ class Parameters:
if len(map[g2])==0 and (self.sidechain_cutoffs.get_value(g1,g2)[0] !=3 or self.sidechain_cutoffs.get_value(g1,g2)[1] != 4): if len(map[g2])==0 and (self.sidechain_cutoffs.get_value(g1,g2)[0] !=3 or self.sidechain_cutoffs.get_value(g1,g2)[1] != 4):
map_interaction += '? ' map_interaction += '? '
print(interaction,map_interaction ) info(interaction, map_interaction)
if g1==g2: if g1==g2:
break break
print('-') info('-')
print('--------------- Exceptions ----------------------------') info('--------------- Exceptions ----------------------------')
print('COO-HIS',self.COO_HIS_exception) info('COO-HIS', self.COO_HIS_exception)
print('OCO-HIS',self.OCO_HIS_exception) info('OCO-HIS', self.OCO_HIS_exception)
print('CYS-HIS',self.CYS_HIS_exception) info('CYS-HIS', self.CYS_HIS_exception)
print('CYS-CYS',self.CYS_CYS_exception) info('CYS-CYS', self.CYS_CYS_exception)
print('--------------- Mapping -------------------------------') info('--------------- Mapping -------------------------------')
print(""" info("""
Titratable: Titratable:
CG ARG CG ARG
C2N ARG C2N ARG
@@ -258,12 +259,12 @@ O2
def print_interaction_parameters_latex(self): def print_interaction_parameters_latex(self):
# print('--------------- Model pKa values ----------------------') # info('--------------- Model pKa values ----------------------')
# for k in self.model_pkas.keys(): # for k in self.model_pkas.keys():
# print('%3s %8.2f'%(k,self.model_pkas[k])) # info('%3s %8.2f'%(k,self.model_pkas[k]))
# print('') # info('')
# print('--------------- Interactions --------------------------') # info('--------------- Interactions --------------------------')
agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] agroups = ['COO', 'HIS', 'CYS', 'TYR', 'SER', 'N+', 'LYS', 'AMD', 'ARG', 'TRP', 'ROH', 'CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH'] lgroups = ['CG', 'C2N', 'N30', 'N31', 'N32', 'N33', 'NAR', 'OCO', 'NP1', 'OH', 'O3', 'CL', 'F', 'NAM', 'N1', 'O2', 'OP', 'SH']
@@ -329,7 +330,7 @@ Group1 & Group2 & Interaction & c1 &c2 \\\\
break break
s += ' \\end{longtable}\n' s += ' \\end{longtable}\n'
print(s) info(s)
return return
def print_interactions_latex(self): def print_interactions_latex(self):
@@ -373,7 +374,7 @@ Group1 & Group2 & Interaction & c1 &c2 \\\\
break break
s += ' \\end{longtable}\n' s += ' \\end{longtable}\n'
print(s) info(s)
return return
@@ -444,7 +445,7 @@ class Interaction_matrix:
# p+='sidechain_cutoff %3s %3s %s\n'%(ks[i],ks[j],self[ks[i]][ks[j]]) # p+='sidechain_cutoff %3s %3s %s\n'%(ks[i],ks[j],self[ks[i]][ks[j]])
# n+=1 # n+=1
# print('total',n,len(ks)) # info('total',n,len(ks))
# return p # return p
@@ -476,7 +477,7 @@ class Pair_wise_matrix:
if k1 in self.dictionary.keys() and k2 in self.dictionary[k1].keys(): if k1 in self.dictionary.keys() and k2 in self.dictionary[k1].keys():
if k1!=k2: if k1!=k2:
print ('Warning: Paramter value for %s, %s defined more than once'%(k1,k2)) warning('Parameter value for %s, %s defined more than once' % (k1, k2))
if not k1 in self.dictionary: if not k1 in self.dictionary:
self.dictionary[k1] = {} self.dictionary[k1] = {}

View File

@@ -5,6 +5,8 @@ from __future__ import print_function
import string, sys, copy import string, sys, copy
import propka.lib import propka.lib
from propka.lib import info, warning
from propka.atom import Atom from propka.atom import Atom
from propka.conformation_container import Conformation_container from propka.conformation_container import Conformation_container
@@ -71,12 +73,12 @@ def protein_precheck(conformations, names):
# check for c-terminal # check for c-terminal
if 'C-' in [a.terminal for a in res_atoms]: if 'C-' in [a.terminal for a in res_atoms]:
if len(res_atoms) != expected_atom_numbers[resname]+1: if len(res_atoms) != expected_atom_numbers[resname]+1:
print('Warning: Unexpected number (%d) of atoms in residue %s in conformation %s'%(len(res_atoms),residue_label, name)) warning('Unexpected number (%d) of atoms in residue %s in conformation %s' % (len(res_atoms), residue_label, name))
continue continue
# check number of atoms in residue # check number of atoms in residue
if len(res_atoms) != expected_atom_numbers[resname]: if len(res_atoms) != expected_atom_numbers[resname]:
print('Warning: Unexpected number (%d) of atoms in residue %s in conformation %s'%(len(res_atoms),residue_label, name)) warning('Unexpected number (%d) of atoms in residue %s in conformation %s' % (len(res_atoms), residue_label, name))
return return

View File

@@ -5,6 +5,7 @@ from __future__ import print_function
from propka.vector_algebra import * from propka.vector_algebra import *
import propka.bonds, propka.pdb, propka.atom import propka.bonds, propka.pdb, propka.atom
from propka.lib import info, warning, debug
class Protonate: class Protonate:
""" Protonates atoms using VSEPR theory """ """ Protonates atoms using VSEPR theory """
@@ -94,7 +95,7 @@ class Protonate:
def protonate(self, molecules): def protonate(self, molecules):
""" Will protonate all atoms in the molecular container """ """ Will protonate all atoms in the molecular container """
self.display('----- Protonation started -----') debug('----- Protonation started -----')
# Remove all currently present hydrogen atoms # Remove all currently present hydrogen atoms
self.remove_all_hydrogen_atoms(molecules) self.remove_all_hydrogen_atoms(molecules)
@@ -122,11 +123,11 @@ class Protonate:
if atom.type=='atom': if atom.type=='atom':
key = '%3s-%s'%(atom.resName, atom.name) key = '%3s-%s'%(atom.resName, atom.name)
if atom.terminal: if atom.terminal:
self.display(atom.terminal) debug(atom.terminal)
key=atom.terminal key=atom.terminal
if key in list(self.standard_charges.keys()): if key in list(self.standard_charges.keys()):
atom.charge = self.standard_charges[key] atom.charge = self.standard_charges[key]
self.display('Charge', atom, atom.charge) debug('Charge', atom, atom.charge)
atom.charge_set = True atom.charge_set = True
# atom is a ligand atom # atom is a ligand atom
elif atom.type=='hetatm': elif atom.type=='hetatm':
@@ -163,21 +164,21 @@ class Protonate:
def set_number_of_protons_to_add(self, atom): def set_number_of_protons_to_add(self, atom):
self.display('*'*10) debug('*'*10)
self.display('Setting number of protons to add for',atom) debug('Setting number of protons to add for',atom)
atom.number_of_protons_to_add = 8 atom.number_of_protons_to_add = 8
self.display(' %4d'%8) debug(' %4d'%8)
atom.number_of_protons_to_add -= self.valence_electrons[atom.element] atom.number_of_protons_to_add -= self.valence_electrons[atom.element]
self.display('Valence eletrons: %4d'%-self.valence_electrons[atom.element]) debug('Valence eletrons: %4d'%-self.valence_electrons[atom.element])
atom.number_of_protons_to_add -= len(atom.bonded_atoms) atom.number_of_protons_to_add -= len(atom.bonded_atoms)
self.display('Number of bonds: %4d'%- len(atom.bonded_atoms)) debug('Number of bonds: %4d'%- len(atom.bonded_atoms))
atom.number_of_protons_to_add -= atom.number_of_pi_electrons_in_double_and_triple_bonds atom.number_of_protons_to_add -= atom.number_of_pi_electrons_in_double_and_triple_bonds
self.display('Pi electrons: %4d'%-atom.number_of_pi_electrons_in_double_and_triple_bonds) debug('Pi electrons: %4d'%-atom.number_of_pi_electrons_in_double_and_triple_bonds)
atom.number_of_protons_to_add += int(atom.charge) atom.number_of_protons_to_add += int(atom.charge)
self.display('Charge: %4.1f'%atom.charge) debug('Charge: %4.1f'%atom.charge)
self.display('-'*10) debug('-'*10)
self.display(atom.number_of_protons_to_add) debug(atom.number_of_protons_to_add)
return return
@@ -187,8 +188,8 @@ class Protonate:
if atom.steric_number_and_lone_pairs_set: if atom.steric_number_and_lone_pairs_set:
return return
self.display('='*10) debug('='*10)
self.display('Setting steric number and lone pairs for',atom) debug('Setting steric number and lone pairs for',atom)
# costumly set the N backbone atoms up for peptide bond trigonal planer shape # costumly set the N backbone atoms up for peptide bond trigonal planer shape
#if atom.name == 'N' and len(atom.bonded_atoms) == 2: #if atom.name == 'N' and len(atom.bonded_atoms) == 2:
@@ -201,34 +202,34 @@ class Protonate:
atom.steric_number = 0 atom.steric_number = 0
self.display('%65s: %4d'%('Valence electrons',self.valence_electrons[atom.element])) debug('%65s: %4d'%('Valence electrons',self.valence_electrons[atom.element]))
atom.steric_number += self.valence_electrons[atom.element] atom.steric_number += self.valence_electrons[atom.element]
self.display('%65s: %4d'%('Number of bonds',len(atom.bonded_atoms))) debug('%65s: %4d'%('Number of bonds',len(atom.bonded_atoms)))
atom.steric_number += len(atom.bonded_atoms) atom.steric_number += len(atom.bonded_atoms)
self.display('%65s: %4d'%('Number of hydrogen atoms to add',atom.number_of_protons_to_add)) debug('%65s: %4d'%('Number of hydrogen atoms to add',atom.number_of_protons_to_add))
atom.steric_number += atom.number_of_protons_to_add atom.steric_number += atom.number_of_protons_to_add
self.display('%65s: %4d'%('Number of pi-electrons in double and triple bonds(-)',atom.number_of_pi_electrons_in_double_and_triple_bonds)) debug('%65s: %4d'%('Number of pi-electrons in double and triple bonds(-)',atom.number_of_pi_electrons_in_double_and_triple_bonds))
atom.steric_number -= atom.number_of_pi_electrons_in_double_and_triple_bonds atom.steric_number -= atom.number_of_pi_electrons_in_double_and_triple_bonds
self.display('%65s: %4d'%('Number of pi-electrons in conjugated double and triple bonds(-)',atom.number_of_pi_electrons_in_conjugate_double_and_triple_bonds)) debug('%65s: %4d'%('Number of pi-electrons in conjugated double and triple bonds(-)',atom.number_of_pi_electrons_in_conjugate_double_and_triple_bonds))
atom.steric_number -= atom.number_of_pi_electrons_in_conjugate_double_and_triple_bonds atom.steric_number -= atom.number_of_pi_electrons_in_conjugate_double_and_triple_bonds
self.display('%65s: %4d'%('Number of donated co-ordinated bonds',0)) debug('%65s: %4d'%('Number of donated co-ordinated bonds',0))
atom.steric_number += 0 atom.steric_number += 0
self.display('%65s: %4.1f'%('Charge(-)',atom.charge)) debug('%65s: %4.1f'%('Charge(-)',atom.charge))
atom.steric_number -= atom.charge atom.steric_number -= atom.charge
atom.steric_number = math.floor(atom.steric_number/2.0) atom.steric_number = math.floor(atom.steric_number/2.0)
atom.number_of_lone_pairs = atom.steric_number - len(atom.bonded_atoms) - atom.number_of_protons_to_add atom.number_of_lone_pairs = atom.steric_number - len(atom.bonded_atoms) - atom.number_of_protons_to_add
self.display('-'*70) debug('-'*70)
self.display('%65s: %4d'%('Steric number',atom.steric_number)) debug('%65s: %4d'%('Steric number',atom.steric_number))
self.display('%65s: %4d'%('Number of lone pairs',atom.number_of_lone_pairs)) debug('%65s: %4d'%('Number of lone pairs',atom.number_of_lone_pairs))
atom.steric_number_and_lone_pairs_set = True atom.steric_number_and_lone_pairs_set = True
@@ -237,17 +238,17 @@ class Protonate:
def add_protons(self, atom): def add_protons(self, atom):
# decide which method to use # decide which method to use
self.display('PROTONATING',atom) debug('PROTONATING',atom)
if atom.steric_number in list(self.protonation_methods.keys()): if atom.steric_number in list(self.protonation_methods.keys()):
self.protonation_methods[atom.steric_number](atom) self.protonation_methods[atom.steric_number](atom)
else: else:
print('Warning: Do not have a method for protonating',atom,'(steric number: %d)'%atom.steric_number) warning('Do not have a method for protonating', atom, '(steric number: %d)' % atom.steric_number)
return return
def trigonal(self, atom): def trigonal(self, atom):
self.display('TRIGONAL - %d bonded atoms'%(len(atom.bonded_atoms))) debug('TRIGONAL - %d bonded atoms'%(len(atom.bonded_atoms)))
rot_angle = math.radians(120.0) rot_angle = math.radians(120.0)
c = vector(atom1 = atom) c = vector(atom1 = atom)
@@ -312,7 +313,7 @@ class Protonate:
def tetrahedral(self, atom): def tetrahedral(self, atom):
self.display('TETRAHEDRAL - %d bonded atoms'%(len(atom.bonded_atoms))) debug('TETRAHEDRAL - %d bonded atoms'%(len(atom.bonded_atoms)))
rot_angle = math.radians(109.5) rot_angle = math.radians(109.5)
# sanity check # sanity check
@@ -399,7 +400,7 @@ class Protonate:
i+=1 i+=1
self.display('added',new_H, 'to',atom) debug('added',new_H, 'to',atom)
return return
def set_bond_distance(self, a, element): def set_bond_distance(self, a, element):
@@ -407,31 +408,23 @@ class Protonate:
if element in list(self.bond_lengths.keys()): if element in list(self.bond_lengths.keys()):
d = self.bond_lengths[element] d = self.bond_lengths[element]
else: else:
print('WARNING: Bond length for %s not found, using the standard value of %f'%(element, d)) warning('Bond length for %s not found, using the standard value of %f' % (element, d))
a = a.rescale(d) a = a.rescale(d)
return a return a
def display(self,*text):
if self.verbose:
s = ''
for t in text:
s+='%s '%t
print(s)
return
if __name__ == '__main__': if __name__ == '__main__':
import protein, pdb, sys,os import protein, pdb, sys,os
arguments = sys.argv arguments = sys.argv
if len(arguments) != 2: if len(arguments) != 2:
print('Usage: protonate.py <pdb_file>') info('Usage: protonate.py <pdb_file>')
sys.exit(0) sys.exit(0)
filename = arguments[1] filename = arguments[1]
if not os.path.isfile(filename): if not os.path.isfile(filename):
print('Error: Could not find \"%s\"'%filename) info('Error: Could not find \"%s\"' % filename)
sys.exit(1) sys.exit(1)

View File

@@ -1,6 +1,7 @@
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
import math import math
from propka.lib import info
class vector: class vector:
""" Vector """ """ Vector """
@@ -47,7 +48,7 @@ class vector:
elif type(other) in [int, float]: elif type(other) in [int, float]:
return vector(self.x * other, self.y * other, self.z * other) return vector(self.x * other, self.y * other, self.z * other)
else: else:
print('%s not supported'%type(other)) info('%s not supported' % type(other))
raise TypeError raise TypeError
def __rmul__(self,other): def __rmul__(self,other):
@@ -235,7 +236,7 @@ class multi_vector:
atom2.setConfiguration(key) atom2.setConfiguration(key)
v = vector(atom1=atom1, atom2=atom2) v = vector(atom1=atom1, atom2=atom2)
self.vectors.append(v) self.vectors.append(v)
#print(key,v) #info(key,v)
return return
def __getattribute__(self,name): def __getattribute__(self,name):
@@ -252,7 +253,7 @@ class multi_vector:
def do_job(self, job): def do_job(self, job):
#print(job) #info(job)
self.res = multi_vector() self.res = multi_vector()
for i in range(len(self.vectors)): for i in range(len(self.vectors)):
self.res.vectors.append(eval('self.vectors[%d].%s()'%(i,job))) self.res.vectors.append(eval('self.vectors[%d].%s()'%(i,job)))

View File

@@ -4,6 +4,7 @@ import math
import sys, os import sys, os
import propka.lib as lib import propka.lib as lib
from propka.lib import info, warning
import propka.calculations as calculations import propka.calculations as calculations
import propka.parameters import propka.parameters
@@ -109,7 +110,7 @@ class simple_hb(version_A):
def __init__(self, parameters): def __init__(self, parameters):
# set the calculation rutines used in this version # set the calculation rutines used in this version
version_A.__init__(self, parameters) version_A.__init__(self, parameters)
print('Using simple hb model') info('Using simple hb model')
return return
def get_hydrogen_bond_parameters(self, atom1, atom2): def get_hydrogen_bond_parameters(self, atom1, atom2):
@@ -126,7 +127,7 @@ class element_based_ligand_interactions(version_A):
def __init__(self, parameters): def __init__(self, parameters):
# set the calculation rutines used in this version # set the calculation rutines used in this version
version_A.__init__(self, parameters) version_A.__init__(self, parameters)
print('Using detailed SC model!') info('Using detailed SC model!')
return return
def get_hydrogen_bond_parameters(self, atom1, atom2): def get_hydrogen_bond_parameters(self, atom1, atom2):
@@ -168,8 +169,8 @@ class element_based_ligand_interactions(version_A):
res = self.parameters.hydrogen_bonds.get_value(elements[0], elements[1]) res = self.parameters.hydrogen_bonds.get_value(elements[0], elements[1])
if not res: if not res:
print('Could not determine backbone interaction parameters for:', info('Could not determine backbone interaction parameters for:',
backbone_atom,atom) backbone_atom, atom)
return return