38 #include <basic/Tracer.hh>
39 #include <basic/prof.hh>
40 #include <basic/basic.hh>
41 #include <basic/options/option.hh>
42 #include <basic/options/keys/in.OptionKeys.gen.hh>
46 #include <numeric/constants.hh>
49 #include <ObjexxFCL/format.hh>
50 #include <ObjexxFCL/string.functions.hh>
53 #include <numeric/xyz.functions.hh>
57 #include <utility/assert.hh>
58 #include <utility/exit.hh>
59 #include <utility/pointer/owning_ptr.hh>
60 #include <utility/pointer/access_ptr.hh>
76 #include <utility/vector1.hh>
77 #include <numeric/random/random.fwd.hh>
78 #include <boost/foreach.hpp>
82 #define foreach BOOST_FOREACH
88 static basic::Tracer
TR(
"core.conformation.Conformation");
91 namespace conformation {
93 using namespace ObjexxFCL;
99 notify_connection_obs(
ConnectionEvent(
this, ConnectionEvent::DISCONNECT ) );
104 utility::pointer::ReferenceCount(),
107 residue_coordinates_need_updating_( false ),
108 residue_torsions_need_updating_( false ),
109 structure_moved_( true )
116 utility::pointer::ReferenceCount()
118 basic::ProfileThis doit( basic::CONFORMATION_COPY );
120 for (
Size i=1; i<= src.
size(); ++i ) {
152 if ( &src ==
this )
return *
this;
154 basic::ProfileThis doit( basic::CONFORMATION_COPY );
164 for (
Size i=1; i<= src.
size(); ++i ) {
229 if (
size() != other.
size() )
return false;
230 for (
Size ii = 1, iiend =
size(); ii <= iiend; ++ii ) {
245 msg +=
"Conformation: fold_tree nres should match conformation nres. conformation nres: ";
246 msg += string_of(
size() );
247 msg +=
" fold_tree nres: " + string_of( fold_tree_in.
nres() ) ;
248 utility_exit_with_message( msg );
251 (*fold_tree_) = fold_tree_in;
283 if ( !connid1 ) utility_exit_with_message( rsd1.
name()+
" doesnt have connection at "+atom_name1 );
284 if ( !connid2 ) utility_exit_with_message( rsd2.
name()+
" doesnt have connection at "+atom_name2 );
302 Size const seqpos ( begin + i );
303 Size const seqpos_src( src_begin + i );
315 bool const orient_backbone
320 Residue const & old_rsd( *old_rsd_ptr );
332 if ( orient_backbone ) {
333 residues_[seqpos]->place( old_rsd, *
this );
354 utility::vector1< std::pair< std::string, std::string > >
const & atom_pairs
362 Residue const & old_rsd( *old_rsd_ptr );
382 Size const anchor_pos,
385 bool const start_new_chain
396 assert( anchor_pos );
418 bool const build_ideal_geometry,
419 int residue_connection_index,
421 int anchor_residue_connection_index,
422 bool const start_new_chain,
423 bool const lookup_bond_length
426 if(!build_ideal_geometry) assert(!lookup_bond_length);
437 bool const polymer_connection( residue_connection_index == 0 );
439 if ( polymer_connection ) anchor_pos = seqpos - 1;
446 if ( polymer_connection ) {
452 assert( anchor_pos && anchor_residue_connection_index );
457 if ( build_ideal_geometry ) {
462 if ( polymer_connection ) {
469 anchor_rsd_connection = anchor_rsd.
residue_connection( anchor_residue_connection_index );
473 ideal_geometry_rsd = new_rsd.
clone();
485 if ( polymer_connection ) {
496 if ( root_atomno ) root_atom = new_rsd.
atom_name( root_atomno );
499 if ( build_ideal_geometry ) {
520 residues_[ seqpos ]->residue_connection_partner( residue_connection_index, anchor_pos, anchor_residue_connection_index );
521 residues_[ anchor_pos ]->residue_connection_partner( anchor_residue_connection_index, seqpos, residue_connection_index );
537 bool const attach_by_jump,
540 bool const start_new_chain
549 bool const first_residue( seqpos == 1 );
557 int anchor_atomno( 0 );
560 if ( anchor_id.
atom().size() ) anchor_atomno =
residues_[ anchor_id.
rsd() ]->atom_index( anchor_id.
atom() );
562 if ( first_residue ) {
566 if ( root_atom.size() ) root_atomno = new_rsd.
atom_index( root_atom );
569 if ( !attach_by_jump && ( new_rsd.
is_ligand() ||
571 residues_[ seqpos-1 ]->is_upper_terminus() ||
573 anchor_atomno !=
int(
residues_[ seqpos-1 ]->upper_connect_atom()) ) ) {
575 TR <<
"appending residue by a chemical bond in the foldtree: " << seqpos <<
' ' <<
576 new_rsd.
name() <<
" anchor: " << anchor_id <<
" root: " << root_atom << std::endl;
577 fold_tree_->append_residue_by_chemical_bond( anchor_id.
rsd(), anchor_id.
atom(), root_atom );
579 fold_tree_->append_residue( attach_by_jump, anchor_id.
rsd(), anchor_id.
atom(), root_atom );
589 if ( first_residue ) {
619 residues_[i]->update_sequence_numbering( old2new );
659 for (
Size i=1, ie=rsd.
natoms(); i<= ie; ++i ) {
665 ( upper_lower == -1 && rsd.
atom_name( i ) ==
" O2P" ) ||
666 ( upper_lower == -1 && rsd.
atom_name( i ) ==
" O1P" ) ||
684 for (
Size i=1, ie=rsd.
natoms(); i<= ie; ++i ) {
698 bool const build_ideal_geometry
713 bool const build_ideal_geometry
720 if ( build_ideal_geometry ) {
725 ideal_geometry_rsd = new_rsd.
clone();
729 bool const join_lower(
true );
730 bool const join_upper( !
fold_tree_->is_cutpoint( seqpos ) );
732 if ( build_ideal_geometry )
insert_polymer_residue( *ideal_geometry_rsd, seqpos+1, join_lower, join_upper );
735 if ( build_ideal_geometry ) {
749 bool const build_ideal_geometry
762 bool const build_ideal_geometry
769 if ( build_ideal_geometry ) {
774 ideal_geometry_rsd = new_rsd.
clone();
779 bool const join_upper(
true );
780 bool const join_lower( !
fold_tree_->is_cutpoint( seqpos-1 ) );
782 if ( build_ideal_geometry )
insert_polymer_residue( *ideal_geometry_rsd, seqpos, join_lower, join_upper );
785 if ( build_ideal_geometry ) {
826 Size const range_size( range_end - range_begin + 1 );
827 assert( range_size >= 1);
828 for (
Size i=1; i<= range_size; ++i ) {
850 assert( !
fold_tree_->is_jump_point( seqpos ) );
875 bool const join_lower,
876 bool const join_upper
889 fold_tree_->insert_polymer_residue( seqpos, join_lower, join_upper );
915 ASSERT_ONLY(
Size const old_size(
size() );)
917 assert(
fold_tree_->is_cutpoint( seqpos-1 ) );
931 assert( new_rsd.
seqpos() == seqpos );
933 fold_tree_->insert_residue_by_jump( seqpos, anchor_pos , anchor_atom, root_atom );
956 Size const insert_seqpos,
957 Size const insert_jumppos,
958 Size const anchor_pos,
959 Size const anchor_jump_number,
969 Size const insert_size( conf.
size() );
970 Size const new_size( old_size + insert_size );
974 bool const fold_tree_polymer_bond( !
fold_tree_->is_cutpoint( insert_seqpos-1 ) );
975 bool const residues_polymer_bond( insert_seqpos > 1 && insert_seqpos <= old_size &&
976 residue( insert_seqpos-1 ).is_polymer_bonded( insert_seqpos ) );
977 if ( fold_tree_polymer_bond || residues_polymer_bond ) {
978 utility_exit_with_message(
"cant insert 'by_jump' into a polymer stretch");
984 for (
Size i=1; i<= old_size; ++i ) old2new.push_back( ( i >= insert_seqpos ) ? i+insert_size : i );
991 for (
Size i=1; i<= insert_size; ++i ) old2new.push_back( i+insert_seqpos-1 );
994 for (
Size i=1; i<= insert_size; ++i ) {
996 new_rsd->update_sequence_numbering( old2new );
997 Size const new_seqpos( old2new[i] );
1010 new_chain_endings.push_back( (*ch<insert_seqpos ? *ch : *ch + insert_size ) );
1012 for (
Size i=1; i< conf.
num_chains(); ++i ) new_chain_endings.push_back( conf.
chain_end(i) + insert_seqpos-1 );
1013 if ( insert_seqpos > 1 &&
1014 std::find(new_chain_endings.begin(),new_chain_endings.end(),insert_seqpos-1) == new_chain_endings.end())
1015 new_chain_endings.push_back( insert_seqpos-1 );
1016 if ( insert_seqpos <= old_size &&
1017 std::find(new_chain_endings.begin(),new_chain_endings.end(),insert_seqpos+insert_size-1) == new_chain_endings.end())
1018 new_chain_endings.push_back( insert_seqpos+insert_size-1 );
1019 std::sort( new_chain_endings.begin(), new_chain_endings.end() );
1025 fold_tree_->insert_fold_tree_by_jump( conf.
fold_tree(), insert_seqpos, insert_jumppos, anchor_pos, anchor_jump_number,
1026 anchor_atom, root_atom );
1050 Size const seqpos( edge.stop() );
1052 if ( edge.has_atom_info() ) {
1058 return AtomID( atomno, seqpos );
1074 residues_[
id.rsd() ]->set_xyz(
id.atomno(), position );
1086 runtime_assert( ids.size() == positions.size() );
1093 residues_[ ids[i].rsd() ]->set_xyz( ids[i].atomno(), positions[i] );
1106 positions.resize( ids.size() );
1110 positions[i] =
xyz( ids[i] );
1122 int const rb_no( tor_id.
torsion() );
1123 assert( rb_no >= 1 && rb_no <= 6 );
1124 int const jump_number( tor_id.
rsd() );
1130 AtomID id1, id2, id3, id4;
1138 return atom_tree_->torsion_angle_dof_id( id1, id2, id3, id4 );
1147 using numeric::conversions::degrees;
1178 using numeric::conversions::radians;
1200 AtomID id1, id2, id3, id4;
1208 (
atom_tree_->set_torsion_angle( id1, id2, id3, id4, radians(setting) ) );
1210 if ( !dof_id.valid() ) {
1212 TR.Warning <<
"Unable to find torsion angle in atom_tree: " <<
1213 tor_id << std::endl;
1235 Size const seqpos( tor_id.
rsd() );
1243 id1.
rsd() = id2.
rsd() = id3.
rsd() = id4.
rsd() = seqpos;
1249 std::cerr <<
"Conformation::get_torsion_angle_atom_ids: " << tor_id <<
1250 " Jump 'torsions' are not described by four atoms!" << std::endl;
1268 DOF_ID const dof_id(
atom_tree_->set_torsion_angle( atom1, atom2, atom3, atom4, setting ) );
1269 if ( dof_id.valid() ) {
1272 TR <<
"set_torsion_angle failed, unable to find dof_id: " << atom1 <<
' ' << atom2 <<
' ' << atom3 <<
' ' <<
1299 Real const bond_distance( connect1.icoor().d() );
1300 Real const bond_angle1( numeric::constants::d::pi - connect1.icoor().theta() );
1301 Real const bond_angle2( numeric::constants::d::pi - connect2.icoor().theta() );
1303 assert( ( connect1.icoor().stub_atom2().atomno() ==
Size( atom1.atomno() ) ) &&
1304 ( connect1.icoor().stub_atom1().atomno() ==
Size( atom2.atomno() ) ) &&
1305 ( connect2.icoor().stub_atom1().atomno() ==
Size( atom3.atomno() ) ) &&
1306 ( connect2.icoor().stub_atom2().atomno() ==
Size( atom4.atomno() ) ) );
1331 Size const pos2( rsd1->connect_map( connid1 ).resid() );
1332 Size const connid2( rsd1->connect_map( connid1 ).connid() );
1339 Real const bond_distance( connect1.icoor().d() );
1340 Real const bond_angle1( numeric::constants::d::pi - connect1.icoor().theta() );
1341 Real const bond_angle2( numeric::constants::d::pi - connect2.icoor().theta() );
1343 AtomID const atom1( connect1.icoor().stub_atom2().atomno(), pos1 );
1344 AtomID const atom2( connect1.icoor().stub_atom1().atomno(), pos1 );
1345 AtomID const atom3( connect2.icoor().stub_atom1().atomno(), pos2 );
1346 AtomID const atom4( connect2.icoor().stub_atom2().atomno(), pos2 );
1370 DOF_ID const dof_id(
atom_tree_->set_bond_angle( atom1, atom2, atom3, setting ) );
1371 if ( dof_id.valid() ) {
1384 DOF_ID const dof_id(
atom_tree_->set_bond_length( atom1, atom2, setting ) );
1385 if ( dof_id.valid() ) {
1394 FragRT const & outstub_transforms,
1400 atom_tree_->insert_fragment( instub_id, outstub_transforms, frag_xyz, moved_atoms );
1402 for (
Size i=1; i<= moved_atoms.size(); ++i ) {
1445 if ( lower_seqpos < 1 || lower_seqpos >=
size() )
return;
1449 bool const disconnected(
1450 lower.chain() != upper.
chain() || lower.is_upper_terminus() ||
1468 Size const lr_conn_id(
residue_( res_id_lower ).type().upper_connect_id());
1469 Size const ur_conn_id(
residue_( res_id_upper ).type().lower_connect_id());
1470 residues_[ res_id_lower ]->residue_connection_partner( lr_conn_id, res_id_upper, ur_conn_id );
1471 residues_[ res_id_upper ]->residue_connection_partner( ur_conn_id, res_id_lower, lr_conn_id );
1477 using namespace graph;
1480 Size num_incomp( 0 );
1481 for (
Size ii = 1; ii <=
size(); ++ii ) {
1484 resid_2_incomp[ ii ] = num_incomp;
1487 if ( num_incomp == 0 )
return;
1489 TR.Debug <<
"Looking for connection partners for " << num_incomp <<
" residues" << std::endl;
1492 for (
Size ii = 1; ii <=
size(); ++ii ) {
1493 if ( resid_2_incomp[ ii ] != 0 ) {
1494 incomp_2_resid[ resid_2_incomp[ ii ]] = ii;
1500 pg->set_num_vertices( num_incomp );
1503 for (
Size ii = 1; ii <= num_incomp; ++ii ) {
1505 pg->get_vertex(ii).data().xyz() = ii_res.
atoms()[ ii_res.
nbr_atom() ].xyz();
1518 Distance neighbor_cutoff = maxrad + maxd;
1519 find_neighbors<core::conformation::PointGraphVertexData,core::conformation::PointGraphEdgeData>( pg, neighbor_cutoff );
1522 for (
Size ii = 1; ii <= num_incomp; ++ii ) {
1523 Size const ii_resid = incomp_2_resid[ ii ];
1526 for (
Size jj = 1; jj <= ii_n_conn; ++jj ) {
1532 Distance best_match( 0.0 ), best_jj( 0.0 ), best_kk( 0.0 );
1533 Size best_match_resid( 0 );
1534 Size best_match_connid( 0 );
1537 ii_iter = pg->get_vertex( ii ).upper_edge_list_begin(),
1538 ii_end_iter = pg->get_vertex( ii ).upper_edge_list_end();
1539 ii_iter != ii_end_iter; ++ii_iter ) {
1540 Size const neighb_id = ii_iter->upper_vertex();
1541 Size const neighb_resid = incomp_2_resid[ neighb_id ];
1545 for (
Size kk = 1; kk <= neighb_n_conn; ++kk ) {
1559 if ( multiple_connections_for_jjatom ) {
1561 jj_distance += jj_expected_coord.distance( neighb.
xyz( kkatom ) );
1564 if ( multiple_connections_for_kkatom ) {
1566 kk_distance += kk_expected_coord.distance( ii_res.
xyz( jjatom ));
1569 if ( best_match_resid == 0 || best_match > kk_distance + jj_distance ) {
1570 best_match = kk_distance + jj_distance;
1571 best_jj = jj_distance; best_kk = kk_distance;
1572 best_match_resid = neighb_resid;
1573 best_match_connid = kk;
1578 if ( best_match_resid == 0 ) {
1579 TR.Warning <<
"Failed to find a residue connection for residue " << ii_resid <<
" with connection point " << jj << std::endl;
1583 TR.Info <<
"Connecting residues: " << ii_resid <<
" ( " << ii_res.
name();
1584 TR.Info <<
" ) and " << best_match_resid <<
" ( " <<
residue( best_match_resid ).
name() <<
" )";
1585 TR.Info <<
" at atoms ";
1588 TR.Info <<
residue( best_match_resid ).
type().
atom_name(
residue( best_match_resid ).type().residue_connection( best_match_connid ).atomno() );
1589 TR.Info << std::endl;
1590 TR.Info <<
" with mututal distances: " << best_jj <<
" and " << best_kk << std::endl;
1592 residues_[ ii_resid ]->residue_connection_partner( jj, best_match_resid, best_match_connid );
1593 residues_[ best_match_resid ]->residue_connection_partner( best_match_connid, ii_resid, jj );
1602 for (
Size ii = 1; ii <=
size(); ++ii ) {
1606 for (
Size jj = 1; jj <= ii_nresconn; ++jj ) {
1608 for (
Size kk = jj + 1; kk <= ii_nresconn; ++kk ) {
1619 Size const lr = jj_conn_res < kk_conn_res ? jj_conn_res : kk_conn_res;
1620 Size const lri = jj_conn_res < kk_conn_res ? jj_conn_id : kk_conn_id ;
1621 Size const ur = jj_conn_res < kk_conn_res ? kk_conn_res : jj_conn_res;
1622 Size const uri = jj_conn_res < kk_conn_res ? kk_conn_id : jj_conn_id ;
1623 if(! (lr && lri && ur && uri))
continue;
1626 TR.Info <<
"Adding PseudoBond between residues " << lr <<
" " << ur <<
", connecting atoms ";
1629 TR.Info <<
" through residue " << ii <<
" at atoms " << ii_res.
type().
atom_name( jj_atid );
1631 TR.Info <<
" which are separated by " << ii_res.
path_distance(kk_atid, jj_atid );
1632 TR.Info <<
" bond"<< (ii_res.
path_distance(kk_atid, jj_atid ) == 1 ?
"" :
"s") << std::endl;
1635 if ( kk_atid == jj_atid ) {
1640 for (
Size ll = 1; ll <= 2; ++ll ) {
1641 Size const ll_resid = two_neighbors[ ll ].resid();
1642 if ( ll_resid < ii )
continue;
1644 Size const ll_connid = two_neighbors[ ll ].connid();
1648 for (
Size mm = 1; mm <= ll_nconn; ++mm ) {
1649 if ( mm == ll_connid )
continue;
1651 if ( mm_atid != ll_atid )
continue;
1666 Size const lr = ll_conn_res < mm_conn_res ? ll_conn_res : mm_conn_res;
1667 Size const lri = ll_conn_res < mm_conn_res ? ll_conn_id : mm_conn_id ;
1668 Size const ur = ll_conn_res < mm_conn_res ? mm_conn_res : ll_conn_res;
1669 Size const uri = ll_conn_res < mm_conn_res ? mm_conn_id : ll_conn_id ;
1673 TR.Info <<
"Adding PseudoBond between residues " << lr <<
" " << ur <<
", connecting atoms ";
1676 TR.Info <<
" through two residues: " << ii <<
" and " << ll_resid <<
" at atoms " << ii_res.
type().
atom_name( jj_atid );
1678 TR.Info <<
" which are separated by 1 bond" << std::endl;
1697 typedef std::pair<Size,Size> SizePair;
1698 foreach(SizePair disulfide_bond, disulf_bonds){
1701 Size l_index = (disulfide_bond).first;
1702 Size u_index = (disulfide_bond).second;
1705 if(l_index >
size() ) {
1706 TR.Error <<
"[ERROR] Residue " << l_index <<
" is out of range." << std::endl;
1709 if(u_index >
size() ) {
1710 TR.Error <<
"[ERROR] Residue " << u_index <<
" is out of range." << std::endl;
1718 TR.Error <<
"Failed to introduce CYD for disulfide ("
1719 << l_index <<
", "<< u_index <<
")." << std::endl;
1732 Size l_bond_atom, u_bond_atom;
1742 TR.Warning <<
"Bonding SG of residue " << l_index
1743 <<
" to non-SG of residue "<< u_index << std::endl;
1745 else if(l_has_cen) {
1749 TR.Error <<
"Cannot form disulfide bond with residue "<<l_index<< std::endl;
1756 TR.Warning <<
"Bonding SG of residue " << u_index
1757 <<
" to non-SG of residue "<< l_index << std::endl;
1759 else if(u_has_cen) {
1767 TR.Error <<
"Cannot form disulfide bond with residue "<<l_index<< std::endl;
1785 residues_[ l_index ]->residue_connection_partner( l_connid, u_index, u_connid);
1786 residues_[ u_index ]->residue_connection_partner( u_connid, l_index, l_connid);
1804 basic::ProfileThis doit( basic::CONFORMATION_DETECT_DISULF );
1805 using namespace graph;
1806 using namespace basic::options;
1811 for (
Size ii = 1; ii <=
size(); ++ii ) {
1814 resid_2_cysid[ ii ] = num_cys;
1817 if ( num_cys == 0 )
return;
1821 for (
Size ii = 1; ii <=
size(); ++ii ) {
1822 if ( resid_2_cysid[ ii ] != 0 ) {
1823 cysid_2_resid[ resid_2_cysid[ ii ]] = ii;
1828 bool fullatom(
true);
1829 for(
Size ii = 1; ii <= num_cys; ++ii) {
1830 if(
residue_type(cysid_2_resid[ii]).residue_type_set().name()
1838 Real const typical_disulfide_distance = fullatom? 2.02 : 3.72;
1839 Real const tolerance = option[OptionKeys::in::detect_disulf_tolerance].user()
1840 ? option[OptionKeys::in::detect_disulf_tolerance]()
1841 : ( fullatom? 0.5 : 1.0 );
1842 std::string const distance_atom = fullatom?
"SG" :
"CB";
1846 pg->set_num_vertices( num_cys );
1848 Distance maxd( typical_disulfide_distance + tolerance );
1849 for (
Size ii = 1; ii <= num_cys; ++ii ) {
1851 pg->get_vertex(ii).data().xyz() = ii_res.
atoms()[ ii_res.
nbr_atom() ].xyz();
1854 Distance neighbor_cutoff = maxrad + maxd;
1860 std::set< Size > processed_cys;
1861 for (
Size ii = 1; ii <= num_cys; ++ii ) {
1862 Size const ii_resid = cysid_2_resid[ ii ];
1867 if( processed_cys.find( ii_resid) != processed_cys.end() ) {
1872 Size ii_sg_atomno(0);
1878 TR.Error <<
"Error: Can't find an atom to disulfide bond from at residue "<< ii_resid <<std::endl;
1883 Size best_neighbor( 0 );
1887 ii_iter = pg->get_vertex( ii ).upper_edge_list_begin(),
1888 ii_end_iter = pg->get_vertex( ii ).upper_edge_list_end();
1889 ii_iter != ii_end_iter; ++ii_iter ) {
1890 Size const jj = ii_iter->upper_vertex();
1892 Size const jj_resid = cysid_2_resid[ jj ];
1897 if( processed_cys.find( jj_resid) != processed_cys.end() ) {
1903 if ( best_neighbor == 0 || dist < best_match ) {
1904 best_neighbor = jj_resid;
1910 if ( best_neighbor == 0 || best_match >= typical_disulfide_distance + tolerance ) {
1915 TR <<
"Reverting out-of-date disulfide CYD to CYS at resid " << ii_resid << std::endl;
1918 if ( !successful_revert ) {
1919 TR.Error <<
"ERROR: unable to revert CYD to CYS for removal of disulfide at resid " << ii_resid << std::endl;
1924 processed_cys.insert( ii_resid );
1934 TR <<
"Found "<< (fullatom?
"":
"CEN ") <<
"disulfide between residues " << ii_resid <<
" " << best_neighbor << std::endl;
1935 TR <<
"current variant for " << ii_resid <<
" " << (
residues_[ ii_resid ]->has_variant_type(
chemical::DISULFIDE ) ?
"CYD" :
"CYS" ) << std::endl;
1936 TR <<
"current variant for " << best_neighbor <<
" " << (
residues_[ best_neighbor ]->has_variant_type(
chemical::DISULFIDE ) ?
"CYD" :
"CYS" ) << std::endl;
1943 if ( !success_at_ii ) {
1944 TR.Error <<
"ERROR: unable to create residue type CYD for disulfide at resid " << ii_resid << std::endl;
1947 if ( !success_at_best_neighbor ) {
1948 TR.Error <<
"ERROR: unable to create residue type CYD for disulfide at resid " << best_neighbor << std::endl;
1951 TR <<
"current variant for " << ii_resid <<
" " << (
residues_[ ii_resid ]->has_variant_type(
chemical::DISULFIDE ) ?
"CYD" :
"CYS" ) << std::endl;
1952 TR <<
"current variant for " << best_neighbor <<
" " << (
residues_[ best_neighbor ]->has_variant_type(
chemical::DISULFIDE ) ?
"CYD" :
"CYS" ) << std::endl;
1955 if ( success_at_ii && success_at_best_neighbor ) {
1959 Size jj_resid = best_neighbor;
1961 Size jj_sg_atomno(0);
1967 TR.Error <<
"Error: Can't find an atom to disulfide bond from at residue "<< jj_resid <<std::endl;
1973 residues_[ ii_resid ]->residue_connection_partner( ii_connid, jj_resid, jj_connid );
1974 residues_[ jj_resid ]->residue_connection_partner( jj_connid, ii_resid, ii_connid );
1978 processed_cys.insert( ii_resid );
1979 processed_cys.insert( best_neighbor );
1999 assert(lr_connid>0);
2001 assert(ur_connid>0);
2012 new_pb.
nbonds( 2 + nbonds );
2013 new_pbs->push_back( new_pb );
2014 residues_[ lr ]->set_pseudobonds_to_residue( ur, new_pbs );
2015 residues_[ ur ]->set_pseudobonds_to_residue( lr, new_pbs );
2058 Size const seqpos(
id.rsd() );
2065 Size const ntorsions( mainchain.size() );
2066 assert( torsion >= 1 && torsion <= ntorsions );
2071 id1.
rsd() = id2.
rsd() = id3.
rsd() = id4.
rsd() = seqpos;
2076 id2.
atomno() = mainchain[1];
2077 id3.
atomno() = mainchain[2];
2078 id4.
atomno() = mainchain[3];
2082 id1.
atomno() = mainchain[1];
2083 id2.
atomno() = mainchain[2];
2084 id3.
atomno() = mainchain[3];
2085 id4.
atomno() = mainchain[4];
2089 id1.
atomno() = mainchain[2];
2090 id2.
atomno() = mainchain[3];
2091 id3.
atomno() = mainchain[4];
2096 id1.
atomno() = mainchain[3];
2097 id2.
atomno() = mainchain[4];
2107 if ( torsion > 1 ) {
2109 id1.
atomno() = mainchain[ torsion-1 ];
2127 (
residue_( seqpos-1 ).mainchain_atoms() );
2128 id1.
rsd() = seqpos-1;
2129 id1.
atomno() = prev_mainchain[ prev_mainchain.size() ];
2140 if ( torsion+2 <= ntorsions ) {
2142 id3.
atomno() = mainchain[ torsion+1 ];
2144 id4.
atomno() = mainchain[ torsion+2 ];
2149 if ( torsion+1 == ntorsions ) {
2151 id3.
atomno() = mainchain[ torsion+1 ];
2155 assert( torsion == ntorsions );
2162 if ( torsion+1 == ntorsions ) {
2164 id3.
atomno() = mainchain[ torsion+1 ];
2168 assert( torsion == ntorsions );
2178 if ( torsion == 2 ) {
2182 assert( torsion == 3 );
2192 (
residue_( seqpos+1 ).mainchain_atoms() );
2193 if ( torsion+1 == ntorsions ) {
2195 id3.
atomno() = mainchain[ torsion+1 ];
2196 id4.
rsd() = seqpos+1;
2197 id4.
atomno() = next_mainchain[ 1 ];
2199 assert( torsion == ntorsions );
2200 id3.
rsd() = seqpos+1;
2201 id3.
atomno() = next_mainchain[ 1 ];
2202 if ( next_mainchain.size() >= 2 ) {
2203 id4.
rsd() = seqpos+1;
2204 id4.
atomno() = next_mainchain[ 2 ];
2209 id4.
rsd() = seqpos+1;
2215 id4.
rsd() = seqpos+2;
2240 using numeric::conversions::degrees;
2249 AtomID id1, id2, id3, id4;
2258 return degrees(
atom_tree_->torsion_angle( id1, id2, id3, id4 ) );
2269 for (
Size i=1; i<=
size(); ++i ) {
2271 const_rsds.push_back( &( *
residues_[i] ) );
2297 domain_map.dimension(
size() );
2322 PROF_START( basic::UPDATE_RESIDUE_COORDINATES );
2324 iter_end =
atom_tree_->residue_xyz_change_list_end(); iter != iter_end; ++iter ) {
2327 atom_tree_->note_coordinate_change_registered();
2328 PROF_STOP( basic::UPDATE_RESIDUE_COORDINATES );
2340 for (
Size j=1, j_end = rsd.
natoms(); j<= j_end; ++j ) {
2351 if ( fire_signal ) {
2369 PROF_START( basic::UPDATE_RESIDUE_TORSIONS );
2370 for (
Size i=1, i_end =
size(); i<= i_end; ++i ) {
2374 PROF_STOP( basic::UPDATE_RESIDUE_TORSIONS );
2396 for (
Size j=1, j_end = rsd.
nchi(); j<= j_end; ++j ) {
2403 if ( fire_signal ) {
2413 foreach(
core::Size orbital_index, orbital_indices){
2429 using namespace ObjexxFCL::fmt;
2430 using basic::subtract_degree_angles;
2434 basic::Tracer my_tracer(
"core.conformation", basic::t_warning );
2442 <<
A( width,
"rsd_dihedral" )
2443 <<
A( width,
"atr_dihedral" )
2444 <<
A( width,
"rsd_torsion" )
2445 <<
A( width,
"torsion" )
2446 <<
A( width,
"atr_torsion" )
2449 for (
Size i=1; i<=
size(); ++i ) {
2452 for (
Size r=1; r<= 2; ++r ) {
2458 for (
Size j=1; j<= n; ++j ) {
2460 AtomID atom1,atom2,atom3,atom4;
2465 ( ( j == 1 &&
fold_tree_->is_cutpoint( i-1 ) ) ||
2466 ( j >= n-1 &&
fold_tree_->is_cutpoint( i ) ) ) )
continue;
2468 my_tracer <<
" missed torsion: " << tor_id << std::endl;
2472 Real const rsd_dihedral
2478 Real const atom_tree_dihedral
2479 ( numeric::dihedral(
atom_tree_->xyz( atom1 ),
2484 Real const rsd_torsion
2487 ASSERT_ONLY(
Real const dev
2488 ( std::abs( subtract_degree_angles(rsd_dihedral,atom_tree_dihedral))+
2489 std::abs( subtract_degree_angles(rsd_dihedral,rsd_torsion))+
2490 std::abs( subtract_degree_angles(rsd_dihedral,
torsion(tor_id)))+
2491 std::abs( subtract_degree_angles(rsd_dihedral,
2494 assert( dev < 1e-3 );
2501 << F( width, precision, rsd_dihedral )
2502 << F( width, precision, atom_tree_dihedral )
2503 << F( width, precision, rsd_torsion )
2504 << F( width, precision,
torsion(tor_id) )
2526 for (
Size ii = 1; ii <=
size(); ++ii )
2528 if (
residues_[ ii ]->requires_actcoord() )
2538 if (
residues_[ resid ]->requires_actcoord() ) {
2546 residues_[ resid ]->update_orbital_coords();
2583 for (
Size i = 1; i <=
size(); ++i) {
2586 os <<
"RESCON: " << i <<
' ' << res.
name() <<
" n-conn= " << nconn <<
2589 for (
Size j = 1; j <= nconn; ++j) {
2601 int const connection_index
2625 for (
Size i = 1; i <= intrares_atomnos.size(); ++i) {
2626 if (virt || ! primary_residue.
is_virtual(intrares_atomnos[i]) ) {
2627 neighbors.push_back(
id::AtomID(intrares_atomnos[i], atomid.
rsd()));
2633 for (
Size i = 1; i <= num_connections; ++i) {
2637 Size connected_atomno(
residue(resconid.resid()).residue_connect_atom_index(resconid.connid()));
2638 if (virt || !
residue(resconid.resid()).is_virtual(connected_atomno)) {
2639 neighbors.push_back(
id::AtomID(connected_atomno, resconid.resid()));
2653 using namespace basic;
2657 for (
Size i=1; i<=
size(); ++i ) {
2663 if ( tries > 10000 ) {
2664 utility_exit_with_message(
"too many tries in fill_missing_atoms!");
2666 bool any_missing(
false );
2667 Size num_present = 0;
2668 for (
Size j=1; j<= natoms; ++j ) {
2669 if ( !missing[
AtomID( j, i ) ] ) num_present += 1;
2671 for (
Size j=1; j<= natoms; ++j ) {
2673 if ( missing[
id ] ) {
2676 TR.Warning <<
"[ WARNING ] missing heavyatom: " << rsd.
atom_name(j) <<
2677 " on residue " << rsd.
name() <<
' ' << i << std::endl;
2692 if ( num_present < 3 && !missing[ stub_atom1 ] ) {
2696 using numeric::random::uniform;
2697 Vector xyz1(
xyz( stub_atom1 ) ), xyz2(
xyz( stub_atom2 ) ), xyz3(
xyz( stub_atom3 ) );
2698 if ( missing[ stub_atom2 ] ) xyz2 =
Vector( uniform(), uniform(), uniform() );
2699 if ( missing[ stub_atom3 ] ) xyz3 =
Vector( uniform(), uniform(), uniform() );
2702 missing[id] =
false;
2705 }
else if (
id == stub_atom1 ||
id == stub_atom2 ||
id == stub_atom3 ) {
2713 tmp_rsd->seqpos( i );
2715 for (
Size root_atomno=1; root_atomno<= natoms; ++root_atomno ) {
2716 if ( root_atomno == j )
continue;
2727 if ( !missing[ new_stub_atom1 ] && !missing[ new_stub_atom2 ] && !missing[ new_stub_atom3 ] ) {
2728 TR.Warning <<
"[ WARNING ] Building missing atom (" << rsd.
atom_name( j ) <<
2729 ") at root of residue tree, using stubs: " <<
2730 rsd.
atom_name( new_stub_atom1.atomno() ) <<
' ' <<
2731 rsd.
atom_name( new_stub_atom2.atomno() ) <<
' ' <<
2732 rsd.
atom_name( new_stub_atom3.atomno() ) <<
2733 "\nThis probably means that a torsion angle is being taken from the ideal residue and"
2734 "\nshould be further optimized..." << std::endl;
2736 ( rsd.
xyz( new_stub_atom1.atomno() ),
2737 rsd.
xyz( new_stub_atom2.atomno() ),
2738 rsd.
xyz( new_stub_atom3.atomno() ) );
2742 missing[ id ] =
false;
2746 if ( root_atomno == natoms ) {
2756 if ( !missing[ stub_atom1 ] && !missing[ stub_atom2 ] && !missing[ stub_atom3 ] ) {
2758 missing[ id ] =
false;
2764 if ( !any_missing )
break;
2776 return ( ( *
residues_[ pos ] ).atom_is_backbone( atomno ) );
2802 for (
Size i=1; i<=
size(); ++i ) {
2825 if ( (*i) >=
size() ) {
2826 utility_exit_with_message(
"new chain endings list contains positions >= Conformation::size()");
2840 assert( seqpos >= 1 && seqpos <
size() );
2854 utility_exit_with_message(
"tried to delete nonexistent chain ending");
2872 for (
Size i=1, ie=
size()-1; i<=ie; ++i ) {
2894 int const old_chain =
residues_[ seqpos ]->chain();
2898 residues_[ seqpos ]->chain( old_chain );
2900 residues_[ seqpos ]->copy_residue_connections( *old_residue );
2913 xyz_m.resize( new_rsd.
natoms(), true );
2918 bool any_dof_moved(
false );
2919 for (
Size i=1; i<= dof_m.size(); ++i ) {
2921 any_dof_moved =
true;
2926 dof_m.resize( new_rsd.
natoms(), any_dof_moved );
2942 bool const use_lower_chain,
2943 bool const new_chain
2946 assert( ! new_chain ||
residues_[ seqpos-1 ]->chain() !=
residues_[ seqpos ]->chain() );
2948 Size const old_size(
residues_.size() ), new_size( old_size+1 );
2952 for (
Size i=1; i<= old_size; ++i ) {
2953 if ( i< seqpos ) old2new[i] = i;
2954 else old2new[i] = i+1;
2958 Size const old_chain( ( new_chain || use_lower_chain ||
Size(seqpos) == new_size ) ?
2962 Size const newrsd_chain( new_chain ? old_chain + 1 :old_chain );
2967 residues_[ seqpos ]->chain( newrsd_chain );
2969 for (
Size ii = seqpos+1; ii <= new_size; ++ii ) {
2974 residues_[ seqpos ]->clear_residue_connections();
2988 assert( xyz_m.empty() && dof_m.empty() );
2989 xyz_m.resize( new_rsd.
natoms(), true );
2990 dof_m.resize( new_rsd.
natoms(), false );
3007 Size const old_size(
residues_.size() ), new_size( old_size-1 );
3014 for (
Size i=1; i<= old_size; ++i ) {
3015 if ( i < seqpos ) old2new[i] = i;
3016 else if ( i > seqpos ) old2new[i] = i-1;
3048 if ( start_new_chain ) {
3050 TR.Debug <<
"Starting a new chain: chain " <<
residues_[nres - 1]->chain() << std::endl;
3060 residues_[ nres ]->clear_residue_connections();
3118 if (
this == &src )
return;
3208 for (
Size ii = 1; ii <=
size(); ++ii ) {
3213 for (
Size jj = 1; jj <=
residues_[ ii ]->natoms(); ++jj ) {
3268 if ( fire_general ) {
3280 if ( fire_general ) {
3292 if ( fire_general ) {
3309 Size const seqpos1( std::max( 1, (
int)
size() / 2 ) );
3310 Size const seqpos2( std::min( (
int)
size(), (
int)
size() / 2 + 2 ) );
3335 return atom_tree_->get_stub_transform( stub_id1, stub_id2 );
3375 return atom_tree_->torsion_angle( atom1, atom2, atom3, atom4 );
3386 return atom_tree_->bond_angle( atom1, atom2, atom3 );
3396 return atom_tree_->bond_length( atom1, atom2 );
3408 int const jump_number,
3409 Jump const & new_jump
3421 int const jump_number,
3422 Jump const & new_jump
3441 Jump const & new_jump
3512 // first atom -- may be in seqpos-1
3513 if ( torsion > 1 ) {
3515 id1.atomno() = mainchain[ torsion-1 ];
3517 if ( fold_tree_->is_cutpoint( seqpos-1 ) ) {
3518 if ( rsd.has_variant_type( chemical::CUTPOINT_UPPER ) ) {
3520 id1.atomno() = rsd.atom_index( "OVU1" );
3522 // first bb-torsion is not well-defined
3523 return true; // FAILURE
3526 AtomIndices const & prev_mainchain
3527 ( residue_( seqpos-1 ).mainchain_atoms() );
3528 id1.rsd() = seqpos-1;
3529 id1.atomno() = prev_mainchain[ prev_mainchain.size() ];
3534 // second atom -- for sure in seqpos
3536 id2.atomno() = mainchain[ torsion ];
3539 // third and fourth atoms, may be in seqpos+1
3540 if ( torsion+1 <= ntorsions ) {
3542 id3.atomno() = mainchain[ torsion+1 ];
3545 assert( torsion == ntorsions );
3546 if ( fold_tree_->is_cutpoint( seqpos ) ) {
3547 if ( rsd.has_variant_type( chemical::CUTPOINT_LOWER ) ) {
3549 id3.atomno() = rsd.atom_index( "OVL1" );
3551 // last bb-bond angle not well defined
3552 return true; // FAILURE
3555 AtomIndices const & next_mainchain
3556 ( residue_( seqpos+1 ).mainchain_atoms() );
3557 id3.rsd() = seqpos+1;
3558 id3.atomno() = next_mainchain[ 1 ];
3559 } // seqpos is a cutpoint
3560 } // torsion+1 <= ntorsions
3565 // returns TRUE for FAILURE
3568 Conformation::backbone_bond_length_atoms(
3569 TorsionID const & id,
3574 using chemical::AtomIndices;
3576 int const seqpos( id.rsd() );
3577 int const torsion( id.torsion() );
3579 Residue const & rsd( *residues_[ seqpos ] );
3581 AtomIndices const & mainchain( rsd.mainchain_atoms() );
3583 int const ntorsions( mainchain.size() );
3584 assert( torsion >= 1 && torsion <= ntorsions );
3587 // first atom -- may be in seqpos-1
3588 if ( torsion > 1 ) {
3590 id1.atomno() = mainchain[ torsion-1 ];
3592 if ( fold_tree_->is_cutpoint( seqpos-1 ) ) {
3593 if ( rsd.has_variant_type( chemical::CUTPOINT_UPPER ) ) {
3595 id1.atomno() = rsd.atom_index( "OVU1" );
3597 // first bb-torsion is not well-defined
3598 return true; // FAILURE
3601 AtomIndices const & prev_mainchain
3602 ( residue_( seqpos-1 ).mainchain_atoms() );
3603 id1.rsd() = seqpos-1;
3604 id1.atomno() = prev_mainchain[ prev_mainchain.size() ];
3609 // second atom -- for sure in seqpos
3611 id2.atomno() = mainchain[ torsion ];
3613 return false; // no failure