diff --git a/modelling/pymod/_reconstruct_sidechains.py b/modelling/pymod/_reconstruct_sidechains.py index aaf1a0eba7b70091746350ca101f31991f5b32ed..26d31567bb76a95dd5703e3da840a77b937e70f5 100644 --- a/modelling/pymod/_reconstruct_sidechains.py +++ b/modelling/pymod/_reconstruct_sidechains.py @@ -297,8 +297,9 @@ def _GetRotamerGroups(res_list, rot_ids, indices, rot_lib, rot_constructor, return rotamer_groups, residues_with_rotamer_group -def _GetDisulfidBridges(frame_residues, cystein_indices, res_list, rotamer_library, - use_frm, bbdep, rotamer_constructor, phi_angles, psi_angles): +def _GetDisulfidBridges(frame_residues, keep_sidechains, cystein_indices, + res_list, rotamer_library, use_frm, bbdep, + rotamer_constructor, phi_angles, psi_angles): '''Get disulfid bridges for CYS and according rotamers. CYS are identified by by items in cystein_indices (into res_list). Returns: disulfid_indices: list of res. index in bridge, @@ -322,10 +323,34 @@ def _GetDisulfidBridges(frame_residues, cystein_indices, res_list, rotamer_libra continue cys_ca_positions.append(ca.GetPos()) cys_cb_positions.append(cb.GetPos()) - # get RotamerGroup in case of disulfids, we do FRM in any case - rot_group = _GetRotamerGroup(r.handle, sidechain.CYD, i, rotamer_library, - rotamer_constructor, phi_angles[i], - psi_angles[i], True, bbdep) + + # get RotamerGroup in case of cysteins, we do FRM in any case... + # If we're suposed to keep the existing sidechains and the processed + # cystein contains all required atoms, we manually construct an FRM + # rotamer to still allow the rotamer to enter the disulfid bridge + # resolving algorithm. + rot_group = None + if keep_sidechains: + sg = r.FindAtom("SG") + if sg.IsValid(): + particle = sidechain.Particle(sidechain.SidechainParticle.SParticle, + sg.GetPos(), + -0.19, "SG") + particle_list = [particle] + # The temperature and self internal_e_prefactor parameter have + # been copied from the SCWRLRotamerConstructor. Hacky... + frm_rotamer = sidechain.FRMRotamer(particle_list, + 1.69, 1.0, 4.07) + frm_rotamer.AddSubrotamerDefinition([0]) + frm_rotamer.SetInternalEnergy(0.0) + rot_group = sidechain.FRMRotamerGroup([frm_rotamer], i) + + if rot_group == None: + rot_group = _GetRotamerGroup(r.handle, sidechain.CYD, i, + rotamer_library, + rotamer_constructor, + phi_angles[i], + psi_angles[i], True, bbdep) rot_group.AddFrameEnergy(frame) cystein_rot_groups.append(rot_group) indices_with_rot_groups.append(i) @@ -455,7 +480,8 @@ def ReconstructSidechains(ent, keep_sidechains=False, build_disulfids=True, if len(cystein_indices) > 0: # get disulfid bridges and according rotamers disulfid_indices, disulfid_rotamers = \ - _GetDisulfidBridges(frame_residues, cystein_indices, prot.residues, + _GetDisulfidBridges(frame_residues, keep_sidechains, + cystein_indices, prot.residues, rotamer_library, use_frm, bbdep, rotamer_constructor, phi_angles, psi_angles) # update frame_residues, incomplete_sidechains diff --git a/modelling/src/sidechain_reconstructor.cc b/modelling/src/sidechain_reconstructor.cc index 8ab263f3b82f5674a5ce2bf9e8aa7a17ef39e80d..5db321783bf5aeb76e317f97217e40c8d73feb24 100644 --- a/modelling/src/sidechain_reconstructor.cc +++ b/modelling/src/sidechain_reconstructor.cc @@ -201,17 +201,19 @@ void SidechainReconstructor::SetEnvData_(loop::AllAtomEnv& env) { attached_environment_ = true; } -// NOTE: it's ok to have private template functions... -template<typename RotamerGroup> void SidechainReconstructor::BuildDisulfids_( +void SidechainReconstructor::BuildDisulfids_( SidechainReconstructionDataPtr res, std::vector<uint>& cys_indices, std::vector<sidechain::FrameResiduePtr>& frame_residues, std::vector<bool>& has_sidechain) const { // setup std::vector<uint>& res_indices = res->env_pos->res_indices; - typedef boost::shared_ptr<RotamerGroup> RotamerGroupPtr; - typedef typename RotamerGroup::value_type RotamerPtr; + typedef sidechain::FRMRotamer Rotamer; + typedef sidechain::FRMRotamerPtr RotamerPtr; + typedef sidechain::FRMRotamerGroup RotamerGroup; + typedef sidechain::FRMRotamerGroupPtr RotamerGroupPtr; + loop::AllAtomPositions& out_pos = *(res->env_pos->all_pos); // collect rotamers and data required to resolve the disulfid bridges @@ -232,6 +234,32 @@ template<typename RotamerGroup> void SidechainReconstructor::BuildDisulfids_( RotamerGroupPtr p; env_->GetCydRotamerGroup(p, global_idx); if (p) { + if(keep_sidechains_) { + sidechain::FrameResiduePtr f_res = env_->GetScFrameResidue(global_idx); + if(f_res) { + // We want to keep existing sidechains (keep_sidechains_ == true) + // and everything seems to be present since the sidechain frame + // residue exists. We therefore replace the extracted FRMRotamerGroup + // (p) with position data from the frame. + // The reason for still creating a FRMRotamerGroup is that it can + // enter the ResolveCystein evaluation. + std::vector<sidechain::Particle> particles; + particles.push_back(sidechain::Particle((*f_res)[0].GetParticleType(), + (*f_res)[0].GetPos(), + (*f_res)[0].GetCharge(), + (*f_res)[0].GetName())); + RotamerPtr r(new Rotamer(particles, (*p)[0]->GetTemperature(), 1.0, + (*p)[0]->GetInternalEnergyPrefactor())); + std::vector<int> subrotamer_definition(1,0); + r->AddSubrotamerDefinition(subrotamer_definition); + r->SetInternalEnergy(0.0); + std::vector<RotamerPtr> rotamers; + rotamers.push_back(r); + RotamerGroupPtr new_rot_group(new RotamerGroup(rotamers, global_idx)); + p = new_rot_group; + } + } + p->SetFrameEnergy(frame); cys_rotamer_groups.push_back(p); ca_pos.push_back(all_pos_->GetPos(global_idx, loop::BB_CA_INDEX)); @@ -380,9 +408,7 @@ void SidechainReconstructor::SolveSystem_( // handle cysteins res->disulfid_bridges.clear(); if (build_disulfids_) { - // we use the FRM rotamer model in any case for reconstructing disulfids - BuildDisulfids_<sidechain::FRMRotamerGroup>(res, cys_indices, - frame_residues, has_sidechain); + BuildDisulfids_(res, cys_indices, frame_residues, has_sidechain); } // collect rotamers diff --git a/modelling/src/sidechain_reconstructor.hh b/modelling/src/sidechain_reconstructor.hh index 565b830a0d5ba40236310aa79d8026193e75ef67..94e05496fb39424649e587e3d7b9f1802c92c211 100644 --- a/modelling/src/sidechain_reconstructor.hh +++ b/modelling/src/sidechain_reconstructor.hh @@ -84,7 +84,6 @@ private: // -> pairs of cys_indices[i] for bridges added to res->disulfid_bridges // -> unhandled CYS with known SC are added to frame_residues // -> has_sidechain is updated as needed (i.e. when SC has been dealt with) - template<typename RotamerGroup> void BuildDisulfids_(SidechainReconstructionDataPtr res, std::vector<uint>& cys_indices, std::vector<sidechain::FrameResiduePtr>& frame_residues,