52 #include <basic/options/option.hh>
56 #include <numeric/constants.hh>
64 #include <basic/Tracer.hh>
68 #include <basic/options/keys/enzdes.OptionKeys.gen.hh>
72 #include <utility/vector1.hh>
74 #include <utility/string_util.hh>
77 static basic::Tracer
tr(
"protocols.toolbox.match_enzdes_util.EnzConstraintParameters");
81 namespace match_enzdes_util {
83 using namespace ObjexxFCL;
94 resA_basename_(resA_base_in), resB_basename_(resB_base_in),
95 resA_varname_(resA_var_in), resB_varname_(resB_var_in),
96 resA_modname_(resA_base_in + resA_var_in), resB_modname_(resB_base_in+resB_var_in),
97 resA_seqpos_(Apos_in), resB_seqpos_(Bpos_in),
98 restype_set_(restype_set_in)
104 resA_basename_(other.resA_basename_), resB_basename_(other.resB_basename_),
105 resA_varname_(other.resA_varname_), resB_varname_(other.resB_varname_),
106 resA_modname_(other.resA_modname_), resB_modname_(other.resB_modname_),
107 resA_seqpos_(other.resA_seqpos_), resB_seqpos_(other.resB_seqpos_),
108 restype_set_(other.restype_set_)
132 for(
core::Size var = 1; var <= curA_variants.size(); var++){
143 for(
core::Size var = 1; var <= curB_variants.size(); var++){
159 if( (
resA_seqpos_ == 0) || (
resB_seqpos_ == 0 ) ) utility_exit_with_message(
"A covalently constrained residue apparently got deleted from the pose");
167 : utility::pointer::ReferenceCount(),
169 ndisAB_(0), nangleA_(0), nangleB_(0), ntorsionA_(0), ntorsionB_(0), ntorsionAB_(0),
170 restype_set_( src_restype_set), enz_io_( src_enz_io ), cst_block_(cst_block)
173 resA_->set_param_index( 1 );
175 resB_->set_param_index( 2 );
181 : utility::pointer::ReferenceCount(),
182 resA_(NULL), resB_(NULL), mcfi_(NULL),disAB_(NULL),
183 angleA_(NULL), angleB_(NULL), torsionA_(NULL),
184 torsionB_(NULL), torsionAB_(NULL),
185 ndisAB_(0), nangleA_(0), nangleB_(0), ntorsionA_(0),
186 ntorsionB_(0), ntorsionAB_(0),
187 is_covalent_(false), empty_(true),
188 restype_set_( NULL), enz_io_( NULL), cst_block_(0)
196 utility::pointer::ReferenceCount(),
198 disAB_(other.disAB_), angleA_(other.angleA_), angleB_(other.angleB_),
199 torsionA_(other.torsionA_), torsionB_(other.torsionB_), torsionAB_(other.torsionAB_),
200 ndisAB_(other.ndisAB_), nangleA_(other.nangleA_), nangleB_(other.nangleB_),
201 ntorsionA_(other.ntorsionA_), ntorsionB_(other.ntorsionB_), ntorsionAB_(other.ntorsionAB_),
202 is_covalent_(other.is_covalent_), empty_(other.empty_),
203 restype_set_( other.restype_set_),
204 cst_block_(other.cst_block_)
220 if(
mcfi_ == mcfi )
return;
225 resA_->set_param_index( 1 );
227 resB_->set_param_index( 2 );
228 resA_->identical_info_consistency_check();
229 resB_->identical_info_consistency_check();
238 if(
mcfi_->dis_U1D1() ){
246 min_dis, max_dis, sqrt(1/ force_k_dis),
"dis");
261 core::Real const rad_per_deg = numeric::constants::f::degrees_to_radians;
262 core::Real const twopi = numeric::constants::f::pi_2;
268 if( !gsi )
return to_return;
270 ideal_val = gsi->ideal_val() * rad_per_deg;
272 if( gsi->force_const() == 0.0 )
return to_return;
274 core::Real x0 = gsi->ideal_val() * rad_per_deg;
275 core::Real x_sd = gsi->tolerance() * rad_per_deg;
276 core::Real period_rad = gsi->periodicity() * rad_per_deg;
278 if( gsi->function_tag() ==
"PERIODIC" ){
280 if( ( gsi->tag() ==
"angle_A:" ) || ( gsi->tag() ==
"angle_B:" ) ){
281 std::cerr <<
"Error in cstfile reading: periodic functions are not supported for angle constraints." << std::endl;
282 utility::exit( EXIT_FAILURE, __FILE__, __LINE__);
286 tr.Info <<
"WARNING: Constraint specified for tag " << gsi->tag() <<
" requests a periodic function. Standard-Deviation/tolerance is meaningless in this case. The tolerance value of " << gsi->tolerance() <<
" that you specified will be ignored!" << std::endl;
309 using namespace core::scoring::constraints;
312 bool all_constraints_empty =
true;
315 runtime_assert( param_cache );
316 param_cache->active_pose_constraints_.clear();
319 Size number_constraints_added(0);
323 for (std::map< Size, EnzCstTemplateResAtomsOP >::const_iterator resApos_it = param_cache->template_res_cache_[1]->seqpos_map_begin(), resApos_end = param_cache->template_res_cache_[1]->seqpos_map_end(); resApos_it != resApos_end; ++resApos_it){
325 for (std::map< Size, EnzCstTemplateResAtomsOP >::const_iterator resBpos_it = param_cache->template_res_cache_[2]->seqpos_map_begin(), resBpos_end = param_cache->template_res_cache_[2]->seqpos_map_end(); resBpos_it != resBpos_end; ++resBpos_it){
329 Size ambig_resA(resApos_it->second->atom1_.size()), ambig_resB(resBpos_it->second->atom1_.size());
331 Size number_ambiguous_constraints = ambig_resA * ambig_resB;
332 if( number_ambiguous_constraints != 1){
333 tr.Info <<
"Constraint specified between residues " << resApos_it->first <<
" and " << resBpos_it->first <<
" is ambiguous, " << number_ambiguous_constraints <<
" different possibilities ( " << ambig_resA <<
" for " << resApos_it->first <<
", " << ambig_resB <<
" for " << resBpos_it->first <<
".)" << std::endl;
339 for(
Size ambig_resA_count(0); ambig_resA_count < ambig_resA; ambig_resA_count++){
341 for(
Size ambig_resB_count(0); ambig_resB_count < ambig_resB; ambig_resB_count++){
347 all_constraints_empty =
false;
348 this_pair_csts.push_back(
new AtomPairConstraint( resApos_it->second->atom1_[ambig_resA_count], resBpos_it->second->atom1_[ambig_resB_count],
disAB_) );
349 number_constraints_added++;
351 if(basic::options::option[basic::options::OptionKeys::enzdes::enz_debug] )
355 tr <<
"adding distance constraint between atom " << at1name <<
"of res " << resApos_it->first <<
" and atom " << at2name <<
" of resi " << resBpos_it->first <<
"." << std::endl;
361 all_constraints_empty =
false;
362 this_pair_csts.push_back(
new AngleConstraint( resApos_it->second->atom2_[ambig_resA_count], resApos_it->second->atom1_[ambig_resA_count], resBpos_it->second->atom1_[ambig_resB_count],
angleA_) );
363 number_constraints_added++;
366 if(basic::options::option[basic::options::OptionKeys::enzdes::enz_debug] )
371 tr <<
"adding angle constraint between atoms " << at1name <<
" and " << at2name <<
"of res " << resApos_it->first <<
" and atom " << at3name <<
" of resi " << resBpos_it->first <<
"." << std::endl;
377 all_constraints_empty =
false;
378 this_pair_csts.push_back(
new AngleConstraint( resApos_it->second->atom1_[ambig_resA_count], resBpos_it->second->atom1_[ambig_resB_count], resBpos_it->second->atom2_[ambig_resB_count],
angleB_) );
379 number_constraints_added++;
382 if(basic::options::option[basic::options::OptionKeys::enzdes::enz_debug] )
387 tr <<
"adding angle constraint between atoms " << at1name <<
"of res " << resApos_it->first <<
" and atom " << at2name <<
" and " << at3name <<
" of resi " << resBpos_it->first <<
"." << std::endl;
394 all_constraints_empty =
false;
395 this_pair_csts.push_back(
new DihedralConstraint( resApos_it->second->atom3_[ambig_resA_count], resApos_it->second->atom2_[ambig_resA_count], resApos_it->second->atom1_[ambig_resA_count], resBpos_it->second->atom1_[ambig_resB_count],
torsionA_) );
396 number_constraints_added++;
399 if(basic::options::option[basic::options::OptionKeys::enzdes::enz_debug] )
405 tr <<
"adding dihedral constraint between atoms " << at1name <<
" and " << at2name <<
" and " << at3name <<
" of res " << resApos_it->first <<
" and atom " << at4name <<
" of resi " << resBpos_it->first <<
"." << std::endl;
412 all_constraints_empty =
false;
413 this_pair_csts.push_back(
new DihedralConstraint( resApos_it->second->atom1_[ambig_resA_count], resBpos_it->second->atom1_[ambig_resB_count], resBpos_it->second->atom2_[ambig_resB_count], resBpos_it->second->atom3_[ambig_resB_count],
torsionB_) );
414 number_constraints_added++;
417 if(basic::options::option[basic::options::OptionKeys::enzdes::enz_debug] )
423 tr <<
"adding dihedral constraint between atoms " << at1name <<
" of res " << resApos_it->first <<
" and " << at2name <<
" and " << at3name <<
" and " << at4name <<
" of resi " << resBpos_it->first <<
"." << std::endl;
429 all_constraints_empty =
false;
430 this_pair_csts.push_back(
new DihedralConstraint( resApos_it->second->atom2_[ambig_resA_count], resApos_it->second->atom1_[ambig_resA_count], resBpos_it->second->atom1_[ambig_resB_count], resBpos_it->second->atom2_[ambig_resB_count],
torsionAB_) );
431 number_constraints_added++;
434 if( (this_pair_csts.size() > 0 ) && ( number_ambiguous_constraints == 1) ){
436 param_cache->active_pose_constraints_.push_back(
new MultiConstraint(this_pair_csts) );
438 else if( (this_pair_csts.size() > 0) && ( number_ambiguous_constraints > 1) ) {
444 if( ambig_csts.size() > 0 ) {
450 tr.Info <<
"The covalent constraint specified for this block is ambiguous. ";
451 tr.Info <<
"Ambiguity will be resolved according to the best constraint in the input pose." << std::endl;
454 param_cache->active_pose_constraints_.push_back( ambig_csts[ n_best_constraint ] );
458 Size best_resA_At(0);
459 Size best_resB_At(0);
460 Size n_mod_ambigA = n_best_constraint % ambig_resA;
461 if( n_mod_ambigA == 0) {
462 best_resA_At = ambig_resA - 1;
463 best_resB_At = ( n_best_constraint / ambig_resA ) - 1;
466 best_resA_At = n_mod_ambigA - 1;
467 best_resB_At = n_best_constraint / ambig_resA;
473 if(basic::options::option[basic::options::OptionKeys::enzdes::enz_debug] ){
474 tr.Info <<
"Adding an ambiguous constraint containing " << ambig_csts.size() <<
"constraints." << std::endl;
487 empty_ = all_constraints_empty;
489 if(all_constraints_empty) {
490 tr.Info <<
"Warning: no constraints were added for constraint block " <<
cst_block_ <<
"." << std::endl;
493 tr.Info <<
"for block " <<
cst_block_ <<
", " << number_constraints_added <<
" newly generated constraints were added " << std::endl;
508 using namespace core::chemical;
510 if(basic::options::option[basic::options::OptionKeys::enzdes::enz_debug] ){
521 if(basic::options::option[basic::options::OptionKeys::enzdes::enz_debug] ){
528 tr.Debug <<
"Adding chemical bond between " << pose.
residue( resA_pos ).
name() <<
" " << (
resA_->get_template_atoms_at_pos(pose, resA_pos))->atom1_[resA_At].atomno() <<
" "<< resA_pos <<
" " << resA_atomname <<
" and "
529 << pose.
residue( resB_pos ).
name() <<
" " << resB_pos <<
" " << (
resB_->get_template_atoms_at_pos(pose, resB_pos))->atom1_[resB_At].atomno() <<
" " << resB_atomname << std::endl;
532 resA_pos, resA_atomname,
533 resB_pos, resB_atomname
559 using namespace core::chemical;
560 using namespace core::pack::dunbrack;
562 std::string res_atom = pose.
residue(res_pos).
atom_name( (template_res->get_template_atoms_at_pos(pose, res_pos) )->atom1_[Atpos].atomno() );
565 int whitespace_pos = res_atom.find(
" ");
566 while( whitespace_pos != -1 ) {
567 res_atom.erase(whitespace_pos, 1 );
568 whitespace_pos = res_atom.find(
" ");
574 res_varname =
"_connect" + res_atom;
582 if ( count > 1000 ) {
583 utility_exit_with_message(
"Encountered infinite loop trying to find a new variant name for residue type " + currres.name() +
" in EnzConstraintParameters. Talk to Andrew.");
587 if ( ! currres.has_variant_type( res_varname ))
break;
589 res_varname =
"_"+utility::to_string(count)+
"connect"+res_atom;
590 if ( ! currres.has_variant_type( res_varname ))
break;
594 std::string res_type_mod_name( current_pose_type_basename + res_varname + current_pose_type_patches_name );
608 RotamerLibrary::get_instance().get_rsd_library( pose.
residue_type( res_pos ));
612 RotamerLibrary::get_instance().rsd_library_already_loaded( pose.
residue_type(res_pos) ) ) {
625 if( current_pose_type_basename == base_name ){
631 std::string new_name( base_name + res_varname + patches_name );
633 mod_res = (*res_it)->clone();
634 con_res = mod_res->add_residue_connection( res_atom );
635 mod_res->name( new_name );
636 assert( ! mod_res->has_variant_type( res_varname ) );
637 mod_res->add_variant_type( res_varname );
639 mod_res->set_icoor(
"CONN"+string_of( con_res ), itorsion, iangle, idis, res_atom, pose.
residue(res_pos).
atom_name( (template_res->get_template_atoms_at_pos( pose, res_pos) )->atom2_[Atpos].atomno() ), pose.
residue(res_pos).
atom_name( (template_res->get_template_atoms_at_pos(pose, res_pos) )->atom3_[Atpos].atomno() ),
true );
643 RotamerLibrary::get_instance().add_residue_library( *mod_res, new_lrots );
647 mod_res->nondefault(
true);
648 mod_res->base_restype_name( base_name );
651 mod_restype_set->add_residue_type( mod_res );
659 static_cast< SingleLigandRotamerLibrary const * >
660 ( RotamerLibrary::get_instance().get_rsd_library( pose.
residue_type( res_pos ))() ));
662 if( old_lrots != 0 ){
664 using namespace core::conformation;
666 new_rotamers.clear();
674 for(
core::Size at_ct = 1; at_ct <= new_rot_res->natoms(); at_ct++){
675 if( !(*oldrot_it)->has( new_rot_res->atom_name( at_ct ) ) ){
676 std::cerr <<
"Unexpected ERROR: when regenerating ligand rotamer library (for covalent constraints), one atom wasn't found in a template rotamer." << std::endl;
677 utility::exit( EXIT_FAILURE, __FILE__, __LINE__);
680 new_rot_res->set_xyz( at_ct, (*oldrot_it)->xyz( new_rot_res->atom_name( at_ct ) ) );
684 new_rot_res->chi( (*oldrot_it)->chi() );
686 new_rotamers.push_back( new_rot_res );
688 new_lrots->set_reference_energy( old_lrots->get_reference_energy() );
689 new_lrots->set_rotamers( new_rotamers );
708 tr.Info <<
"parameters residue 1:" << std::endl;
709 resA_->show_params();
710 tr.Info <<
"parameters residue 2:" << std::endl;
711 resB_->show_params();
719 resA_->get_pose_data(pose);
720 resB_->get_pose_data(pose);
737 if( candidate_csts.size() < 2 ){
738 std::cerr <<
"Error, this function should not be called with a constraint input vector containing less than 2 constraints. " << std::endl;
739 utility::exit( EXIT_FAILURE, __FILE__, __LINE__);
757 bool first_pass =
true;
758 Size best_constraint(0);
761 for(
Size cur_cst(1); cur_cst <= candidate_csts.size(); cur_cst++ ){
764 cur_cstset->add_constraint( candidate_csts[cur_cst] );
766 helper_scofx( helper_pose );
770 if( first_pass || ( total_cst_e < cur_low_e ) ) {
771 best_constraint = cur_cst;
772 cur_low_e = total_cst_e;
777 return best_constraint;
787 for(
core::Size i = 1; i <= template_res_cache.size(); ++i ){
788 if( template_res_cache[i]->not_in_pose() )
return true;
818 using namespace core::pose;
824 for( std::vector< core::pose::RemarkInfo >::iterator remark_it = rems.begin(); remark_it != rems.end(); remark_it++) {
826 bool remark_changed(
false);
829 int rem_pdbposA(0), rem_pdbposB(0);
835 if( (param_cache->template_res_cache_[1]->seqpos_map_size() > 1 ) || (param_cache->template_res_cache_[2]->seqpos_map_size() > 1 ) ){
836 tr <<
"Error in updating remarks for cst block " <<
cst_block_ <<
". More than one seqpos in template resA or resB." << std::endl;
840 core::Size seqposA( param_cache->template_res_cache_[1]->seqpos_map_begin()->first );
841 core::Size seqposB( param_cache->template_res_cache_[2]->seqpos_map_begin()->first );
843 if( rem_pdbposA != pdbinfo.
number( seqposA ) ){
847 remark_changed =
true;
848 rem_pdbposA = pdbinfo.
number( seqposA );
851 if( chainA[0] != pdbinfo.
chain( seqposA ) ){
852 remark_changed =
true;
853 chainA = pdbinfo.
chain( seqposA );
856 remark_changed =
true;
860 if( rem_pdbposB != pdbinfo.
number( seqposB) ){
861 remark_changed =
true;
862 rem_pdbposB = pdbinfo.
number( seqposB );
864 if( chainB[0] != pdbinfo.
chain( seqposB ) ){
865 remark_changed =
true;
866 chainB = pdbinfo.
chain( seqposB );
869 remark_changed =
true;
873 if( remark_changed ){
915 if( template_res_cache.size() != 2 ) utility_exit_with_message(
"More or less than 2 template res caches detected in enzdes cst param cache");
916 if( template_res_cache[1]->not_in_pose() && template_res_cache[2]->not_in_pose() ) utility_exit_with_message(
"Error: Both template residues are missing in the pose. This shouldn't happen...\n");
918 if( template_res_cache[1]->not_in_pose() )
return resA_;
919 else if( template_res_cache[2]->not_in_pose() )
return resB_;
921 utility_exit_with_message(
"Error: no template residue is missing in the pose, this shouldn't have happened... \n");
933 if( template_res_cache.size() != 2 ) utility_exit_with_message(
"More or less than 2 template res caches detected in enzdes cst param cache");
934 if( template_res_cache[1]->not_in_pose() && template_res_cache[2]->not_in_pose() ) utility_exit_with_message(
"Error: Both template residues are missing in the pose. This shouldn't happen...\n");
936 if( template_res_cache[1]->not_in_pose() )
return resB_;
937 else if( template_res_cache[2]->not_in_pose() )
return resA_;
939 utility_exit_with_message(
"Error: no template residue is missing in the pose, this shouldn't have happened... \n");
947 std::set< std::string >
956 std::set< std::string > to_return;
958 if( param_cache->template_res_cache(1)->contains_position( seqpos ) ) template_res =
resA_;
959 else if( param_cache->template_res_cache(2)->contains_position( seqpos ) ) template_res =
resB_;
961 else return to_return;
963 for(
core::Size i = 1; i <= template_res->allowed_res_types().size(); ++i ){
964 to_return.insert( template_res->allowed_res_types()[i] );
973 resA_->set_external_position( pos );
980 resB_->set_external_position( pos );
989 cov_it != param_cache->covalent_connections_.end(); ++cov_it ){
990 (*cov_it)->remove_covalent_connection_from_pose( pose );
992 param_cache->covalent_connections_.clear();
998 resA_->remap_resid( smap );
999 resB_->remap_resid( smap );