import warnings
import subprocess
import logging
from math import degrees
import Bio.PDB
from Bio.PDB.Polypeptide import three_to_one

logger = logging.getLogger('CReF')


def backbone_dihedral_angles(pdb_code, pdb_chain, pdb_filepath):
    """
    The backbone dihedral angles of proteins are called φ (phi, involving
    the backbone atoms C'-N-Cα-C'), ψ (psi, involving the backbone atoms
    N-Cα-C'-N) and ω (omega, involving the backbone atoms Cα-C'-N-Cα).

    We *only* obtain phi and psi angles.

    :param pdb_code: Identifier for the pdb
    :param pdb_chain: Identifier for the chain inside the model
    :param pdb_filepath: Path to the pdb file used as input

    :return: List residues and torsion angles
        [residues, phi, psi]
    """
    # Silence pdb reader warnings
    warnings.simplefilter("ignore")
    structure = Bio.PDB.PDBParser().get_structure(pdb_code, pdb_filepath)
    residues = ''
    phi_angles = []
    psi_angles = []
    for model in structure:
        chain = model[pdb_chain]
        polypeptides = Bio.PDB.CaPPBuilder().build_peptides(chain)
        for polypeptide in polypeptides:
            phi_psi = polypeptide.get_phi_psi_list()
            # Convert to degrees
            phi_angles += [degrees(phi) if phi else None for phi, _ in phi_psi]
            psi_angles += [degrees(psi) if psi else None for _, psi in phi_psi]
            # Get one letter code
            residues += ''.join(
                [three_to_one(aa.resname) for aa in polypeptide])
    return dict(residues=residues, phi=phi_angles, psi=psi_angles)


def backbone_torsion_angles(pdb_filepath):
    """
    Wrapper around Torsions

    Torsions is a simple program to read a PDB file and calculate backbone
    torsion angles.

    The backbone dihedral angles of proteins are called φ (phi, involving
    the backbone atoms C'-N-Cα-C'), ψ (psi, involving the backbone atoms
    N-Cα-C'-N) and ω (omega, involving the backbone atoms Cα-C'-N-Cα).

    See http://www.bioinf.org.uk/software/torsions/

    :param pdb_filepath: Path to the pdb file used as input to torsions
    """
    output = subprocess.check_output([
        './libs/torsions',
        pdb_filepath,
    ])
    lines = output.decode('utf-8').split('\n')[2:]  # remove heading
    result = [line.split()[1:] for line in lines[:-1]]
    result = list(zip(*result))

    residues = ''
    phi = []
    psi = []

    for i in range(len(result[0])):
        try:
            residues += three_to_one(result[0][i])
        except Exception as e:
            logger.debug(
                'Could not get one letter code for ' + result[0][i])
            logger.debug(e)
        else:
            phi.append(float(result[1][i]))
            psi.append(float(result[2][i]))

    return dict(residues=residues, phi=phi, psi=psi)

@@ -1,20 +1,4 @@
-import warnings%0A
 impo
@@ -30,47 +30,37 @@
 ing%0A
-from math import degrees%0Aimport Bio.PDB
+import pickle%0Aimport sqlite3%0A
 %0Afro
@@ -102,16 +102,49 @@
 to_one%0A%0A
+from cref.utils import Database%0A%0A
 logger =
@@ -172,1413 +172,8 @@
 ReF'
-)%0A%0A%0Adef backbone_dihedral_angles(pdb_code, pdb_chain, pdb_filepath):%0A    %22%22%22%0A    The backbone dihedral angles of proteins are called %CF%86 (phi, involving%0A    the backbone atoms C'-N-C%CE%B1-C'), %CF%88 (psi, involving the backbone atoms%0A    N-C%CE%B1-C'-N) and %CF%89 (omega, involving the backbone atoms C%CE%B1-C'-N-C%CE%B1).%0A%0A    We *only* obtain phi and psi angles.%0A%0A    :param pdb_code: Identifier for the pdb%0A    :param pdb_chain: Identifier for the chain inside the model%0A    :param pdb_filepath: Path to the pdb file used as input%0A%0A    :return: List residues and torsion angles%0A        %5Bresidues, phi, psi%5D%0A    %22%22%22%0A    # Silence pdb reader warnings%0A    warnings.simplefilter(%22ignore%22)%0A    structure = Bio.PDB.PDBParser().get_structure(pdb_code, pdb_filepath)%0A    residues = ''%0A    phi_angles = %5B%5D%0A    psi_angles = %5B%5D%0A    for model in structure:%0A        chain = model%5Bpdb_chain%5D%0A        polypeptides = Bio.PDB.CaPPBuilder().build_peptides(chain)%0A        for polypeptide in polypeptides:%0A            phi_psi = polypeptide.get_phi_psi_list()%0A            # Convert to degrees%0A            phi_angles += %5Bdegrees(phi) if phi else None for phi, _ in phi_psi%5D%0A            psi_angles += %5Bdegrees(psi) if psi else None for _, psi in phi_psi%5D%0A            # Get one letter code%0A            residues += ''.join(%0A                %5Bthree_to_one(aa.resname) for aa in polypeptide%5D)%0A    return dict(residues=residues, phi=phi_angles, psi=psi_angles
 )%0A%0A%0A

Remove dihedral angles calculation that uses biopython