def compute_chi_angle_residue()

in mmcif_utils.py [0:0]


def compute_chi_angle_residue(residue):
    # look up the atoms that are used for computing the chi angles.
    chi_angles_atoms = kvs[residue.name]

    angles = []

    try:
        for chi_angles_atom in chi_angles_atoms:
            atoms = chi_angles_atom.split("-")
            pos = []

            for atom in atoms:
                # In some cases, amino acid side chains are listed with CD1 instead of CD
                if atom == "CD":
                    if "CD" not in residue:
                        atom = residue["CD1"]
                    else:
                        atom = residue[atom]
                else:
                    atom = residue[atom]

                pos.append((atom.pos.x, atom.pos.y, atom.pos.z))

            pos = np.array(pos)
            diff_vec = pos[2] - pos[1]
            # Compute the axis in which we are computing the dihedral angle
            diff_vec_normalize = diff_vec / np.linalg.norm(diff_vec)

            diff_bot = pos[0] - pos[1]
            diff_top = pos[3] - pos[2]

            # Now project diff_bot and diff_top to be on the plane
            diff_bot = diff_bot - diff_bot.dot(diff_vec_normalize) * diff_vec_normalize
            diff_top = diff_top - diff_top.dot(diff_vec_normalize) * diff_vec_normalize

            diff_bot_normalize = diff_bot / np.linalg.norm(diff_bot)
            diff_top_normalize = diff_top / np.linalg.norm(diff_top)

            # Compute the dot product for cos and cross product for sin
            sin = (np.cross(diff_bot_normalize, diff_top_normalize) * diff_vec_normalize).sum(
                axis=1
            )
            cos = diff_bot_normalize.dot(diff_top_normalize)

            # print("trig value ", sin, cos, np.linalg.norm([sin, cos]))
            angle = np.arctan2(sin, cos)
            # print("angle ", angle)

            angles.append(angle)
    except Exception as e:
        return None

    return angles