24 #include <basic/Tracer.hh>
27 #include <utility/exit.hh>
30 #include <ObjexxFCL/format.hh>
33 #include <boost/lexical_cast.hpp>
52 using ObjexxFCL::rstrip_whitespace;
54 using ObjexxFCL::rstripped_whitespace;
55 using ObjexxFCL::stripped_whitespace;
57 static basic::Tracer
TR(
"core.io.pdb.HeaderInformation");
67 keyword_in_progress_(false),
69 compound_in_progress_(false),
70 experimental_techniques_(),
71 experimental_technique_in_progress_(
"")
76 classification_(src.classification_),
77 dep_year_(src.dep_year_),
78 dep_month_(src.dep_month_),
79 dep_day_(src.dep_day_),
82 keywords_(src.keywords_),
83 keyword_in_progress_(src.keyword_in_progress_),
84 compounds_(src.compounds_),
85 compound_in_progress_(src.compound_in_progress_),
86 experimental_techniques_(src.experimental_techniques_),
87 experimental_technique_in_progress_(src.experimental_technique_in_progress_)
95 string const & type = R[
"type"].value;
100 }
else if(type ==
"TITLE "){
102 }
else if(type ==
"KEYWDS"){
104 }
else if(type ==
"COMPND"){
106 }
else if(type ==
"EXPDTA"){
109 std::stringstream err_msg;
111 <<
"Attempting to add unrecognized record type '" << type <<
"' "
112 <<
"to header information.";
113 utility_exit_with_message(err_msg.str());
134 std::vector<Record> & VR
163 dep_day_ = atoi(depDate.substr(0,2).c_str());
165 TR.Warning <<
"Deposition day not in range [1, 31]: " <<
dep_day_ << endl;
168 string const & mon(depDate.substr(3,3));
182 TR.Warning <<
"Unrecognized month in HEADER deposition date " + depDate << mon << std::endl;
198 TR.Warning <<
"Deposition month not in range [01, 99]: " <<
dep_month_ << endl;
203 TR.Warning <<
"Deposition month not in range [1, 12]: " <<
dep_month_ << endl;
208 TR.Warning <<
"Deposition day not in range [1, 31]: " <<
dep_day_ << endl;
215 std::stringstream dep_date;
218 utility_exit_with_message(
"deposition day is outside of range [1,31]: " +
dep_day_);
222 case 1: dep_date <<
"JAN";
break;
223 case 2: dep_date <<
"FEB";
break;
224 case 3: dep_date <<
"MAR";
break;
225 case 4: dep_date <<
"APR";
break;
226 case 5: dep_date <<
"MAY";
break;
227 case 6: dep_date <<
"JUN";
break;
228 case 7: dep_date <<
"JUL";
break;
229 case 8: dep_date <<
"AUG";
break;
230 case 9: dep_date <<
"SEP";
break;
231 case 10: dep_date <<
"OCT";
break;
232 case 11: dep_date <<
"NOV";
break;
233 case 12: dep_date <<
"DEC";
break;
235 utility_exit_with_message(
"Unrecognized deposition month index " +
dep_month_);
238 utility_exit_with_message(
"Deposition year is out side of range [01,99]: " +
dep_year_);
241 return dep_date.str();
267 std::vector< Record > & VR
272 R[
"type"].value =
"HEADER";
275 R[
"idCode"].value =
idCode();
288 TR.Warning <<
"Attempting to store empty title record field." << endl;
297 title_.append(rstripped_whitespace(title));
313 std::vector< Record > & VR
326 if(keywords.empty()){
327 TR.Warning <<
"Attempting to add empty keywords string." << endl;
331 size_t i(keywords.find_first_not_of(
' '));
333 while(i != std::string::npos) {
334 j = keywords.find(
',', i);
337 " " + rstripped_whitespace(keywords.substr(i, j-i)));
340 keywords_.push_back(rstripped_whitespace(keywords.substr(i, j-i)));
342 if(j != std::string::npos){
343 i = keywords.find_first_not_of(
' ', j+1);
351 list< string >
const &
373 std::vector< Record > & VR
380 if(!keywords.empty()) keywords.append(
", ");
393 case MOL_ID: token_str =
"MOL_ID";
break;
394 case MOLECULE: token_str =
"MOLECULE";
break;
395 case CHAIN: token_str =
"CHAIN";
break;
396 case FRAGMENT: token_str =
"FRAGMENT";
break;
397 case SYNONYM: token_str =
"SYNONYM";
break;
398 case EC: token_str =
"EC";
break;
399 case ENGINEERED: token_str =
"ENGINEERED";
break;
400 case MUTATION: token_str =
"MUTATION";
break;
403 TR.Error <<
"Unrecognized compound token '" << token <<
"'" << endl;
411 if(token ==
"MOL_ID")
return MOL_ID;
412 else if(token ==
"MOLECULE")
return MOLECULE;
413 else if(token ==
"CHAIN")
return CHAIN;
414 else if(token ==
"FRAGMENT")
return FRAGMENT;
415 else if(token ==
"SYNONYM")
return SYNONYM;
416 else if(token ==
"EC")
return EC;
417 else if(token ==
"ENGINEERED")
return ENGINEERED;
418 else if(token ==
"MUTATION")
return MUTATION;
421 TR.Error <<
"Unrecognized compound token string '" << token <<
"'" << endl;
436 size_t v_end(compound.find(
';'));
439 rstripped_whitespace(compound.substr(0,v_end)));
443 size_t t_begin(compound.find_first_not_of(
' '));
444 size_t t_end(compound.find(
':', t_begin));
445 if(t_end == std::string::npos) {
447 <<
"Attempting to add compound to header information "
448 <<
"but no compund token was found in '" << compound <<
"'" << endl;
454 size_t v_begin(compound.find_first_not_of(
' ', t_end + 1));
455 if(v_begin == std::string::npos){
457 <<
"Attempting to add compound to header information "
458 <<
"but no compund value was found in '" << compound <<
"'" << endl;
461 size_t v_end(compound.find(
';', v_begin));
462 if(v_end == std::string::npos){
466 make_pair(token, compound.substr(v_begin, v_end - v_begin)));
474 compounds_.push_back(make_pair(token, value));
499 std::vector< Record > & VR
506 std::stringstream comp_field;
509 << (line_no == 1 ?
"" :
" ")
540 t =
"ELECTRON DEFRACTION";
542 <<
"Encountered obsolete experimental technqiue coding '"
547 t =
"CRYO-ELECTRON MICROSCOPY";
549 <<
"Encountered obsolete experimental technqiue coding '"
554 t =
"SOLUTION SCATTERING, THEORETICAL MODEL";
556 <<
"Encountered obsolete experimental technqiue coding '"
561 t =
"FLORECENCE TRANSFER";
563 <<
"Encountered obsolete experimental technqiue coding '"
570 <<
"Encountered obsolete experimental technqiue coding '"
576 <<
"Unrecognized experimental technique value '"
577 << technique <<
"'" << endl;
585 string const & technique
590 else if(technique ==
"ELECTRON CRYSTALLOGRAPHY")
594 else if(technique ==
"SOLUTION NMR")
return SOLUTION_NMR;
599 else if(technique ==
"ELECTRON DEFRACTION") {
601 <<
"Encountered obsolete experimental technqiue string '"
602 << technique <<
"'" << endl;
604 }
else if(technique ==
"CRYO-ELECTRON MICROSCOPY") {
606 <<
"Encountered obsolete experimental technqiue string '"
607 << technique <<
"'" << endl;
609 }
else if(technique ==
"FLORECENCE TRANSFER") {
611 <<
"Encountered obsolete experimental technqiue string '"
612 << technique <<
"'" << endl;
614 }
else if(technique ==
"NMR") {
616 <<
"Encountered obsolete experimental technqiue string '"
617 << technique <<
"'" << endl;
621 <<
"Unrecognized experimental technique string '"
622 << technique <<
"'" << endl;
630 string const & exp) {
632 TR.Error <<
"Attempting to add empty experimental technique string." << endl;
636 size_t t_begin, t_len, t_end(-1);
639 t_begin = exp.find_first_not_of(
' ', t_end+1);
640 if(t_begin == std::string::npos)
return;
642 t_end = exp.find(
';', t_begin);
643 if(t_end == std::string::npos){
645 rstripped_whitespace(exp.substr(t_begin, t_len));
647 }
else if(exp.length() - t_begin >= 3 && exp.compare(t_begin, 3,
"NMR") == 0){
651 t_len = t_end - t_begin;
674 list< HeaderInformation::ExperimentalTechnique >
const &
702 list< HeaderInformation::ExperimentalTechnique >::const_iterator
711 std::vector< Record > & VR
715 <<
"Attempting to fill experimental technique records the "
716 <<
"HeaderInformation is in the middle of parsing. If you think the "
717 <<
"parsing is complete and you have reached this recording in error, "
718 <<
"please call finalize_parse()";
724 ExperimentalTechniques::const_iterator
728 if(!techniques.empty()) techniques.append(
"; ");
742 string const & record_type,
743 string const & field_name,
744 string const & contents,
746 std::vector< Record > & VR
749 size_t l_begin(0), l_len(0), l_end(0);
750 size_t field_width(60);
751 while(l_begin != contents.length()){
753 R[
"type"].value = record_type;
757 if(contents.length() - l_begin <= field_width){
758 l_len = contents.length() - l_begin;
763 l_end = l_begin + field_width;
767 if(l_end == l_begin){
771 <<
"The for record type '" << record_type <<
"', "
772 <<
"field '" << field_name <<
"' "
773 <<
"contains a word that has more than 59 characters and "
774 <<
"is too long to fit on one line." << endl;
775 TR.Error << field_name <<
": " << contents << endl;
778 if (contents[l_end] ==
' ' || contents[l_end - 1] ==
'-'){
784 l_len = l_end - l_begin;
786 R[field_name].value = contents.substr(l_begin, l_len);
792 l_begin = l_begin + l_len;
804 TR.Error <<
"Attempting to write a line continuation record for line 0, please begin the line continuation count at 1." << endl;
810 }
else if(line_no > 99){
811 TR.Error <<
"Attempting to write record that takes more than 99 lines, which overflows the continuation field in the." << endl;
815 sprintf(&con_field[0],
"%2d", static_cast<int>(line_no));