diff --git a/propka/calculations.py b/propka/calculations.py index b507764..c7c84af 100644 --- a/propka/calculations.py +++ b/propka/calculations.py @@ -242,8 +242,8 @@ def add_trp_hydrogen(residue): elif atom.name == "CE2": ce_atom = atom if (cd_atom is None) or (ne_atom is None) or (ce_atom is None): - errstr = "Unable to find all atoms for %s %s" % (residue[0].res_name, - residue[0].res_num) + errstr = "Unable to find all atoms for %s %s" % ( + residue[0].res_name, residue[0].res_num) raise ValueError(errstr) he_atom = protonate_sp2(cd_atom, ne_atom, ce_atom) he_atom.name = "HNE" @@ -269,8 +269,8 @@ def add_amd_hydrogen(residue): or (atom.res_name == "ASN" and atom.name == "ND2")): n_atom = atom if (c_atom is None) or (o_atom is None) or (n_atom is None): - errstr = "Unable to find all atoms for %s %s" % (residue[0].res_name, - residue[0].res_num) + errstr = "Unable to find all atoms for %s %s" % ( + residue[0].res_name, residue[0].res_num) raise ValueError(errstr) h1_atom = protonate_direction(n_atom, o_atom, c_atom) h1_atom.name = "HN1" @@ -604,8 +604,8 @@ def hydrogen_bond_interaction(group1, group2, version): atoms2 = group2.get_interaction_atoms(group1) [closest_atom1, dist, closest_atom2] = get_smallest_distance(atoms1, atoms2) if None in [closest_atom1, closest_atom2]: - 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 # get the parameters [dpka_max, cutoff] = version.get_hydrogen_bond_parameters(closest_atom1, diff --git a/propka/conformation_container.py b/propka/conformation_container.py index e81b8ac..f86b739 100644 --- a/propka/conformation_container.py +++ b/propka/conformation_container.py @@ -575,9 +575,11 @@ class ConformationContainer: def __str__(self): """String that lists statistics of atoms and groups.""" - str_ = ( - 'Conformation container %s with %d atoms and %d groups' - % (self.name, len(self), len(self.groups))) + fmt = ( + "Conformation container {name} with {natoms:d} atoms and " + "{ngroups:d} groups") + str_ = fmt.format( + name=self.name, natoms=len(self), ngroups=len(self.groups)) return str_ def __len__(self): diff --git a/propka/coupled_groups.py b/propka/coupled_groups.py index 7220304..942fed8 100644 --- a/propka/coupled_groups.py +++ b/propka/coupled_groups.py @@ -146,31 +146,27 @@ class NonCovalentlyCoupledGroups: """ self.parameters = conformation.parameters if verbose: - info('') - info(' Warning: When using the -d option, pKa values based on ' - '\'swapped\' interactions') - info(' will be writting to the output .pka file') - info('') - info('-' * 103) - info(' Detecting non-covalently coupled residues') - info('-' * 103) - info(' Maximum pKa difference: %4.2f pKa units' - % self.parameters.max_intrinsic_pka_diff) - info(' Minimum interaction energy: %4.2f pKa units' - % self.parameters.min_interaction_energy) - info(' Maximum free energy diff.: %4.2f pKa units' - % self.parameters.max_free_energy_diff) - info(' Minimum swap pKa shift: %4.2f pKa units' - % self.parameters.min_swap_pka_shift) - info(' pH: %6s ' - % str(self.parameters.pH)) - info(' Reference: %s' - % self.parameters.reference) - info(' Min pKa: %4.2f' - % self.parameters.min_pka) - info(' Max pKa: %4.2f' - % self.parameters.max_pka) - info('') + info_fmt = ( + '\n' + ' Warning: When using the -d option, pKa values based on \n' + '\'swapped\' interactions\n' + ' will be writting to the output .pka file\n' + '\n' + '{sep}\n' + '\n' + ' Detecting non-covalently coupled residues\n' + '{sep}\n' + ' Maximum pKa difference: {c.max_intrinsic_pka_diff:>4.2f} pKa units\n' + ' Minimum interaction energy: {c.min_interaction_energy:>4.2f} pKa units\n' + ' Maximum free energy diff.: {c.max_free_energy_diff:>4.2f} pKa units\n' + ' Minimum swap pKa shift: {c.min_swap_pka_shift:>4.2f} pKa units\n' + ' pH: {c.pH:>6} \n' + ' Reference: {c.reference}\n' + ' Min pKa: {c.min_pka:>4.2f}\n' + ' Max pKa: {c.max_pka:>4.2f}\n' + '\n') + sep = "-" * 103 + info(info_fmt.format(sep=sep, c=self)) # find coupled residues titratable_groups = conformation.get_titratable_groups() if not conformation.non_covalently_coupled_groups: @@ -364,20 +360,24 @@ class NonCovalentlyCoupledGroups: formatted string with information. """ str_ = ( - """ %s and %s coupled (prot.state): %5.2f - Energy levels: %6.2f, %6.2f (difference: %6.2f) at pH %6.2f - Interaction energy: %6.2f - Intrinsic pka's: %6.2f, %6.2f (difference: %6.2f) - Swapped pKa's: %6.2f, %6.2f (difference: %6.2f, %6.2f)""" - % ( - group1.label, group2.label, data['coupling_factor'], - data['default_energy'], data['swapped_energy'], - data['default_energy'] - data['swapped_energy'], - data['pH'], data['interaction_energy'], - group1.intrinsic_pka, group2.intrinsic_pka, - group1.intrinsic_pka-group2.intrinsic_pka, - data['swapped_pka1'], data['swapped_pka2'], - data['pka_shift1'], data['pka_shift2'])) + " {label1} and {label2} coupled (prot.state): {coupl_fact:>5.2f}\n" + " Energy levels: {def_energy:>6.2f}, {swap_energy:>6.2f} " + "(difference: {diff_energy:>6.2f}) at pH {ph:>6.2f}\n" + " Interaction energy: {int_energy:>6.2f}\n" + " Intrinsic pka's: {pka1:>6.2f}, {pka2:>6.2f} " + "(difference: {diff_pka:>6.2f})\n" + " Swapped pKa's: {swap1:>6.2f}, {swap2:>6.2f} " + "(difference: {shift1:>6.2f}, {shift2:>6.2f})" + ).format( + label1=group1.label, label2=group2.label, + coupl_fact=data['coupling_factor'], def_energy=data['default_energy'], + swap_energy=data['swapped_energy'], + diff_energy=data['default_energy']-data['swapped_energy'], ph=data['pH'], + int_energy=data['interaction_energy'], pka1=group1.intrinsic_pka, + pka2=group2.intrinsic_pka, + diff_pka=group1.intrinsic_pka-group2.intrinsic_pka, + swap1=data['swapped_pka1'], swap2=data['swapped_pka2'], + shift1=data['pka_shift1'], shift2=data['pka_shift2']) return str_ diff --git a/propka/group.py b/propka/group.py index 24cb852..9b5c445 100644 --- a/propka/group.py +++ b/propka/group.py @@ -76,15 +76,18 @@ class Group: if self.atom.terminal: self.residue_type = self.atom.terminal if self.atom.type == 'atom': - self.label = '%-3s%4d%2s' % (self.residue_type, atom.res_num, - atom.chain_id) + fmt = "{g.residue_type:<3s}{a.res_num:>4d}{a.chain_id:>2s}" + self.label = fmt.format(g=self, a=atom) elif self.atom.res_name in ['DA ', 'DC ', 'DG ', 'DT ']: - self.label = '%1s%1s%1s%4d%2s' % ( - self.residue_type[1], atom.element, - atom.name.replace('\'', '')[-1], atom.res_num, atom.chain_id) + fmt = "{type:1s}{elem:1s}{name:1s}{res_num:>4d}{chain:>2s}" + self.label = fmt.format( + type=self.residue_type[1], elem=atom.element, + name=atom.name.replace('\'', '')[-1], res_num=atom.res_num, + chain=atom.chain_id) else: - self.label = '%-3s%4s%2s' % ( - self.residue_type, atom.name, atom.chain_id) + fmt = "{type:<3s}{name:>4s}{chain:>2s}" + self.label = fmt.format( + type=self.residue_type, name=atom.name, chain=atom.chain_id) # container for squared distances self.squared_distances = {} @@ -545,11 +548,10 @@ class Group: penalty = ( ' NB: Discarded due to coupling with %s' % self.coupled_titrating_group.label) - str_ = ( - " %9s %8.2lf %10.2lf %18s %s\n" - % (self.label, self.pka_value, self.model_pka, ligand_type, - penalty)) - return str_ + fmt = ( + " {g.label:>9s} {g.pka_value:8.2f} {g.model_pka:10.2f} " + "{type:>18s} {penalty:s}\n") + return fmt.format(g=self, type=ligand_type, penalty=penalty) def __str__(self): return 'Group (%s) for %s' % (self.type, self.atom) diff --git a/propka/ligand_pka_values.py b/propka/ligand_pka_values.py index ae38c3f..43e9dac 100644 --- a/propka/ligand_pka_values.py +++ b/propka/ligand_pka_values.py @@ -113,7 +113,7 @@ class LigandPkaValues: # do one molecule at the time so we don't confuse marvin molecules = propka.lib.split_atoms_into_molecules(atoms) for i, molecule in enumerate(molecules): - filename = '%s_%d.mol2'%(name, i+1) + filename = '%s_%d.mol2' % (name, i+1) self.get_marvin_pkas_for_molecule( molecule, filename=filename, reuse=reuse, num_pkas=num_pkas, min_ph=min_ph, max_ph=max_ph) @@ -141,8 +141,12 @@ class LigandPkaValues: warning(errstr) propka.pdb.write_mol2_for_atoms(atoms, filename) # Marvin calculate pKa values - options = ('pka -a %d -b %d --min %f --max %f -d large' - % (num_pkas, num_pkas, min_ph, max_ph)) + fmt = ( + 'pka -a {num1} -b {num2} --min {min_ph} ' + '--max {max_ph} -d large') + options = ( + fmt.format( + num1=num_pkas, num2=num_pkas, min_ph=min_ph, max_ph=max_ph)) (output, errors) = subprocess.Popen( [self.cxcalc, filename]+options.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() diff --git a/propka/output.py b/propka/output.py index be0e353..d2ed804 100644 --- a/propka/output.py +++ b/propka/output.py @@ -270,9 +270,10 @@ def get_charge_profile_section(protein, conformation='AVR', _=None): if profile is None: str_ += "Could not determine charge profile\n" else: - str_ += "%6s%10s%8s\n" % ("pH", "unfolded", "folded") + str_ += ' pH unfolded folded\n' for (ph, q_mod, q_pro) in profile: - str_ += "%6.2lf%10.2lf%8.2lf\n" % (ph, q_mod, q_pro) + str_ += "{ph:6.2f}{qm:10.2f}{qp:8.2f}\n".format( + ph=ph, qm=q_mod, qp=q_pro) pi_pro, pi_mod = protein.get_pi(conformation=conformation) if pi_pro is None or pi_mod is None: str_ += "Could not determine the pI\n\n" diff --git a/propka/parameters.py b/propka/parameters.py index 9210081..4bdff07 100644 --- a/propka/parameters.py +++ b/propka/parameters.py @@ -225,14 +225,17 @@ class Parameters: 'NAM': ['AMD'], 'N1': [], 'O2': []} for group1 in agroups: for group2 in lgroups: - interaction = '%3s %3s %1s %4s %4s' % ( - group1, group2, self.interaction_matrix[group1][group2], - self.sidechain_cutoffs.get_value(group1, group2)[0], - self.sidechain_cutoffs.get_value(group1, group2)[1]) + fmt = "{grp1:>3s} {grp2:>3s} {mat:1s} {val1:4} {val2:4}" + interaction = fmt.format( + grp1=group1, grp2=group2, + mat=self.interaction_matrix[group1][group2], + val1=self.sidechain_cutoffs.get_value(group1, group2)[0], + val2=self.sidechain_cutoffs.get_value(group1, group2)[1]) map_interaction = '' if group2 in map_: for val in map_[group2]: - map_interaction += '|%3s %3s %1s %4s %4s' % ( + fmt = "|{grp1:>3s} {grp2:>3s} {mat:1s} {val1:4} {val2:4}" + map_interaction += fmt.format( group1, val, self.interaction_matrix[group1][val], self.sidechain_cutoffs.get_value(group1, val)[0], self.sidechain_cutoffs.get_value(group1, val)[1]) @@ -334,13 +337,14 @@ Group1 & Group2 & Interaction & c1 &c2 \\\\ if (self.sidechain_cutoffs.get_value(group1, group2) == self.sidechain_cutoffs.default): continue - str_ += ('%3s & %3s & %1s & %4s & %4s\\\\ \n' - % (group1, group2, - self.interaction_matrix[group1][group2], - self.sidechain_cutoffs.get_value(group1, - group2)[0], - self.sidechain_cutoffs.get_value(group1, - group2)[1])) + fmt = ( + "{grp1:>3s} & {grp2:>3s} & {mat:1s} & {val1:4} & " + "{val2:4}\\\\ \n") + str_ += fmt.format( + group1, group2, + self.interaction_matrix[group1][group2], + self.sidechain_cutoffs.get_value(group1, group2)[0], + self.sidechain_cutoffs.get_value(group1, group2)[1]) if group1 == group2: break str_ += ' \\end{longtable}\n'