def trigonal(self, atom): """Add hydrogens in trigonal geometry. Args: atom: atom to protonate """ debug('TRIGONAL - {0:d} bonded atoms'.format(len(atom.bonded_atoms))) rot_angle = math.radians(120.0) cvec = Vector(atom1=atom) # 0 bonds if len(atom.bonded_atoms) == 0: pass # 1 bond if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first one avec = Vector(atom1=atom, atom2=atom.bonded_atoms[0]) # use plane of bonded trigonal atom - e.g. arg self.set_steric_number_and_lone_pairs(atom.bonded_atoms[0]) if (atom.bonded_atoms[0].steric_number == 3 and len(atom.bonded_atoms[0].bonded_atoms) > 1): # use other atoms bonded to the neighbour to establish the # plane, if possible other_atom_indices = [] for i, bonded_atom in enumerate( atom.bonded_atoms[0].bonded_atoms): if bonded_atom != atom: other_atom_indices.append(i) vec1 = Vector(atom1=atom, atom2=atom.bonded_atoms[0]) vec2 = Vector(atom1=atom.bonded_atoms[0], atom2=atom.bonded_atoms[0].bonded_atoms[ other_atom_indices[0]]) axis = vec1**vec2 # this is a trick to make sure that the order of atoms doesn't # influence the final postions of added protons if len(other_atom_indices) > 1: vec3 = Vector(atom1=atom.bonded_atoms[0], atom2=atom.bonded_atoms[0].bonded_atoms[ other_atom_indices[1]]) axis2 = vec1**vec3 if axis * axis2 > 0: axis = axis + axis2 else: axis = axis - axis2 else: axis = avec.orthogonal() avec = rotate_vector_around_an_axis(rot_angle, axis, avec) avec = self.set_bond_distance(avec, atom.element) self.add_proton(atom, cvec + avec) # 2 bonds if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first two avec1 = Vector(atom1=atom, atom2=atom.bonded_atoms[0]).rescale(1.0) avec2 = Vector(atom1=atom, atom2=atom.bonded_atoms[1]).rescale(1.0) new_a = -avec1 - avec2 new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, cvec + new_a)
def add_protons(self, atom): # decide which method to use debug('PROTONATING',atom) if atom.steric_number in list(self.protonation_methods.keys()): self.protonation_methods[atom.steric_number](atom) else: warning('Do not have a method for protonating', atom, '(steric number: %d)' % atom.steric_number) return
def add_protons(self, atom): # decide which method to use debug('PROTONATING', atom) if atom.steric_number in list(self.protonation_methods.keys()): self.protonation_methods[atom.steric_number](atom) else: warning('Do not have a method for protonating', atom, '(steric number: %d)' % atom.steric_number) return
def add_protons(self, atom): """Add protons to atom. Args: atom: atom for calculation """ # decide which method to use debug('PROTONATING', atom) if atom.steric_number in list(self.protonation_methods.keys()): self.protonation_methods[atom.steric_number](atom) else: warning('Do not have a method for protonating', atom, '(steric number: {0:d})'.format(atom.steric_number))
def protonate(self, molecules): """Protonate all atoms in the molecular container. Args: molecules: molecular containers """ debug('----- Protonation started -----') # Remove all currently present hydrogen atoms self.remove_all_hydrogen_atoms(molecules) # protonate all atoms for name in molecules.conformation_names: non_h_atoms = ( molecules.conformations[name].get_non_hydrogen_atoms()) for atom in non_h_atoms: self.protonate_atom(atom)
def tetrahedral(self, atom): debug('TETRAHEDRAL - %d bonded atoms' % (len(atom.bonded_atoms))) rot_angle = math.radians(109.5) # sanity check # if atom.number_of_protons_to_add + len(atom.bonded_atoms) != 4: # self.display 'Error: Attempting tetrahedral structure with %d bonds'%(atom.number_of_protons_to_add + # len(atom.bonded_atoms)) c = vector(atom1=atom) # 0 bonds if len(atom.bonded_atoms) == 0: pass # 1 bond if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first one a = vector(atom1=atom, atom2=atom.bonded_atoms[0]) axis = a.orthogonal() a = rotate_vector_around_an_axis(rot_angle, axis, a) a = self.set_bond_distance(a, atom.element) self.add_proton(atom, c + a) # 2 bonds if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first two a1 = vector(atom1=atom, atom2=atom.bonded_atoms[0]).rescale(1.0) a2 = vector(atom1=atom, atom2=atom.bonded_atoms[1]).rescale(1.0) axis = a1 + a2 new_a = rotate_vector_around_an_axis(math.radians(90), axis, -a1) new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, c + new_a) # 3 bonds if len(atom.bonded_atoms) == 3 and atom.number_of_protons_to_add > 0: a1 = vector(atom1=atom, atom2=atom.bonded_atoms[0]).rescale(1.0) a2 = vector(atom1=atom, atom2=atom.bonded_atoms[1]).rescale(1.0) a3 = vector(atom1=atom, atom2=atom.bonded_atoms[2]).rescale(1.0) new_a = -a1 - a2 - a3 new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, c + new_a) return
def tetrahedral(self, atom): debug('TETRAHEDRAL - %d bonded atoms'%(len(atom.bonded_atoms))) rot_angle = math.radians(109.5) # sanity check # if atom.number_of_protons_to_add + len(atom.bonded_atoms) != 4: # self.display 'Error: Attempting tetrahedral structure with %d bonds'%(atom.number_of_protons_to_add + # len(atom.bonded_atoms)) c = vector(atom1 = atom) # 0 bonds if len(atom.bonded_atoms) == 0: pass # 1 bond if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first one a = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]) axis = a.orthogonal() a = rotate_vector_around_an_axis(rot_angle, axis, a) a = self.set_bond_distance(a, atom.element) self.add_proton(atom, c+a) # 2 bonds if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first two a1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]).rescale(1.0) a2 = vector(atom1 = atom, atom2 = atom.bonded_atoms[1]).rescale(1.0) axis = a1 + a2 new_a = rotate_vector_around_an_axis(math.radians(90), axis, -a1) new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, c+new_a) # 3 bonds if len(atom.bonded_atoms) == 3 and atom.number_of_protons_to_add > 0: a1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]).rescale(1.0) a2 = vector(atom1 = atom, atom2 = atom.bonded_atoms[1]).rescale(1.0) a3 = vector(atom1 = atom, atom2 = atom.bonded_atoms[2]).rescale(1.0) new_a = -a1-a2-a3 new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, c+new_a) return
def add_proton(atom, position): """Add a proton to an atom at a specific position. Args: atom: atom to protonate position: position for proton """ # Create the new proton new_h = propka.atom.Atom() new_h.set_property( numb=None, name='H{0:s}'.format(atom.name[1:]), res_name=atom.res_name, chain_id=atom.chain_id, res_num=atom.res_num, x=round(position.x, 3), # round of to three decimal points to # avoid round-off differences in input file y=round(position.y, 3), z=round(position.z, 3), occ=None, beta=None) new_h.element = 'H' new_h.type = atom.type new_h.bonded_atoms = [atom] new_h.charge = 0 new_h.steric_number = 0 new_h.number_of_lone_pairs = 0 new_h.number_of_protons_to_add = 0 new_h.num_pi_elec_2_3_bonds = 0 new_h.is_protonates = True atom.bonded_atoms.append(new_h) atom.number_of_protons_to_add -= 1 atom.conformation_container.add_atom(new_h) # update names of all protons on this atom new_h.residue_label = "{0:<3s}{1:>4d}{2:>2s}".format( new_h.name, new_h.res_num, new_h.chain_id) no_protons = atom.count_bonded_elements('H') if no_protons > 1: i = 1 for proton in atom.get_bonded_elements('H'): proton.name = 'H{0:s}{1:d}'.format(atom.name[1:], i) proton.residue_label = "{0:<3s}{1:>4d}{2:>2s}".format( proton.name, proton.res_num, proton.chain_id) i += 1 debug('added', new_h, 'to', atom)
def protonate(self, molecules): """ Will protonate all atoms in the molecular container """ debug('----- Protonation started -----') # Remove all currently present hydrogen atoms self.remove_all_hydrogen_atoms(molecules) # protonate all atoms for name in molecules.conformation_names: non_H_atoms = molecules.conformations[name].get_non_hydrogen_atoms() for atom in non_H_atoms: self.protonate_atom(atom) # fix hydrogen names #self.set_proton_names(non_H_atoms) return
def set_charge(self, atom): # atom is a protein atom if atom.type == 'atom': key = '%3s-%s' % (atom.resName, atom.name) if atom.terminal: debug(atom.terminal) key = atom.terminal if key in list(self.standard_charges.keys()): atom.charge = self.standard_charges[key] debug('Charge', atom, atom.charge) atom.charge_set = True # atom is a ligand atom elif atom.type == 'hetatm': if atom.sybyl_type in list(self.sybyl_charges.keys()): atom.charge = self.sybyl_charges[atom.sybyl_type] atom.sybyl_type = atom.sybyl_type.replace('-', '') atom.charge_set = True return
def set_charge(self, atom): # atom is a protein atom if atom.type=='atom': key = '%3s-%s'%(atom.resName, atom.name) if atom.terminal: debug(atom.terminal) key=atom.terminal if key in list(self.standard_charges.keys()): atom.charge = self.standard_charges[key] debug('Charge', atom, atom.charge) atom.charge_set = True # atom is a ligand atom elif atom.type=='hetatm': if atom.sybyl_type in list(self.sybyl_charges.keys()): atom.charge = self.sybyl_charges[atom.sybyl_type] atom.sybyl_type = atom.sybyl_type.replace('-','') atom.charge_set = True return
def protonate(self, molecules): """ Will protonate all atoms in the molecular container """ debug('----- Protonation started -----') # Remove all currently present hydrogen atoms self.remove_all_hydrogen_atoms(molecules) # protonate all atoms for name in molecules.conformation_names: non_H_atoms = molecules.conformations[name].get_non_hydrogen_atoms( ) for atom in non_H_atoms: self.protonate_atom(atom) # fix hydrogen names #self.set_proton_names(non_H_atoms) return
def add_proton(self, atom, position): # Create the new proton new_H = propka.atom.Atom() new_H.setProperty( numb=None, name='H%s' % atom.name[1:], resName=atom.resName, chainID=atom.chainID, resNumb=atom.resNumb, x=round(position.x, 3), # round of to three digimal points y=round(position.y, 3), # to avoid round-off differences z=round(position.z, 3), # when input file occ=None, beta=None) new_H.element = 'H' new_H.type = atom.type new_H.bonded_atoms = [atom] new_H.charge = 0 new_H.steric_number = 0 new_H.number_of_lone_pairs = 0 new_H.number_of_protons_to_add = 0 new_H.number_of_pi_electrons_in_double_and_triple_bonds = 0 new_H.is_protonates = True atom.bonded_atoms.append(new_H) atom.number_of_protons_to_add -= 1 atom.conformation_container.add_atom(new_H) # update names of all protons on this atom new_H.residue_label = "%-3s%4d%2s" % (new_H.name, new_H.resNumb, new_H.chainID) no_protons = atom.count_bonded_elements('H') if no_protons > 1: i = 1 for proton in atom.get_bonded_elements('H'): proton.name = 'H%s%d' % (atom.name[1:], i) proton.residue_label = "%-3s%4d%2s" % ( proton.name, proton.resNumb, proton.chainID) i += 1 debug('added', new_H, 'to', atom) return
def add_proton(self, atom, position): # Create the new proton new_H = propka.atom.Atom() new_H.setProperty(numb = None, name = 'H%s'%atom.name[1:], resName = atom.resName, chainID = atom.chainID, resNumb = atom.resNumb, x = round(position.x,3), # round of to three digimal points y = round(position.y,3), # to avoid round-off differences z = round(position.z,3), # when input file occ = None, beta = None) new_H.element = 'H' new_H.type = atom.type new_H.bonded_atoms = [atom] new_H.charge = 0 new_H.steric_number = 0 new_H.number_of_lone_pairs = 0 new_H.number_of_protons_to_add = 0 new_H.number_of_pi_electrons_in_double_and_triple_bonds = 0 new_H.is_protonates = True atom.bonded_atoms.append(new_H) atom.number_of_protons_to_add -=1 atom.conformation_container.add_atom(new_H) # update names of all protons on this atom new_H.residue_label = "%-3s%4d%2s" % (new_H.name,new_H.resNumb, new_H.chainID) no_protons = atom.count_bonded_elements('H') if no_protons > 1: i = 1 for proton in atom.get_bonded_elements('H'): proton.name = 'H%s%d'%(atom.name[1:],i) proton.residue_label = "%-3s%4d%2s" % (proton.name,proton.resNumb, proton.chainID) i+=1 debug('added',new_H, 'to',atom) return
def tetrahedral(self, atom): """Protonate atom in tetrahedral geometry. Args: atom: atom to protonate. """ debug('TETRAHEDRAL - {0:d} bonded atoms'.format(len( atom.bonded_atoms))) # TODO - might be good to move tetrahedral angle to constant rot_angle = math.radians(109.5) cvec = Vector(atom1=atom) # 0 bonds if len(atom.bonded_atoms) == 0: pass # 1 bond if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first one avec = Vector(atom1=atom, atom2=atom.bonded_atoms[0]) axis = avec.orthogonal() avec = rotate_vector_around_an_axis(rot_angle, axis, avec) avec = self.set_bond_distance(avec, atom.element) self.add_proton(atom, cvec + avec) # 2 bonds if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first two avec1 = Vector(atom1=atom, atom2=atom.bonded_atoms[0]).rescale(1.0) avec2 = Vector(atom1=atom, atom2=atom.bonded_atoms[1]).rescale(1.0) axis = avec1 + avec2 new_a = rotate_vector_around_an_axis(math.radians(90), axis, -avec1) new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, cvec + new_a) # 3 bonds if len(atom.bonded_atoms) == 3 and atom.number_of_protons_to_add > 0: avec1 = Vector(atom1=atom, atom2=atom.bonded_atoms[0]).rescale(1.0) avec2 = Vector(atom1=atom, atom2=atom.bonded_atoms[1]).rescale(1.0) avec3 = Vector(atom1=atom, atom2=atom.bonded_atoms[2]).rescale(1.0) new_a = -avec1 - avec2 - avec3 new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, cvec + new_a)
def set_charge(self, atom): """Set charge for atom. Args: atom: atom to be charged """ # atom is a protein atom if atom.type == 'atom': key = '{0:3s}-{1:s}'.format(atom.res_name, atom.name) if atom.terminal: debug(atom.terminal) key = atom.terminal if key in self.standard_charges: atom.charge = self.standard_charges[key] debug('Charge', atom, atom.charge) atom.charge_set = True # atom is a ligand atom elif atom.type == 'hetatm': if atom.sybyl_type in self.sybyl_charges: atom.charge = self.sybyl_charges[atom.sybyl_type] atom.sybyl_type = atom.sybyl_type.replace('-', '') atom.charge_set = True
def trigonal(self, atom): debug('TRIGONAL - %d bonded atoms' % (len(atom.bonded_atoms))) rot_angle = math.radians(120.0) c = vector(atom1=atom) # 0 bonds if len(atom.bonded_atoms) == 0: pass # 1 bond if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first one a = vector(atom1=atom, atom2=atom.bonded_atoms[0]) # use plane of bonded trigonal atom - e.g. arg self.set_steric_number_and_lone_pairs(atom.bonded_atoms[0]) if atom.bonded_atoms[0].steric_number == 3 and len( atom.bonded_atoms[0].bonded_atoms) > 1: # use other atoms bonded to the neighbour to establish the plane, if possible other_atom_indices = [] for i in range(len(atom.bonded_atoms[0].bonded_atoms)): if atom.bonded_atoms[0].bonded_atoms[i] != atom: other_atom_indices.append(i) v1 = vector(atom1=atom, atom2=atom.bonded_atoms[0]) v2 = vector(atom1=atom.bonded_atoms[0], atom2=atom.bonded_atoms[0].bonded_atoms[ other_atom_indices[0]]) axis = v1**v2 # this is a trick to make sure that the order of atoms doesn't influence # the final postions of added protons if len(other_atom_indices) > 1: v3 = vector(atom1=atom.bonded_atoms[0], atom2=atom.bonded_atoms[0].bonded_atoms[ other_atom_indices[1]]) axis2 = v1**v3 if axis * axis2 > 0: axis = axis + axis2 else: axis = axis - axis2 else: axis = a.orthogonal() a = rotate_vector_around_an_axis(rot_angle, axis, a) a = self.set_bond_distance(a, atom.element) self.add_proton(atom, c + a) # 2 bonds if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first two a1 = vector(atom1=atom, atom2=atom.bonded_atoms[0]).rescale(1.0) a2 = vector(atom1=atom, atom2=atom.bonded_atoms[1]).rescale(1.0) new_a = -a1 - a2 new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, c + new_a) return
def set_steric_number_and_lone_pairs(self, atom): # If we already did this, there is no reason to do it again if atom.steric_number_and_lone_pairs_set: return debug('='*10) debug('Setting steric number and lone pairs for',atom) # costumly set the N backbone atoms up for peptide bond trigonal planer shape #if atom.name == 'N' and len(atom.bonded_atoms) == 2: # atom.steric_number = 3 # atom.number_of_lone_pairs = 0 # self.display 'Peptide bond: steric number is %d and number of lone pairs is %s'%(atom.steric_number, # atom.number_of_lone_pairs) # return atom.steric_number = 0 debug('%65s: %4d'%('Valence electrons',self.valence_electrons[atom.element])) atom.steric_number += self.valence_electrons[atom.element] debug('%65s: %4d'%('Number of bonds',len(atom.bonded_atoms))) atom.steric_number += len(atom.bonded_atoms) debug('%65s: %4d'%('Number of hydrogen atoms to add',atom.number_of_protons_to_add)) atom.steric_number += atom.number_of_protons_to_add 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 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 debug('%65s: %4d'%('Number of donated co-ordinated bonds',0)) atom.steric_number += 0 debug('%65s: %4.1f'%('Charge(-)',atom.charge)) atom.steric_number -= atom.charge 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 debug('-'*70) debug('%65s: %4d'%('Steric number',atom.steric_number)) debug('%65s: %4d'%('Number of lone pairs',atom.number_of_lone_pairs)) atom.steric_number_and_lone_pairs_set = True return
def trigonal(self, atom): debug('TRIGONAL - %d bonded atoms'%(len(atom.bonded_atoms))) rot_angle = math.radians(120.0) c = vector(atom1 = atom) # 0 bonds if len(atom.bonded_atoms) == 0: pass # 1 bond if len(atom.bonded_atoms) == 1 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first one a = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]) # use plane of bonded trigonal atom - e.g. arg self.set_steric_number_and_lone_pairs(atom.bonded_atoms[0]) if atom.bonded_atoms[0].steric_number == 3 and len(atom.bonded_atoms[0].bonded_atoms)>1: # use other atoms bonded to the neighbour to establish the plane, if possible other_atom_indices = [] for i in range(len(atom.bonded_atoms[0].bonded_atoms)): if atom.bonded_atoms[0].bonded_atoms[i] != atom: other_atom_indices.append(i) v1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]) v2 = vector(atom1 = atom.bonded_atoms[0], atom2 = atom.bonded_atoms[0].bonded_atoms[other_atom_indices[0]]) axis = v1**v2 # this is a trick to make sure that the order of atoms doesn't influence # the final postions of added protons if len(other_atom_indices)>1: v3 = vector(atom1 = atom.bonded_atoms[0], atom2 = atom.bonded_atoms[0].bonded_atoms[other_atom_indices[1]]) axis2 = v1**v3 if axis * axis2>0: axis = axis+axis2 else: axis = axis-axis2 else: axis = a.orthogonal() a = rotate_vector_around_an_axis(rot_angle, axis, a) a = self.set_bond_distance(a, atom.element) self.add_proton(atom, c+a) # 2 bonds if len(atom.bonded_atoms) == 2 and atom.number_of_protons_to_add > 0: # Add another atom with the right angle to the first two a1 = vector(atom1 = atom, atom2 = atom.bonded_atoms[0]).rescale(1.0) a2 = vector(atom1 = atom, atom2 = atom.bonded_atoms[1]).rescale(1.0) new_a = -a1 - a2 new_a = self.set_bond_distance(new_a, atom.element) self.add_proton(atom, c+new_a) return
def set_steric_number_and_lone_pairs(self, atom): """Set steric number and lone pairs for atom. Args: atom: atom for calculation """ # If we already did this, there is no reason to do it again if atom.steric_num_lone_pairs_set: return debug('=' * 10) debug('Setting steric number and lone pairs for', atom) atom.steric_number = 0 debug('{0:>65s}: {1:>4d}'.format('Valence electrons', self.valence_electrons[atom.element])) atom.steric_number += self.valence_electrons[atom.element] debug('{0:>65s}: {1:>4d}'.format('Number of bonds', len(atom.bonded_atoms))) atom.steric_number += len(atom.bonded_atoms) debug('{0:>65s}: {1:>4d}'.format('Number of hydrogen atoms to add', atom.number_of_protons_to_add)) atom.steric_number += atom.number_of_protons_to_add debug('{0:>65s}: {1:>4d}'.format( 'Number of pi-electrons in double and triple bonds(-)', atom.num_pi_elec_2_3_bonds)) atom.steric_number -= atom.num_pi_elec_2_3_bonds debug('{0:>65s}: {1:>4d}'.format( 'Number of pi-electrons in conjugated double and triple bonds(-)', atom.num_pi_elec_conj_2_3_bonds)) atom.steric_number -= atom.num_pi_elec_conj_2_3_bonds debug('{0:>65s}: {1:>4d}'.format( 'Number of donated co-ordinated bonds', 0)) atom.steric_number += 0 debug('{0:>65s}: {1:>4.1f}'.format('Charge(-)', atom.charge)) atom.steric_number -= atom.charge 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) debug('-' * 70) debug('{0:>65s}: {1:>4d}'.format('Steric number', atom.steric_number)) debug('{0:>65s}: {1:>4d}'.format('Number of lone pairs', atom.number_of_lone_pairs)) atom.steric_num_lone_pairs_set = True
def set_number_of_protons_to_add(self, atom): """Set the number of protons to add to this atom. Args: atom: atom for calculation """ debug('*' * 10) debug('Setting number of protons to add for', atom) atom.number_of_protons_to_add = 8 debug(" 8") atom.number_of_protons_to_add -= self.valence_electrons[atom.element] debug('Valence electrons: {0:>4d}'.format( -self.valence_electrons[atom.element])) atom.number_of_protons_to_add -= len(atom.bonded_atoms) debug('Number of bonds: {0:>4d}'.format(-len(atom.bonded_atoms))) atom.number_of_protons_to_add -= atom.num_pi_elec_2_3_bonds debug('Pi electrons: {0:>4d}'.format(-atom.num_pi_elec_2_3_bonds)) atom.number_of_protons_to_add += int(atom.charge) debug('Charge: {0:>4.1f}'.format(atom.charge)) debug('-' * 10) debug(atom.number_of_protons_to_add)
def addDeterminants(iterative_interactions, version, options=None): """ The iterative pKa scheme. Later it is all added in 'calculateTotalPKA' """ # --- setup --- iteratives = [] done_group = [] # creating iterative objects with references to their real group counterparts for interaction in iterative_interactions: pair = interaction[0] for group in pair: if group in done_group: #print "done already" """ do nothing - already have an iterative object for this group """ else: newIterative = Iterative(group) iteratives.append(newIterative) done_group.append(group) # Initialize iterative scheme debug("\n --- pKa iterations (%d groups, %d interactions) ---" % (len(iteratives), len(iterative_interactions))) converged = False iteration = 0 # set non-iterative pka values as first step for itres in iteratives: itres.pKa_iter.append(itres.pKa_NonIterative) # --- starting pKa iterations --- while converged == False: # initialize pKa_new iteration += 1 for itres in iteratives: itres.determinants = { 'sidechain': [], 'backbone': [], 'coulomb': [] } itres.pKa_new = itres.pKa_NonIterative # Adding interactions to temporary determinant container for interaction in iterative_interactions: pair = interaction[0] values = interaction[1] annihilation = interaction[2] #print "len(interaction) = %d" % (len(interaction)) object1, object2 = findIterative(pair, iteratives) Q1 = object1.Q Q2 = object2.Q if Q1 < 0.0 and Q2 < 0.0: """ both are acids """ addIterativeAcidPair(object1, object2, interaction) elif Q1 > 0.0 and Q2 > 0.0: """ both are bases """ addIterativeBasePair(object1, object2, interaction) else: """ one of each """ addIterativeIonPair(object1, object2, interaction, version) # Calculating pKa_new values for itres in iteratives: for type in ['sidechain', 'backbone', 'coulomb']: for determinant in itres.determinants[type]: itres.pKa_new += determinant[1] # Check convergence converged = True for itres in iteratives: if itres.pKa_new == itres.pKa_old: itres.converged = True else: itres.converged = False converged = False # reset pKa_old & storing pKa_new in pKa_iter for itres in iteratives: itres.pKa_old = itres.pKa_new itres.pKa_iter.append(itres.pKa_new) if iteration == 10: info("did not converge in %d iterations" % (iteration)) break # --- Iterations finished --- # printing pKa iterations # formerly was conditioned on if options.verbosity >= 2 - now unnecessary str = "%12s" % (" ") for index in range(0, iteration + 1): str += "%8d" % (index) debug(str) for itres in iteratives: str = "%s " % (itres.label) for pKa in itres.pKa_iter: str += "%8.2lf" % (pKa) if itres.converged == False: str += " *" debug(str) # creating real determinants and adding them to group object for itres in iteratives: for type in ['sidechain', 'backbone', 'coulomb']: for interaction in itres.determinants[type]: #info('done',itres.group.label,interaction[0],interaction[1]) value = interaction[1] if value > 0.005 or value < -0.005: g = interaction[0] newDeterminant = Determinant(g, value) itres.group.determinants[type].append(newDeterminant)
def addDeterminants(iterative_interactions, version, options=None): """ The iterative pKa scheme. Later it is all added in 'calculateTotalPKA' """ # --- setup --- iteratives = [] done_group = [] # creating iterative objects with references to their real group counterparts for interaction in iterative_interactions: pair = interaction[0] for group in pair: if group in done_group: #print "done already" """ do nothing - already have an iterative object for this group """ else: newIterative = Iterative(group) iteratives.append(newIterative) done_group.append(group) # Initialize iterative scheme debug("\n --- pKa iterations (%d groups, %d interactions) ---" % (len(iteratives), len(iterative_interactions))) converged = False iteration = 0 # set non-iterative pka values as first step for itres in iteratives: itres.pKa_iter.append(itres.pKa_NonIterative) # --- starting pKa iterations --- while converged == False: # initialize pKa_new iteration += 1 for itres in iteratives: itres.determinants = {'sidechain':[],'backbone':[],'coulomb':[]} itres.pKa_new = itres.pKa_NonIterative # Adding interactions to temporary determinant container for interaction in iterative_interactions: pair = interaction[0] values = interaction[1] annihilation = interaction[2] #print "len(interaction) = %d" % (len(interaction)) object1, object2 = findIterative(pair, iteratives) Q1 = object1.Q Q2 = object2.Q if Q1 < 0.0 and Q2 < 0.0: """ both are acids """ addIterativeAcidPair(object1, object2, interaction) elif Q1 > 0.0 and Q2 > 0.0: """ both are bases """ addIterativeBasePair(object1, object2, interaction) else: """ one of each """ addIterativeIonPair(object1, object2, interaction, version) # Calculating pKa_new values for itres in iteratives: for type in ['sidechain','backbone','coulomb']: for determinant in itres.determinants[type]: itres.pKa_new += determinant[1] # Check convergence converged = True for itres in iteratives: if itres.pKa_new == itres.pKa_old: itres.converged = True else: itres.converged = False converged = False # reset pKa_old & storing pKa_new in pKa_iter for itres in iteratives: itres.pKa_old = itres.pKa_new itres.pKa_iter.append(itres.pKa_new) if iteration == 10: info("did not converge in %d iterations" % (iteration)) break # --- Iterations finished --- # printing pKa iterations # formerly was conditioned on if options.verbosity >= 2 - now unnecessary str = "%12s" % (" ") for index in range(0, iteration+1 ): str += "%8d" % (index) debug(str) for itres in iteratives: str = "%s " % (itres.label) for pKa in itres.pKa_iter: str += "%8.2lf" % (pKa) if itres.converged == False: str += " *" debug(str) # creating real determinants and adding them to group object for itres in iteratives: for type in ['sidechain','backbone','coulomb']: for interaction in itres.determinants[type]: #info('done',itres.group.label,interaction[0],interaction[1]) value = interaction[1] if value > 0.005 or value < -0.005: g = interaction[0] newDeterminant = Determinant(g, value) itres.group.determinants[type].append(newDeterminant)
def add_determinants(iterative_interactions, version, _=None): """Add determinants iteratively. The iterative pKa scheme. Later it is all added in 'calculateTotalPKA' Args: iterative_interactions: list of iterative interactions version: version object _: options object """ # --- setup --- iteratives = [] done_group = [] # create iterative objects with references to their real group counterparts for interaction in iterative_interactions: pair = interaction[0] for group in pair: if group in done_group: # do nothing - already have an iterative object for this group pass else: new_iterative = Iterative(group) iteratives.append(new_iterative) done_group.append(group) # Initialize iterative scheme debug( "\n --- pKa iterations ({0:d} groups, {1:d} interactions) ---".format( len(iteratives), len(iterative_interactions))) converged = False iteration = 0 # set non-iterative pka values as first step for iter_ in iteratives: iter_.pka_iter.append(iter_.pka_noniterative) # --- starting pKa iterations --- while not converged: # initialize pka_new iteration += 1 for itres in iteratives: itres.determinants = {'sidechain': [], 'backbone': [], 'coulomb': []} itres.pka_new = itres.pka_noniterative # Adding interactions to temporary determinant container for interaction in iterative_interactions: pair = interaction[0] object1, object2 = find_iterative(pair, iteratives) q1 = object1.q q2 = object2.q if q1 < 0.0 and q2 < 0.0: # both are acids add_iterative_acid_pair(object1, object2, interaction) elif q1 > 0.0 and q2 > 0.0: # both are bases add_iterative_base_pair(object1, object2, interaction) else: # one of each add_iterative_ion_pair(object1, object2, interaction, version) # Calculating pka_new values for itres in iteratives: for type_ in ['sidechain', 'backbone', 'coulomb']: for determinant in itres.determinants[type_]: itres.pka_new += determinant[1] # Check convergence converged = True for itres in iteratives: if itres.pka_new == itres.pka_old: itres.converged = True else: itres.converged = False converged = False # reset pka_old & storing pka_new in pka_iter for itres in iteratives: itres.pka_old = itres.pka_new itres.pka_iter.append(itres.pka_new) if iteration == 10: info("did not converge in {0:d} iterations".format(iteration)) break # printing pKa iterations # formerly was conditioned on if options.verbosity >= 2 - now unnecessary str_ = ' ' for index in range(iteration+1): str_ += "{0:>8d}".format(index) debug(str_) for itres in iteratives: str_ = "{0:s} ".format(itres.label) for pka in itres.pka_iter: str_ += "{0:>8.2f}".format(pka) if not itres.converged: str_ += " *" debug(str_) # creating real determinants and adding them to group object for itres in iteratives: for type_ in ['sidechain', 'backbone', 'coulomb']: for interaction in itres.determinants[type_]: #info('done',itres.group.label,interaction[0],interaction[1]) value = interaction[1] if value > UNK_MIN_VALUE or value < -UNK_MIN_VALUE: group = interaction[0] new_det = Determinant(group, value) itres.group.determinants[type_].append(new_det)
def set_number_of_protons_to_add(self, atom): debug('*'*10) debug('Setting number of protons to add for',atom) atom.number_of_protons_to_add = 8 debug(' %4d'%8) atom.number_of_protons_to_add -= self.valence_electrons[atom.element] debug('Valence eletrons: %4d'%-self.valence_electrons[atom.element]) atom.number_of_protons_to_add -= 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 debug('Pi electrons: %4d'%-atom.number_of_pi_electrons_in_double_and_triple_bonds) atom.number_of_protons_to_add += int(atom.charge) debug('Charge: %4.1f'%atom.charge) debug('-'*10) debug(atom.number_of_protons_to_add) return
def set_number_of_protons_to_add(self, atom): debug('*' * 10) debug('Setting number of protons to add for', atom) atom.number_of_protons_to_add = 8 debug(' %4d' % 8) atom.number_of_protons_to_add -= self.valence_electrons[atom.element] debug('Valence eletrons: %4d' % -self.valence_electrons[atom.element]) atom.number_of_protons_to_add -= 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 debug('Pi electrons: %4d' % -atom.number_of_pi_electrons_in_double_and_triple_bonds) atom.number_of_protons_to_add += int(atom.charge) debug('Charge: %4.1f' % atom.charge) debug('-' * 10) debug(atom.number_of_protons_to_add) return
def set_steric_number_and_lone_pairs(self, atom): # If we already did this, there is no reason to do it again if atom.steric_number_and_lone_pairs_set: return debug('=' * 10) debug('Setting steric number and lone pairs for', atom) # costumly set the N backbone atoms up for peptide bond trigonal planer shape #if atom.name == 'N' and len(atom.bonded_atoms) == 2: # atom.steric_number = 3 # atom.number_of_lone_pairs = 0 # self.display 'Peptide bond: steric number is %d and number of lone pairs is %s'%(atom.steric_number, # atom.number_of_lone_pairs) # return atom.steric_number = 0 debug('%65s: %4d' % ('Valence electrons', self.valence_electrons[atom.element])) atom.steric_number += self.valence_electrons[atom.element] debug('%65s: %4d' % ('Number of bonds', len(atom.bonded_atoms))) atom.steric_number += len(atom.bonded_atoms) debug( '%65s: %4d' % ('Number of hydrogen atoms to add', atom.number_of_protons_to_add)) atom.steric_number += atom.number_of_protons_to_add 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 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 debug('%65s: %4d' % ('Number of donated co-ordinated bonds', 0)) atom.steric_number += 0 debug('%65s: %4.1f' % ('Charge(-)', atom.charge)) atom.steric_number -= atom.charge 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 debug('-' * 70) debug('%65s: %4d' % ('Steric number', atom.steric_number)) debug('%65s: %4d' % ('Number of lone pairs', atom.number_of_lone_pairs)) atom.steric_number_and_lone_pairs_set = True return