19 #include <basic/options/option.hh>
20 #include <basic/options/keys/in.OptionKeys.gen.hh>
22 #include <basic/Tracer.hh>
25 #include <utility/vector1.hh>
41 namespace conformation {
44 static basic::Tracer
TR(
"core.conformation.symmetry.Conformation");
57 symm_info_( symm_info.
clone() )
65 symm_info_( src.symm_info_->
clone() ),
91 if ( ! dynamic_cast< SymmetricConformation const * > ( &other) ) {
123 if ( !
symm_info_->dof_is_independent(
id, *
this ) ) {
124 TR.Debug <<
"SymmetricConformation:: directly setting a dependent DOF!, try to set its parent" << std::endl;
126 int parent_jump =
symm_info_->jump_follows(
fold_tree().get_jump_that_builds_residue(
id.rsd() ) );
132 parent_rsd =
symm_info_->bb_follows(
id.rsd() ) ;
135 parent_rsd =
id.rsd();
143 DOF_IDs
const & dofs(
symm_info_->dependent_dofs( parent_id, *
this ) );
144 for ( DOF_IDs::const_iterator
dof =dofs.begin(), dofe= dofs.end();
dof != dofe; ++
dof ) {
158 if (
symm_info_->bb_is_independent( seqpos ) ) {
159 for ( SymmetryInfo::Clones::const_iterator pos=
symm_info_->bb_clones( seqpos ).begin(),
160 epos=
symm_info_->bb_clones( seqpos ).end(); pos != epos; ++pos ) {
164 TR.Debug <<
"SymmetricConformation:: Setting secstruct for dependent residue!, try to set its parent" << std::endl;
183 TR.Trace <<
"SymmetricConformation: set_torsion: " <<
id <<
' ' << setting << std::endl;
187 if ( !
symm_info_->torsion_is_independent(
id ) ) {
188 TR.Debug <<
"SymmetricConformation:: directly setting a dependent TORSION!, try to set its parent" << std::endl;
189 parent_rsd =
symm_info_->bb_follows(
id.rsd() ) ;
191 parent_rsd =
id.rsd();
199 TorsionIDs
const & tors(
symm_info_->dependent_torsions( parent_id ) );
200 for ( TorsionIDs::const_iterator tor =tors.begin(), tore= tors.end(); tor != tore; ++tor ) {
216 AtomID parent_atom1, parent_atom2, parent_atom3, parent_atom4;
218 TR.Trace <<
"SymmetricConformation: set_torsion_angle: " << atom1 <<
"+ to " << setting << std::endl;
222 TR.Debug <<
"SymmetricConformation:: directly setting a dependent ANGLE!, try to set its parent" << std::endl;
243 AtomID dep_atom1, dep_atom2, dep_atom3, dep_atom4;
244 for (
int i=1; i<=(
int)nclones; ++i) {
264 AtomID parent_atom1, parent_atom2, parent_atom3;
266 TR.Trace <<
"SymmetricConformation: set_bond_angle: " << atom1 <<
"+ to " << setting << std::endl;
270 TR.Debug <<
"SymmetricConformation:: directly setting a dependent ANGLE!, try to set its parent" << std::endl;
288 AtomID dep_atom1, dep_atom2, dep_atom3;
289 for (
int i=1; i<=(
int)nclones; ++i) {
306 AtomID parent_atom1, parent_atom2;
308 TR.Trace <<
"SymmetricConformation: set_bond_length: " << atom1 <<
"+ to " << setting << std::endl;
312 TR.Debug <<
"SymmetricConformation:: directly setting a dependent BONDLENGTH!, try to set its parent" << std::endl;
327 AtomID dep_atom1, dep_atom2, dep_atom3;
328 for (
int i=1; i<=(
int)nclones; ++i) {
344 TR.Trace <<
"SymmetricConformation: set_jump jump_number: " << jump_number << std::endl;
352 if ( !
symm_info_->jump_is_independent( jump_number ) ) {
353 TR.Warning <<
"SymmetricConformation:: directly setting a dependent ATOM!" << std::endl;
354 TR.Warning <<
"the jump " << jump_number <<
" is controlled by " <<
symm_info_->jump_follows( jump_number ) << std::endl;
356 for ( Clones::const_iterator pos=
symm_info_->jump_clones( jump_number ).begin(),
357 epos=
symm_info_->jump_clones( jump_number ).end(); pos != epos; ++pos ) {
370 TR.Trace <<
"SymmetricConformation: set_jump jump_number: " << jump_number << std::endl;
377 if ( !
symm_info_->jump_is_independent( jump_number ) ) {
378 TR.Warning <<
"SymmetricConformation:: directly setting a dependent ATOM!" << std::endl;
380 for ( Clones::const_iterator pos=
symm_info_->jump_clones( jump_number ).begin(),
381 epos=
symm_info_->jump_clones( jump_number ).end(); pos != epos; ++pos ) {
395 TR.Trace <<
"SymmetricConformation: set_jump id:" <<
id << std::endl;
402 int const jump_number (
fold_tree().get_jump_that_builds_residue(
id.rsd() ) );
403 if ( !
symm_info_->jump_is_independent( jump_number ) ) {
404 TR.Warning <<
"SymmetricConformation:: directly setting a dependent ATOM!" << std::endl;
406 for ( Clones::const_iterator pos=
symm_info_->jump_clones( jump_number ).begin(),
407 epos=
symm_info_->jump_clones( jump_number ).end(); pos != epos; ++pos ) {
424 return symm_info_->score_multiply(resid1,resid2);
430 TR.Debug <<
"SymmetricConformation: replace_residue: " << seqpos << std::endl;
435 if ( !
symm_info_->bb_is_independent( seqpos ) ) {
436 TR.Debug <<
"SymmetricConformation::replace_residue(2) directly setting a dependent TORSION!, try to set its parent" << std::endl;
438 parent_rsd =
symm_info_->bb_follows( seqpos ) ;
441 if (!orient_backbone) {
443 for (
int i=1; i<=(
int)new_rsd.
natoms(); ++i) {
455 for ( SymmetryInfo::Clones::const_iterator pos=
symm_info_->bb_clones( parent_rsd ).begin(),
456 epos=
symm_info_->bb_clones( parent_rsd ).end(); pos != epos; ++pos ) {
459 if (!orient_backbone) {
462 for (
int i=1; i<=(
int)new_new_rsd.
natoms(); ++i) {
476 utility::vector1< std::pair< std::string, std::string > >
const & atom_pairs ) {
479 if ( !
symm_info_->bb_is_independent( seqpos ) ) {
480 TR.Debug <<
"SymmetricConformation::replace_residue(3) setting a dependent TORSION!, try to set its parent" << std::endl;
481 parent_rsd =
symm_info_->bb_follows( seqpos ) ;
490 for ( SymmetryInfo::Clones::const_iterator pos=
symm_info_->bb_clones( parent_rsd ).begin(),
491 epos=
symm_info_->bb_clones( parent_rsd ).end(); pos != epos; ++pos ) {
495 for (
int i=1; i<=(
int)new_new_rsd.
natoms(); ++i) {
514 curr_res = e_i.
start();
521 numeric::HomogeneousTransform< core::Real >
538 numeric::HomogeneousTransform< core::Real >
const &Tsymm_from
540 numeric::HomogeneousTransform< core::Real >
const &Tsymm_to
544 Xout = (Tsymm_from.inverse() * Xin);
545 Xout = (Tsymm_to * Xout);
557 TR.Debug <<
"SymmetricConformation::set_xyz: " <<
id << std::endl;
564 if (
id.rsd() >
symm_info_->num_total_residues_without_pseudo() ) {
569 if ( !
symm_info_->bb_is_independent(
id.rsd() ) ) {
570 TR.Debug <<
"SymmetricConformation::set_xyz setting a dependent XYZ; remapping to its parent" << std::endl;
575 parent_pos = position;
580 for ( SymmetryInfo::Clones::const_iterator pos=
symm_info_->bb_clones( parent_id.
rsd() ).begin(),
594 runtime_assert( ids.size() == positions.size() );
595 TR.Debug <<
"SymmetricConformation::batch_set_xyz" << std::endl;
602 for (
int i=1; i<=(
int)ids.size(); ++i) {
603 AtomID id=ids[i], parent_id;
606 if (
id.rsd() >
symm_info_->num_total_residues_without_pseudo() ) {
607 ids_with_symm.push_back(
id );
608 positions_with_symm.push_back( position );
610 if ( !
symm_info_->bb_is_independent(
id.rsd() ) ) {
611 TR.Debug <<
"SymmetricConformation::set_xyz setting a dependent XYZ; remapping to its parent" << std::endl;
616 parent_pos = position;
620 ids_with_symm.push_back( parent_id );
621 positions_with_symm.push_back( parent_pos );
622 for ( SymmetryInfo::Clones::const_iterator pos=
symm_info_->bb_clones( parent_id.rsd() ).begin(),
623 epos=
symm_info_->bb_clones( parent_id.rsd() ).
end(); pos != epos; ++pos ) {
626 ids_with_symm.push_back( id_i );
627 positions_with_symm.push_back( pos_i );
638 using namespace numeric;
647 for (
int i=1; i<=(
int)nsubunits; ++i) {
662 Tsymm_.push_back( HomogeneousTransform< core::Real>( orig-Y,orig-Z, orig ) );
671 Size const anchor_pos,
674 bool const start_new_chain
677 if (start_new_chain) {
678 TR.Warning <<
"SymmetricConformation::append_residue_by_jump ignores start_new_chain" << std::endl;
684 core::Size asymm_anchor = ((anchor_pos-1)%nres_monomer) + 1;
689 for (
int i=nsubunits; i>=1; --i ) {
691 core::Size anchor_pos = (i-1)*nres_monomer+asymm_anchor;
693 if ( !
symm_info_->bb_is_independent( seqpos ) ) {
695 for (
int j=1; j<=(
int)new_new_rsd.
natoms(); ++j) {
703 symm_info_->update_nmonomer_jumps( nmonomer_jumps + 1 );
714 Size const insert_seqpos,
716 Size const anchor_pos,
717 Size const anchor_jump_number,
721 if (anchor_jump_number != 0) {
722 TR.Warning <<
"SymmetricConformation::insert_conformation_by_jump ignores anchor_jump_number" << std::endl;
728 core::Size asymm_insert = ((insert_seqpos-2)%nres_monomer) + 2;
729 core::Size asymm_anchor = ((anchor_pos-1)%nres_monomer) + 1;
734 for (
int i=nsubunits; i>=1; --i ) {
735 core::Size insert_i = (i-1)*nres_monomer+asymm_insert;
736 core::Size anchor_i = (i-1)*nres_monomer+asymm_anchor;
739 if ( !
symm_info_->bb_is_independent( anchor_i ) ) {
770 using namespace graph;
771 using namespace basic::options;
776 for (
Size ii = 1; ii <=
size(); ++ii ) {
779 resid_2_cysid[ ii ] = num_cys;
782 if ( num_cys == 0 )
return;
786 for (
Size ii = 1; ii <=
size(); ++ii ) {
787 if ( resid_2_cysid[ ii ] != 0 ) {
788 cysid_2_resid[ resid_2_cysid[ ii ]] = ii;
794 for(
Size ii = 1; ii <= num_cys; ++ii) {
795 if(
residue_type(cysid_2_resid[ii]).residue_type_set().name()
803 Real const typical_disulfide_distance = fullatom? 2.02 : 3.72;
804 Real const tolerance = option[OptionKeys::in::detect_disulf_tolerance].user()
805 ? option[OptionKeys::in::detect_disulf_tolerance]()
806 : ( fullatom? 0.5 : 1.0 );
807 std::string const distance_atom = fullatom?
"SG" :
"CB";
811 pg->set_num_vertices( num_cys );
813 Distance maxd( typical_disulfide_distance + tolerance );
814 for (
Size ii = 1; ii <= num_cys; ++ii ) {
816 pg->get_vertex(ii).data().xyz() = ii_res.
atoms()[ ii_res.
nbr_atom() ].xyz();
819 Distance neighbor_cutoff = maxrad + maxd;
825 std::set< Size > processed_cys;
826 for (
Size ii = 1; ii <= num_cys; ++ii ) {
827 Size const ii_resid = cysid_2_resid[ ii ];
828 if(ii_resid >
symm_info_->num_independent_residues())
continue;
832 if( processed_cys.find( ii_resid) != processed_cys.end() ) {
837 Size ii_sg_atomno(0);
843 TR.Error <<
"Error: Can't find an atom to disulfide bond from at residue "<< ii_resid <<std::endl;
848 Size best_neighbor( 0 );
852 ii_iter = pg->get_vertex( ii ).upper_edge_list_begin(),
853 ii_end_iter = pg->get_vertex( ii ).upper_edge_list_end();
854 ii_iter != ii_end_iter; ++ii_iter ) {
855 Size const jj = ii_iter->upper_vertex();
857 Size const jj_resid = cysid_2_resid[ jj ];
862 if( processed_cys.find( jj_resid) != processed_cys.end() ) {
868 if ( best_neighbor == 0 || dist < best_match ) {
869 best_neighbor = jj_resid;
875 if ( best_neighbor == 0 || best_match >= typical_disulfide_distance + tolerance ) {
879 TR <<
"Reverting out-of-date disulfide CYD to CYS at resid " << ii_resid << std::endl;
882 if ( !successful_revert ) {
883 TR.Error <<
"ERROR: unable to revert CYD to CYS for removal of disulfide at resid " << ii_resid << std::endl;
888 processed_cys.insert( ii_resid );
898 TR <<
"Found "<< (fullatom?
"":
"CEN ") <<
"disulfide between residues " << ii_resid <<
" " << best_neighbor << std::endl;
899 TR <<
"current variant for " << ii_resid <<
" " << (
residues_[ ii_resid ]->has_variant_type(
chemical::DISULFIDE ) ?
"CYD" :
"CYS" ) << std::endl;
900 TR <<
"current variant for " << best_neighbor <<
" " << (
residues_[ best_neighbor ]->has_variant_type(
chemical::DISULFIDE ) ?
"CYD" :
"CYS" ) << std::endl;
907 if ( !success_at_ii ) {
908 TR.Error <<
"ERROR: unable to create residue type CYD for disulfide at resid " << ii_resid << std::endl;
911 if ( !success_at_best_neighbor ) {
912 TR.Error <<
"ERROR: unable to create residue type CYD for disulfide at resid " << best_neighbor << std::endl;
915 TR <<
"current variant for " << ii_resid <<
" " << (
residues_[ ii_resid ]->has_variant_type(
chemical::DISULFIDE ) ?
"CYD" :
"CYS" ) << std::endl;
916 TR <<
"current variant for " << best_neighbor <<
" " << (
residues_[ best_neighbor ]->has_variant_type(
chemical::DISULFIDE ) ?
"CYD" :
"CYS" ) << std::endl;
919 if ( success_at_ii && success_at_best_neighbor ) {
923 Size jj_resid = best_neighbor;
925 Size jj_sg_atomno(0);
931 TR.Error <<
"Error: Can't find an atom to disulfide bond from at residue "<< jj_resid <<std::endl;
937 residues_[ ii_resid ]->residue_connection_partner( ii_connid, jj_resid, jj_connid );
938 residues_[ jj_resid ]->residue_connection_partner( jj_connid, ii_resid, ii_connid );
941 processed_cys.insert( ii_resid );
942 processed_cys.insert( best_neighbor );