def build_bb(self):
        """Build backbone for residue."""
        if self.prev_res is None:
            self.bb = self._init_bb()
        else:
            pts = [self.prev_res.bb[0], self.prev_res.bb[1], self.prev_res.bb[2]]
            for j in range(4):
                if j == 0:
                    # Placing N
                    t = self.prev_res.ang[4]  # thetas["ca-c-n"]
                    b = BB_BUILD_INFO["BONDLENS"]["c-n"]
                    pb = BB_BUILD_INFO["BONDLENS"]["ca-c"]  # pb is previous bond len
                    dihedral = self.prev_res.ang[1]  # psi of previous residue
                elif j == 1:
                    # Placing Ca
                    t = self.prev_res.ang[5]  # thetas["c-n-ca"]
                    b = BB_BUILD_INFO["BONDLENS"]["n-ca"]
                    pb = BB_BUILD_INFO["BONDLENS"]["c-n"]
                    dihedral = self.prev_res.ang[2]  # omega of previous residue
                elif j == 2:
                    # Placing C
                    t = self.ang[3]  # thetas["n-ca-c"]
                    b = BB_BUILD_INFO["BONDLENS"]["ca-c"]
                    pb = BB_BUILD_INFO["BONDLENS"]["n-ca"]
                    dihedral = self.ang[0]  # phi of current residue
                else:
                    # Placing O (carbonyl)
                    t = torch.tensor(BB_BUILD_INFO["BONDANGS"]["ca-c-o"])
                    b = BB_BUILD_INFO["BONDLENS"]["c-o"]
                    pb = BB_BUILD_INFO["BONDLENS"]["ca-c"]
                    if self.is_last_res:
                        # we explicitly measure this angle during dataset creation,
                        # no need to invert it here.
                        dihedral = self.ang[1]
                    else:
                        # the angle for placing oxygen is opposite to psi of current res
                        dihedral = self.ang[1] - np.pi

                next_pt = nerf(pts[-3],
                               pts[-2],
                               pts[-1],
                               b,
                               t,
                               dihedral,
                               l_bc=pb,
                               nerf_method=self.nerf_method)
                pts.append(next_pt)
            self.bb = pts[3:]

        return self.bb
Esempio n. 2
0
    def _init_bb(self):
        """Initialize the first 3 points of the protein's backbone.

        Placed in an arbitrary plane (z = .001).
        """
        n = torch.tensor([0, 0, 0.001], device=self.device)
        ca = n + torch.tensor([BB_BUILD_INFO["BONDLENS"]["n-ca"], 0, 0],
                              device=self.device)
        cx = torch.cos(np.pi - self.ang[3]) * BB_BUILD_INFO["BONDLENS"]["ca-c"]
        cy = torch.sin(np.pi - self.ang[3]) * BB_BUILD_INFO["BONDLENS"]['ca-c']
        c = ca + torch.tensor(
            [cx, cy, 0], device=self.device, dtype=torch.float32)
        o = nerf(n, ca, c, torch.tensor(BB_BUILD_INFO["BONDLENS"]["c-o"]),
                 torch.tensor(BB_BUILD_INFO["BONDANGS"]["ca-c-o"]),
                 self.ang[1] - np.pi)  # opposite to current residue's psi
        return [n, ca, c, o]
    def build_sc(self):
        """Build the sidechain atoms for this residue.

        Care is taken when placing the first sc atom (the beta-Carbon). This is
        because the dihedral angle that places this atom must be defined using a
        neighboring (previous or next) residue.
        """
        assert len(self.bb) > 0, "Backbone must be built first."
        self.atom_names = ["N", "CA", "C", "O"]
        self.pts = {"N": self.bb[0], "CA": self.bb[1], "C": self.bb[2]}
        if self.next_res:
            self.pts["N+"] = self.next_res.bb[0]
        else:
            self.pts["C-"] = self.prev_res.bb[2]

        last_torsion = None
        for i, (pbond_len, bond_len, angle, torsion, atom_names) in enumerate(
                _get_residue_build_iter(self.name, SC_BUILD_INFO)):
            # Select appropriate 3 points to build from
            if self.next_res and i == 0:
                a, b, c = self.pts["N+"], self.pts["C"], self.pts["CA"]
            elif i == 0:
                a, b, c = self.pts["C-"], self.pts["N"], self.pts["CA"]
            else:
                a, b, c = (self.pts[an] for an in atom_names[:-1])

            # Select appropriate torsion angle, or infer if part of a planar configuration
            if type(torsion) is str and torsion == "p":
                torsion = self.ang[SC_ANGLES_START_POS + i]
            elif type(torsion) is str and torsion == "i" and last_torsion is not None:
                torsion = last_torsion - np.pi

            new_pt = nerf(a,
                          b,
                          c,
                          bond_len,
                          angle,
                          torsion,
                          l_bc=pbond_len,
                          nerf_method=self.nerf_method)
            self.pts[atom_names[-1]] = new_pt
            self.sc.append(new_pt)
            last_torsion = torsion
            self.atom_names.append(atom_names[-1])

        return self.sc