def measure_sidechain_torsion_angles(residue, verbose=True):
    """Calculates sidechain dihedral angles for a residue

    Parameters
    ----------
    residue : [ampal.Residue]
        `Residue` object.
    verbose : bool, optional
        If `true`, tells you when a residue does not have any known
        dihedral angles to measure.

    Returns
    -------
    chi_angles: [float]
        Length depends on residue type, in range [-pi, pi]

        [0] = chi1 [if applicable]
        [1] = chi2 [if applicable]
        [2] = chi3 [if applicable]
        [3] = chi4 [if applicable]
    """
    chi_angles = []
    aa = residue.mol_code
    if aa not in side_chain_dihedrals:
        if verbose:
            print("Amino acid {} has no known side-chain dihedral".format(aa))
    else:
        for set_atoms in side_chain_dihedrals[aa]:
            required_for_dihedral = set_atoms[0:4]
            try:
                angle = dihedral(
                    residue[required_for_dihedral[0]]._vector,
                    residue[required_for_dihedral[1]]._vector,
                    residue[required_for_dihedral[2]]._vector,
                    residue[required_for_dihedral[3]]._vector)
                chi_angles.append(angle)
            except KeyError as k:
                print("{0} atom missing from residue {1} {2} "
                      "- can't assign dihedral".format(
                          k, residue.mol_code, residue.id))
                chi_angles.append(None)
    return chi_angles
Calculates sidechain dihedral angles for a residue

    Parameters
    ----------
    residue : [ampal.Residue]
        `Residue` object.
    verbose : bool, optional
        If `true`, tells you when a residue does not have any known
        dihedral angles to measure.

    Returns
    -------
    chi_angles: [float]
        Length depends on residue type, in range [-pi, pi]

        [0] = chi1 [if applicable]
        [1] = chi2 [if applicable]
        [2] = chi3 [if applicable]
        [3] = chi4 [if applicable]