Beispiel #1
0
def addCoulombBasePair(object1, object2, value):
    """
    Adding the Coulomb interaction (a base pair):
    the lower pKa is lowered
    """
    if object1.model_pka < object2.model_pka:
        newDeterminant = Determinant(object2, -value)
        object1.determinants['coulomb'].append(newDeterminant)
    else:
        newDeterminant = Determinant(object1, -value)
        object2.determinants['coulomb'].append(newDeterminant)
Beispiel #2
0
def addCoulombAcidPair(object1, object2, value):
    """
    Adding the Coulomb interaction (an acid pair):
    the higher pKa is raised
    """

    if object1.model_pka > object2.model_pka:
        newDeterminant = Determinant(object2, value)
        object1.determinants['coulomb'].append(newDeterminant)
    else:
        newDeterminant = Determinant(object1, value)
        object2.determinants['coulomb'].append(newDeterminant)
Beispiel #3
0
def addCoulombIonPair(object1, object2, value):
    """
    Adding the Coulomb interaction (an acid-base pair):
    the pKa of the acid is lowered & the pKa of the base is raised
    """

    # residue1
    Q1 = object1.charge
    newDeterminant = Determinant(object2, Q1 * value)
    object1.determinants['coulomb'].append(newDeterminant)

    # residue2
    Q2 = object2.charge
    newDeterminant = Determinant(object1, Q2 * value)
    object2.determinants['coulomb'].append(newDeterminant)
    def share_determinants(groups):
        """Share sidechain, backbone, and Coloumb determinants between groups.

        Args:
            groups:  groups to share between
        """
        # make a list of the determinants to share
        types = ['sidechain', 'backbone', 'coulomb']
        for type_ in types:
            # find maximum value for each determinant
            max_dets = {}
            for group in groups:
                for det in group.determinants[type_]:
                    # update max dets
                    if det.group not in max_dets.keys():
                        max_dets[det.group] = det.value
                    else:
                        max_dets[det.group] = max(det.value,
                                                  max_dets[det.group],
                                                  key=lambda v: abs(v))
            # overwrite/add maximum value for each determinant
            for det_group in max_dets:
                new_determinant = Determinant(det_group, max_dets[det_group])
                for group in groups:
                    group.set_determinant(new_determinant, type_)
Beispiel #5
0
def add_coulomb_acid_pair(object1, object2, value):
    """Add the Coulomb interaction (an acid pair).

    The higher pKa is raised.

    Args:
        object1:  first part of pair
        object2:  second part of pair
        value:  determinant value
    """
    if object1.model_pka > object2.model_pka:
        new_determinant = Determinant(object2, value)
        object1.determinants['coulomb'].append(new_determinant)
    else:
        new_determinant = Determinant(object1, value)
        object2.determinants['coulomb'].append(new_determinant)
Beispiel #6
0
def add_coulomb_base_pair(object1, object2, value):
    """Add the Coulomb interaction (a base pair).

    The lower pKa is lowered.

    Args:
        object1:  first part of pair
        object2:  second part of pair
        value:  determinant value
    """
    if object1.model_pka < object2.model_pka:
        new_determinant = Determinant(object2, -value)
        object1.determinants['coulomb'].append(new_determinant)
    else:
        new_determinant = Determinant(object1, -value)
        object2.determinants['coulomb'].append(new_determinant)
Beispiel #7
0
def add_coulomb_ion_pair(object1, object2, value):
    """Add the Coulomb interaction (an acid-base pair).

    The pKa of the acid is lowered & the pKa of the base is raised.

    Args:
        object1:  first part of pair
        object2:  second part of pair
        value:  determinant value
    """
    # residue1
    q1 = object1.charge
    new_determinant = Determinant(object2, q1 * value)
    object1.determinants['coulomb'].append(new_determinant)
    # residue2
    q2 = object2.charge
    new_determinant = Determinant(object1, q2 * value)
    object2.determinants['coulomb'].append(new_determinant)
Beispiel #8
0
def add_sidechain_determinants(group1, group2, version=None):
    """Add side-chain determinants and perturbations.

    NOTE - res_num1 > res_num2

    Args:
        group1:  first group to add
        group2:  second group to add
        version:  version object
    """
    hbond_interaction = version.hydrogen_bond_interaction(group1, group2)
    if hbond_interaction:
        if group1.charge == group2.charge:
            # acid pair or base pair
            if group1.model_pka < group2.model_pka:
                new_determinant1 = Determinant(group2, -hbond_interaction)
                new_determinant2 = Determinant(group1, hbond_interaction)
            else:
                new_determinant1 = Determinant(group2, hbond_interaction)
                new_determinant2 = Determinant(group1, -hbond_interaction)
        else:
            new_determinant1 = Determinant(group2,
                                           hbond_interaction * group1.charge)
            new_determinant2 = Determinant(group1,
                                           hbond_interaction * group2.charge)
        group1.determinants['sidechain'].append(new_determinant1)
        group2.determinants['sidechain'].append(new_determinant2)
Beispiel #9
0
def addSidechainDeterminants(group1, group2, version=None):
    """
    adding side-chain determinants/perturbations
    Note, resNumb1 > resNumb2
    """

    hbond_interaction = version.hydrogen_bond_interaction(group1, group2)

    if hbond_interaction:

        if group1.charge == group2.charge:
            # acid pair or base pair
            if group1.model_pka < group2.model_pka:
                newDeterminant1 = Determinant(group2, -hbond_interaction)
                newDeterminant2 = Determinant(group1, hbond_interaction)
            else:
                newDeterminant1 = Determinant(group2, hbond_interaction)
                newDeterminant2 = Determinant(group1, -hbond_interaction)
        else:
            newDeterminant1 = Determinant(group2,
                                          hbond_interaction * group1.charge)
            newDeterminant2 = Determinant(group1,
                                          hbond_interaction * group2.charge)

        group1.determinants['sidechain'].append(newDeterminant1)
        group2.determinants['sidechain'].append(newDeterminant2)

    return
Beispiel #10
0
    def set_determinant(self, new_determinant, type_):
        """Overwrite current and create non-present determinants.

        Args:
            new_determinant:  new determinant to add
            type_:  determinant type
        """
        # first check if we already have a determinant with this label
        for own_determinant in self.determinants[type_]:
            if own_determinant.group == new_determinant.group:
                # if so, overwrite the value
                own_determinant.value = new_determinant.value
                return
        # otherwise we just add the determinant to our list
        self.determinants[type_].append(
            Determinant(new_determinant.group, new_determinant.value))
Beispiel #11
0
def setIonDeterminants(conformation_container, version):
    """
    adding ion determinants/perturbations
    """
    for titratable_group in conformation_container.get_titratable_groups():
        for ion_group in conformation_container.get_ions():
            squared_distance = propka.calculations.squared_distance(
                titratable_group, ion_group)
            if squared_distance < version.parameters.coulomb_cutoff2_squared:
                weight = version.calculatePairWeight(titratable_group.Nmass,
                                                     ion_group.Nmass)
                # the pKa of both acids and bases are shifted up by negative ions (and vice versa)
                value = (-ion_group.charge) * version.calculateCoulombEnergy(
                    math.sqrt(squared_distance), weight)
                newDeterminant = Determinant(ion_group, value)
                titratable_group.determinants['coulomb'].append(newDeterminant)

    return
Beispiel #12
0
def set_ion_determinants(conformation_container, version):
    """Add ion determinants and perturbations.

    Args:
        conformation_container:  conformation to set
        version:  version object
    """
    for titratable_group in conformation_container.get_titratable_groups():
        for ion_group in conformation_container.get_ions():
            dist_sq = squared_distance(titratable_group, ion_group)
            if dist_sq < version.parameters.coulomb_cutoff2_squared:
                weight = version.calculate_pair_weight(
                    titratable_group.num_volume, ion_group.num_volume)
                # the pKa of both acids and bases are shifted up by negative
                # ions (and vice versa)
                value = (-ion_group.charge * version.calculate_coulomb_energy(
                    math.sqrt(dist_sq), weight))
                new_det = Determinant(ion_group, value)
                titratable_group.determinants['coulomb'].append(new_det)
Beispiel #13
0
    def share_determinant(self, new_determinant, type_):
        """Add determinant to this group's list of determinants.

        Args:
            new_determinant:  determinant to add
            type_:  type of determinant
        """
        added = False
        # first check if we already have a determinant with this label
        for own_determinant in self.determinants[type_]:
            if own_determinant.group == new_determinant.group:
                # if so, find the average value
                avr = 0.5 * (own_determinant.value + new_determinant.value)
                own_determinant.value = avr
                new_determinant.value = avr
                added = True
        # otherwise we just add the determinant to our list
        if not added:
            self.determinants[type_].append(
                Determinant(new_determinant.group, new_determinant.value))
Beispiel #14
0
def set_backbone_determinants(titratable_groups, backbone_groups, version):
    """Set determinants between titrable and backbone groups.

    Args:
        titratable_groups:  list of titratable groups
        backbone_groups:  list of backbone groups
        version:  version object
    """
    for titratable_group in titratable_groups:
        titratable_group_interaction_atoms = (
            titratable_group.interaction_atoms_for_acids)
        if not titratable_group_interaction_atoms:
            continue
        # find out which backbone groups this titratable is interacting with
        for backbone_group in backbone_groups:
            # find the interacting atoms
            backbone_interaction_atoms = (
                backbone_group.get_interaction_atoms(titratable_group))
            if not backbone_interaction_atoms:
                continue
            # find the smallest distance
            [backbone_atom, distance, titratable_atom
             ] = (get_smallest_distance(backbone_interaction_atoms,
                                        titratable_group_interaction_atoms))
            # get the parameters
            parameters = (version.get_backbone_hydrogen_bond_parameters(
                backbone_atom, titratable_atom))
            if not parameters:
                continue
            [dpka_max, [cutoff1, cutoff2]] = parameters
            if distance < cutoff2:
                # calculate angle factor
                f_angle = 1.0
                # for BBC groups, the hydrogen is on the titratable group
                #
                #        Titra.
                #       /
                #      H
                #     .
                #    O
                #    ||
                #    C
                if backbone_group.type == 'BBC':
                    if (titratable_group.type in version.parameters.
                            angular_dependent_sidechain_interactions):
                        if titratable_atom.element == 'H':
                            heavy_atom = titratable_atom.bonded_atoms[0]
                            hydrogen_atom = titratable_atom
                            [_, f_angle,
                             _] = angle_distance_factors(atom1=heavy_atom,
                                                         atom2=hydrogen_atom,
                                                         atom3=backbone_atom)
                        else:
                            # Either the structure is corrupt (no hydrogen),
                            # or the heavy atom is closer to the titratable
                            # atom than the hydrogen. In either case we set the
                            # angle factor to 0
                            f_angle = 0.0
                # for BBN groups, the hydrogen is on the backbone group
                #
                #      Titra.
                #     .
                #    H
                #    |
                #    N
                #  /   \
                if backbone_group.type == 'BBN':
                    if backbone_atom.element == 'H':
                        backbone_n = backbone_atom.bonded_atoms[0]
                        backbone_h = backbone_atom
                        [_, f_angle,
                         _] = (angle_distance_factors(atom1=titratable_atom,
                                                      atom2=backbone_h,
                                                      atom3=backbone_n))
                    else:
                        # Either the structure is corrupt (no hydrogen), or the
                        # heavy atom is closer to the titratable atom than the
                        # hydrogen. In either case we set the angle factor to 0
                        f_angle = 0.0
                if f_angle > FANGLE_MIN:
                    value = (titratable_group.charge * hydrogen_bond_energy(
                        distance, dpka_max, [cutoff1, cutoff2], f_angle))
                    new_determinant = Determinant(backbone_group, value)
                    titratable_group.determinants['backbone'].append(
                        new_determinant)
Beispiel #15
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 #16
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 #17
0
def setBackBoneDeterminants(titratable_groups, backbone_groups, version):

    for titratable_group in titratable_groups:
        titratable_group_interaction_atoms = titratable_group.interaction_atoms_for_acids
        if not titratable_group_interaction_atoms:
            continue

        # find out which backbone groups this titratable is interacting with
        for backbone_group in backbone_groups:
            # find the interacting atoms
            backbone_interaction_atoms = backbone_group.get_interaction_atoms(
                titratable_group)
            if not backbone_interaction_atoms:
                continue

            # find the smallest distance
            [backbone_atom, distance,
             titratable_atom] = propka.calculations.get_smallest_distance(
                 backbone_interaction_atoms,
                 titratable_group_interaction_atoms)
            # get the parameters
            parameters = version.get_backbone_hydrogen_bond_parameters(
                backbone_atom, titratable_atom)
            if not parameters:
                continue
            [dpKa_max, [cutoff1, cutoff2]] = parameters

            if distance < cutoff2:
                # calculate angle factor
                f_angle = 1.0
                # for BBC groups, the hydrogen is on the titratable group
                #
                #        Titra.
                #       /
                #      H
                #     .
                #    O
                #    ||
                #    C
                if backbone_group.type == 'BBC':
                    if titratable_group.type in version.parameters.angular_dependent_sidechain_interactions:
                        if titratable_atom.element == 'H':
                            heavy_atom = titratable_atom.bonded_atoms[0]
                            hydrogen_atom = titratable_atom
                            [d1, f_angle,
                             d2] = propka.calculations.AngleFactorX(
                                 atom1=heavy_atom,
                                 atom2=hydrogen_atom,
                                 atom3=backbone_atom)
                        else:
                            # Either the structure is corrupt (no hydrogen), or the heavy atom is closer to
                            # the titratable atom than the hydrogen. In either case we set the angle factor
                            # to 0
                            f_angle = 0.0

                # for BBN groups, the hydrogen is on the backbone group
                #
                #      Titra.
                #     .
                #    H
                #    |
                #    N
                #  /   \
                if backbone_group.type == 'BBN':
                    if backbone_atom.element == 'H':
                        backbone_N = backbone_atom.bonded_atoms[0]
                        backbone_H = backbone_atom
                        [d1, f_angle, d2] = propka.calculations.AngleFactorX(
                            atom1=titratable_atom,
                            atom2=backbone_H,
                            atom3=backbone_N)
                    else:
                        # Either the structure is corrupt (no hydrogen), or the heavy atom is closer to
                        # the titratable atom than the hydrogen. In either case we set the angle factor
                        # to 0
                        f_angle = 0.0

                if f_angle > 0.001:
                    value = titratable_group.charge * propka.calculations.HydrogenBondEnergy(
                        distance, dpKa_max, [cutoff1, cutoff2], f_angle)

                    newDeterminant = Determinant(backbone_group, value)
                    titratable_group.determinants['backbone'].append(
                        newDeterminant)

    return