Beispiel #1
0
    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)
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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))
Beispiel #5
0
    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)
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
    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)
Beispiel #9
0
    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
Beispiel #10
0
    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
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #13
0
    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
Beispiel #14
0
    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
Beispiel #15
0
    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)
Beispiel #16
0
    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
Beispiel #17
0
    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
Beispiel #18
0
    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
Beispiel #19
0
    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
Beispiel #20
0
    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
Beispiel #21
0
    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)
Beispiel #22
0
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)
Beispiel #23
0
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)
Beispiel #24
0
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)
Beispiel #25
0
    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
Beispiel #26
0
    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
Beispiel #27
0
    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