26 #include <basic/Tracer.hh>
27 #include <utility/exit.hh>
28 #include <utility/string_util.hh>
29 #include <utility/vector1.hh>
30 #include <ObjexxFCL/string.functions.hh>
41 static basic::Tracer
tr(
"protocols.loops.LoopsFileIO");
47 bool prohibit_single_residue_loops,
54 if ( start > stop || ( start == stop && prohibit_single_residue_loops ) ) {
55 utility_exit_with_message(
56 "[ERROR] Error parsing " + filename +
" ( line " + ObjexxFCL::string_of( linecount ) +
57 " ): " +
" Invalid loop definition (start residue " +
58 ( prohibit_single_residue_loops ?
">=" :
">" ) +
" end residue) - ERROR" );
64 pose_numbered_( false ),
68 insertion_code_(
' ' )
75 pose_numbered_( true ),
76 pose_index_( pose_index ),
79 insertion_code_(
' ' )
88 pose_numbered_( false ),
91 resindex_( resindex ),
92 insertion_code_( insertion_code )
104 utility_exit_with_message(
"Residue index description exceeds the number of residues in the Pose: pose_index_ = " +
115 utility_exit_with_message(
"Unable to find PDB residue " + utility::to_string(
resindex_ ) +
insertion_code_ +
"on chain " +
chain_ +
" in input Pose" );
157 utility_exit_with_message(
"Residue index description given on line " + utility::to_string(
linenum_ ) +
158 " of the file named " +
fname_ +
" exceeds the number of residues in the Pose: pose_index_ = " +
159 utility::to_string(
pose_index() ) +
" vs pose.total_residue() " + utility::to_string( pose.
total_residue() ));
169 utility_exit_with_message(
"Unable to find PDB residue " + utility::to_string(
resindex() ) +
insertion_code() +
"on chain " +
chain() +
" in input Pose" );
178 prohibit_single_residue_loops_( true )
187 bool prohibit_single_residue_loops
189 start_res_( start_res ),
190 cutpoint_res_( cutpoint_res ),
192 skip_rate_( skip_rate ),
193 extended_( extended ),
194 prohibit_single_residue_loops_( prohibit_single_residue_loops )
201 bool prohibit_single_residue_loops
203 start_res_( fname, 0, loop.
start ),
204 cutpoint_res_( fname, 0, loop.cut ),
205 end_res_( fname, 0, loop.
stop ),
207 extended_( loop.extended ),
208 prohibit_single_residue_loops_( prohibit_single_residue_loops )
227 loop.
start = start_res_index;
228 loop.cut = cutpoint_res_index;
229 loop.stop = end_res_index;
242 return new Loops( sloops );
251 for (
Size ii = 1; ii <=
size(); ++ii ) {
252 sloops.push_back( (*
this)[ ii ].resolve_as_serialized_loop_from_pose( pose ) );
286 pose_has_resolved_loop_indices_( true ),
287 rely_on_loopfile_indices_( false ),
294 pose_has_resolved_loop_indices_( false ),
295 rely_on_loopfile_indices_( true ),
296 loops_file_data_( lfd ),
303 pose_has_resolved_loop_indices_( true ),
304 rely_on_loopfile_indices_( false ),
312 pose_has_resolved_loop_indices_( true ),
313 rely_on_loopfile_indices_( false ),
314 loops_( new
Loops( loops ) )
321 utility::pointer::ReferenceCount(),
322 in_charge_( src.in_charge_ ),
323 pose_has_resolved_loop_indices_( src.pose_has_resolved_loop_indices_ ),
324 rely_on_loopfile_indices_( src.rely_on_loopfile_indices_ ),
325 loops_file_data_( src.loops_file_data_ ),
332 utility::pointer::ReferenceCount(),
334 pose_has_resolved_loop_indices_( src.pose_has_resolved_loop_indices_ ),
335 rely_on_loopfile_indices_( src.rely_on_loopfile_indices_ ),
336 loops_file_data_( src.loops_file_data_ ),
344 if (
this != & rhs ) {
372 (*loops_) = (*loops_from_lfd );
472 bool prohibit_single_residue_loops
475 std::ifstream infile( filename.c_str() );
477 if (!infile.good()) {
478 utility_exit_with_message(
"[ERROR] Error opening RBSeg file '" + filename +
"'" );
485 std::istream & loopfstream,
487 bool prohibit_single_residue_loops
493 if ( loopfstream.peek() ==
'#' ) {
495 getline( loopfstream, line );
499 if ( tokens.size() >= 3 && tokens[2] ==
"FORMAT" ) {
500 if ( tokens[3] ==
"JSON" ) {
514 loops->resize( sloops.size() );
515 for (
core::Size ii = 1; ii <= sloops.size(); ++ii ) {
516 loops->insert_loop_at_index(
LoopFromFileData( sloops[ ii ], filename, prohibit_single_residue_loops ), ii );
522 loop_line_begin_token_(
"LOOP" ),
523 linecount_offset_( 0 )
530 bool strict_looprelax_checks
539 while( getline( is, line) ) {
544 if ( tokens.size() > 0 ) {
545 if ( tokens[1].substr(0,3) ==
"END" )
break;
547 if ( tokens.size() < 3 ) {
548 utility_exit_with_message(
"[ERROR] Error parsing " + filename +
" ( line " + ObjexxFCL::string_of( linecount ) +
" ): " +
" Minimum of 3 tokens necessary (begin, end, cutpoint)" );
550 if ( tokens.size() > 6 ) {
551 utility_exit_with_message(
"[ERROR] Error parsing " + filename +
" ( line " + ObjexxFCL::string_of( linecount ) +
" ): " +
" Maximum of 6 tokens allowed (LOOP begin end cutpoint skiprate extended)" );
555 current_loop.
cut = 0;
558 bool extend_loop =
false;
560 if (tokens.size() > 3)
562 if (tokens.size() > 4)
563 current_loop.
skip_rate = atof(tokens[5].c_str());
564 if (tokens.size() > 5){
565 if ( tokens[6] ==
"X" ){
566 tr.Error <<
"[ERROR] Error parsing " + filename +
" ( line " + ObjexxFCL::string_of( linecount ) +
" ): " +
"[WARNING] DEPRECATED old style extended marker X is used" << std::endl;
568 if ( errcount > 0 ) errcount--;
570 utility_exit_with_message(
"too many errors in loop-file " + filename );
573 int extended_token = atoi(tokens[6].c_str());
574 if ( extended_token == 0 ) extend_loop =
false;
575 else extend_loop =
true;
579 current_loop.
extended = extend_loop;
581 loops.push_back( current_loop );
582 }
else if ( tokens[1][0] !=
'#' ) {
583 if (tokens.size() >= 2) {
584 tr.Error <<
"[ERROR] Error parsing " + filename +
" ( line " + ObjexxFCL::string_of( linecount ) +
" ): " +
"DEPRECATED r++ style loopfile" << std::endl;
589 utility_exit_with_message(
"too many errors in loop-file " + filename );
594 current_loop.
cut = 0;
596 bool extend_loop =
false;
597 if (tokens.size() > 2) {
600 if (tokens.size() > 3) {
601 current_loop.
skip_rate = atof(tokens[4].c_str());
603 if (tokens.size() > 4) {
604 if ( tokens[5] ==
"X" ){
605 tr.Error <<
"[ERROR] Error parsing " + filename +
" ( line " + ObjexxFCL::string_of( linecount ) +
" ): " +
"[WARNING] DEPRECATED old style extended marker X is used" << std::endl;
608 int extended_token = atoi(tokens[5].c_str());
609 if ( extended_token == 0 ) extend_loop =
false;
610 else extend_loop =
true;
613 current_loop.
extended = extend_loop;
616 loops.push_back( current_loop );
619 tr.Warning <<
"[WARNING] Skipping line '" << line <<
"'" << std::endl;
648 bool prohibit_single_residue_loops
650 utility::json_spirit::mValue mapped_json;
653 if ( utility::json_spirit::read(is, mapped_json) ) utility_exit_with_message(
"Unable to read loops file '" + filename +
"'." );
654 if ( mapped_json.type() != utility::json_spirit::obj_type ) utility_exit_with_message(
"The loop file '" + filename +
"' is not formatted correctly. Please see the documenation.");
661 utility::json_spirit::mValue & json_data,
662 bool prohibit_single_residue_loops,
666 if ( ! json_data.get_obj().count( LoopSetKey ) ) utility_exit_with_message(
"The loop file '" + filename +
"' is not formatted correctly. Please see the documenation.");
667 utility::json_spirit::mArray & array = json_data.get_obj()[LoopSetKey].get_array();
668 if ( ! array.size() ) utility_exit_with_message(
"The LoopList appears to be empty. Please check your input file, '" + filename +
"'." );
683 loops->push_back( current_loop );
691 if ( json_data.type() != utility::json_spirit::obj_type )
693 utility_exit_with_message(
"The loop file '" + fname +
"' is not formatted correctly. Please see the documenation.");
697 for (std::map<std::string,utility::json_spirit::mValue>::iterator it = json_data.get_obj().begin(); it != json_data.get_obj().end(); ++it )
702 utility_exit_with_message(
"Unknown key \"" + it->first +
".\" Please check your input file." );
716 utility::json_spirit::mValue & json_loop_data,
723 char insert_code =
' ';
724 bool usesPDBNumbering =
false;
727 if (json_loop_data.get_obj().count( res_identity ) ) {
728 ++approximate_linenumber;
731 utility::json_spirit::mObject json_representation_of_residue_data = json_loop_data.get_obj()[ res_identity ].get_obj();
735 if ( json_representation_of_residue_data.count( residue_number ) ) {
736 if ( json_representation_of_residue_data[ residue_number ].type() != utility::json_spirit::int_type ) {
737 utility_exit_with_message(
"The \"resSeq\" field must be an integer. Please check your input file, '" + filename +
"'." );
739 resNo = json_representation_of_residue_data[ residue_number ].get_int();
741 utility_exit_with_message(
"The \"resSeq\" field for " + res_identity +
" must be defined. Please check your input file, '" + filename +
"'." );
746 if ( json_representation_of_residue_data.count( chain_identifier ) ) {
747 if ( json_representation_of_residue_data[ chain_identifier ].type() != utility::json_spirit::str_type ){
748 utility_exit_with_message(
"The \"chainID\" field must be a one character string. Please check your input file, '" +filename +
"'." );
750 std::string tmp_chainID = json_representation_of_residue_data[ chain_identifier ].get_str();
751 if ( tmp_chainID.length() != 1 ) {
752 utility_exit_with_message(
"chainIDs must be exactly one character long. Please check your input file, '" + filename +
"'." );
754 chain_id = char( tmp_chainID[0] );
755 usesPDBNumbering =
true;
760 if (json_representation_of_residue_data.count( insertion_code ) ) {
761 if ( ! usesPDBNumbering ) {
762 utility_exit_with_message(
"Using an insertion code requires specifying the residue's chainID. Please check your input file, '" + filename +
"'." );
764 if ( json_representation_of_residue_data[ insertion_code ].type() != utility::json_spirit::str_type ) {
765 utility_exit_with_message(
"The \"iCode\" field must be a one character string or omitted. Please check your input file, '" + filename +
"'." );
767 std::string tmp_iCode = json_representation_of_residue_data[ insertion_code ].get_str();
768 if ( tmp_iCode.length() != 1 ) {
769 utility_exit_with_message(
"Insertion codes must be exactly one character long. Please check your input file, '" + filename +
"'." );
771 insert_code = char( tmp_iCode[0] );
774 utility_exit_with_message(
"The \"" + res_identity +
"\" residue must be specified. Please check your input file '" + filename +
"'." );
777 return usesPDBNumbering ?
779 ResidueIndexDescriptionFromFile( filename, approximate_linenumber, resNo );
784 utility::json_spirit::mValue & json_loop_data,
793 if ( json_representation_of_residue_data.count( skip_rate_name ) ) {
794 if ( json_representation_of_residue_data[ skip_rate_name ].type() != utility::json_spirit::real_type && json_representation_of_residue_data[ skip_rate_name ].type() != utility::json_spirit::int_type ) {
795 utility_exit_with_message(
"Skip rates in loop files must be a floating point number in [0, 1). Please check your input file." );
797 loop.
skip_rate( json_representation_of_residue_data[ skip_rate_name ].get_real() );
800 utility_exit_with_message(
"Skip rates in loop files must be in [0, 1). Please check your input file." );
806 if ( json_representation_of_residue_data.count( extend_name ) ) {
807 if ( json_representation_of_residue_data[ extend_name ].type() != utility::json_spirit::bool_type ) {
808 utility_exit_with_message(
"The \"extend\" field must be a boolean. Use the string literals \"true\" or \"false\" to toggle the behavior. If this field is omitted, it will default to \"false.\" Please check your input file." );
810 loop.
extended( json_representation_of_residue_data[ extend_name ].get_bool() );
815 if ( json_representation_of_residue_data.count( pose_numbering_name ) ) {
816 if ( json_representation_of_residue_data[ pose_numbering_name ].type() != utility::json_spirit::bool_type ) {
817 utility_exit_with_message(
"The \"use_pose_numbering\" field must be a boolean. Use the string literals \"true\" or \"false\" to toggle the behavior. If this field is omitted, it will default to \"false.\" Please check your input file. Note that this field exists only to provide compatibility with the old style loops files." );
819 if ( json_representation_of_residue_data[ pose_numbering_name ].get_bool() ) {